Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package lime for openSUSE:Factory checked in at 2021-07-29 21:31:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/lime (Old) and /work/SRC/openSUSE:Factory/.lime.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "lime" Thu Jul 29 21:31:56 2021 rev:4 rq:909075 version:5.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/lime/lime.changes 2021-06-09 21:53:25.662595121 +0200 +++ /work/SRC/openSUSE:Factory/.lime.new.1899/lime.changes 2021-07-29 21:33:02.252691746 +0200 @@ -1,0 +2,12 @@ +Thu Jul 29 05:57:32 UTC 2021 - Paolo Stivanin <[email protected]> + +- Update to 5.0.0 (no changelog) + +------------------------------------------------------------------- +Sun Jul 4 2021 Giacomo Comes <[email protected]> - 4.5.20 + +- Update to version 4.5.20: + * No changes +- fix several RPMLINT warning + +------------------------------------------------------------------- Old: ---- lime-4.5.7.tar.bz2 New: ---- lime-5.0.0.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ lime.spec ++++++ --- /var/tmp/diff_new_pack.9bLXJ4/_old 2021-07-29 21:33:02.640691268 +0200 +++ /var/tmp/diff_new_pack.9bLXJ4/_new 2021-07-29 21:33:02.644691263 +0200 @@ -19,11 +19,12 @@ %define soname liblime %define sover 0 Name: lime -Version: 4.5.7 +Version: 5.0.0 Release: 0 Summary: Instant Message End-to-End Encryption Library License: GPL-3.0-or-later -URL: https://linphone.org/technical-corner/lime/overview +Group: Productivity/Networking/Instant Messenger +URL: https://linphone.org/technical-corner/lime/ Source: https://gitlab.linphone.org/BC/public/lime/-/archive/%{version}/%{name}-%{version}.tar.bz2 BuildRequires: cmake BuildRequires: gcc-c++ @@ -66,6 +67,7 @@ %package devel Summary: Development files for lime +Group: Development/Languages/C and C++ Requires: %{soname}%{sover} = %{version} Requires: soci-devel Requires: soci-sqlite3-devel ++++++ lime-4.5.7.tar.bz2 -> lime-5.0.0.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/CMakeLists.txt new/lime-5.0.0/CMakeLists.txt --- old/lime-4.5.7/CMakeLists.txt 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/CMakeLists.txt 2021-05-11 23:07:21.000000000 +0200 @@ -47,7 +47,7 @@ set (LANGUAGES_LIST ${LANGUAGES_LIST} Java) endif() -project(lime VERSION 4.5.0 LANGUAGES ${LANGUAGES_LIST}) +project(lime VERSION 5.0.0 LANGUAGES ${LANGUAGES_LIST}) set(LIME_SO_VERSION "0") set(LIME_VERSION ${PROJECT_VERSION}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/src/lime.cpp new/lime-5.0.0/src/lime.cpp --- old/lime-4.5.7/src/lime.cpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/src/lime.cpp 2021-05-11 23:07:21.000000000 +0200 @@ -217,7 +217,7 @@ } // We have everyone: encrypt - encryptMessage(internal_recipients, *plainMessage, *recipientUserId, m_selfDeviceId, *cipherMessage, encryptionPolicy); + encryptMessage(internal_recipients, *plainMessage, *recipientUserId, m_selfDeviceId, *cipherMessage, encryptionPolicy, m_localStorage); // move DR messages to the input/output structure, ignoring again the input with peerStatus set to fail // so the index on the internal_recipients still matches the way we created it from recipients diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/src/lime_double_ratchet.cpp new/lime-5.0.0/src/lime_double_ratchet.cpp --- old/lime-4.5.7/src/lime_double_ratchet.cpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/src/lime_double_ratchet.cpp 2021-05-11 23:07:21.000000000 +0200 @@ -346,7 +346,7 @@ m_active_status = false; } - if (session_save() == true) { + if (session_save(false) == true) { // session_save called with false, will not manage db lock and transaction, it is taken care by ratchetEncrypt caller m_dirty = DRSessionDbStatus::clean; // this session and local storage are back in sync } } @@ -439,14 +439,14 @@ /* template instanciations for Curve25519 and Curve448 */ #ifdef EC25519_ENABLED extern template bool DR<C255>::session_load(); - extern template bool DR<C255>::session_save(); + extern template bool DR<C255>::session_save(bool commit); extern template bool DR<C255>::trySkippedMessageKeys(const uint16_t Nr, const X<C255, lime::Xtype::publicKey> &DHr, DRMKey &MK); template class DR<C255>; #endif #ifdef EC448_ENABLED extern template bool DR<C448>::session_load(); - extern template bool DR<C448>::session_save(); + extern template bool DR<C448>::session_save(bool commit); extern template bool DR<C448>::trySkippedMessageKeys(const uint16_t Nr, const X<C448, lime::Xtype::publicKey> &DHr, DRMKey &MK); template class DR<C448>; #endif @@ -464,9 +464,10 @@ * @param[out] cipherMessage message encrypted with a random generated key(and IV). May be an empty buffer depending on encryptionPolicy, recipients and plaintext characteristics * @param[in] encryptionPolicy select how to manage the encryption: direct use of Double Ratchet message or encrypt in the cipher message and use the DR message to share the cipher message key\n * default is optimized output size mode. + * @param[in] localStorage pointer to the local storage, used to get lock and start transaction on all DR sessions at once */ template <typename Curve> - void encryptMessage(std::vector<RecipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy) { + void encryptMessage(std::vector<RecipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<lime::Db> localStorage) { // Shall we set the payload in the DR message or in a separate cupher message buffer? bool payloadDirectEncryption; switch (encryptionPolicy) { @@ -558,16 +559,29 @@ */ AD.insert(AD.end(), sourceDeviceId.cbegin(), sourceDeviceId.cend()); - for(size_t i=0; i<recipients.size(); i++) { - std::vector<uint8_t> recipientAD{AD}; // copy AD - recipientAD.insert(recipientAD.end(), recipients[i].deviceId.cbegin(), recipients[i].deviceId.cend()); //insert recipient device id(gruu) - - if (payloadDirectEncryption) { - recipients[i].DRSession->ratchetEncrypt(plaintext, std::move(recipientAD), recipients[i].DRmessage, payloadDirectEncryption); - } else { - recipients[i].DRSession->ratchetEncrypt(randomSeed, std::move(recipientAD), recipients[i].DRmessage, payloadDirectEncryption); + // ratchet encrypt write to the db, to avoid a serie of transaction, manage it outside of the loop + // acquire lock and open a transaction + std::lock_guard<std::recursive_mutex> lock(*(localStorage->m_db_mutex)); + localStorage->start_transaction(); + + try { + for(size_t i=0; i<recipients.size(); i++) { + std::vector<uint8_t> recipientAD{AD}; // copy AD + recipientAD.insert(recipientAD.end(), recipients[i].deviceId.cbegin(), recipients[i].deviceId.cend()); //insert recipient device id(gruu) + + if (payloadDirectEncryption) { + recipients[i].DRSession->ratchetEncrypt(plaintext, std::move(recipientAD), recipients[i].DRmessage, payloadDirectEncryption); + } else { + recipients[i].DRSession->ratchetEncrypt(randomSeed, std::move(recipientAD), recipients[i].DRmessage, payloadDirectEncryption); + } } + } catch (...) { + localStorage->rollback_transaction(); + throw; } + + // ratchet encrypt write to the db, to avoid a serie of transaction, manage it outside of the loop + localStorage->commit_transaction(); } /** @@ -659,11 +673,11 @@ /* template instanciations for C25519 and C448 encryption/decryption functions */ #ifdef EC25519_ENABLED - template void encryptMessage<C255>(std::vector<RecipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy); + template void encryptMessage<C255>(std::vector<RecipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<lime::Db> localStorage); template std::shared_ptr<DR<C255>> decryptMessage<C255>(const std::string& sourceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C255>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext); #endif #ifdef EC448_ENABLED - template void encryptMessage<C448>(std::vector<RecipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy); + template void encryptMessage<C448>(std::vector<RecipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<lime::Db> localStorage); template std::shared_ptr<DR<C448>> decryptMessage<C448>(const std::string& sourceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C448>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext); #endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/src/lime_double_ratchet.hpp new/lime-5.0.0/src/lime_double_ratchet.hpp --- old/lime-4.5.7/src/lime_double_ratchet.hpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/src/lime_double_ratchet.hpp 2021-05-11 23:07:21.000000000 +0200 @@ -112,7 +112,7 @@ void skipMessageKeys(const uint16_t until, const int limit); /* check if we skipped some messages in current receiving chain, generate and store in session intermediate message keys */ void DHRatchet(const X<Curve, lime::Xtype::publicKey> &headerDH); /* perform a Diffie-Hellman ratchet using the given peer public key */ /* local storage related implemented in lime_localStorage.cpp */ - bool session_save(); /* save/update session in database : updated component depends m_dirty value */ + bool session_save(bool commit=true); /* save/update session in database : updated component depends m_dirty value, when commit is true, commit transaction in DB */ bool session_load(); /* load session in database */ bool trySkippedMessageKeys(const uint16_t Nr, const X<Curve, lime::Xtype::publicKey> &DHr, DRMKey &MK); /* check in DB if we have a message key matching public DH and Ns */ @@ -161,7 +161,7 @@ // helpers function wich are the one to be used to encrypt/decrypt messages template <typename Curve> - void encryptMessage(std::vector<RecipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy); + void encryptMessage(std::vector<RecipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<lime::Db> localStorage); template <typename Curve> std::shared_ptr<DR<Curve>> decryptMessage(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<Curve>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext); @@ -169,12 +169,12 @@ /* this templates are instanciated once in the lime_double_ratchet.cpp file, explicitly tell anyone including this header that there is no need to re-instanciate them */ #ifdef EC25519_ENABLED extern template class DR<C255>; - extern template void encryptMessage<C255>(std::vector<RecipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy); + extern template void encryptMessage<C255>(std::vector<RecipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<lime::Db> localStorage); extern template std::shared_ptr<DR<C255>> decryptMessage<C255>(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C255>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext); #endif #ifdef EC448_ENABLED extern template class DR<C448>; - extern template void encryptMessage<C448>(std::vector<RecipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy); + extern template void encryptMessage<C448>(std::vector<RecipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<lime::Db> localStorage); extern template std::shared_ptr<DR<C448>> decryptMessage<C448>(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C448>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/src/lime_localStorage.cpp new/lime-5.0.0/src/lime_localStorage.cpp --- old/lime-4.5.7/src/lime_localStorage.cpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/src/lime_localStorage.cpp 2021-05-11 23:07:21.000000000 +0200 @@ -593,6 +593,33 @@ sql<<"DELETE FROM lime_LocalUsers WHERE UserId = :userId;", use(deviceId); } +/** + * @brief start a transaction on this Db + * + */ +void Db::start_transaction() +{ + sql.begin(); +} + +/** + * @brief commit a transaction on this Db + * + */ +void Db::commit_transaction() +{ + sql.commit(); +} + +/** + * @brief rollback a transaction on this Db + * + */ +void Db::rollback_transaction() +{ + sql.rollback(); +} + /* template instanciations for Curves 25519 and 448 */ #ifdef EC25519_ENABLED template long int Db::check_peerDevice<C255>(const std::string &peerDeviceId, const DSA<C255, lime::DSAtype::publicKey> &Ik, const bool updateInvalid); @@ -610,62 +637,64 @@ /* */ /******************************************************************************/ template <typename Curve> -bool DR<Curve>::session_save() { +bool DR<Curve>::session_save(bool commit) { // commit default to true std::lock_guard<std::recursive_mutex> lock(*(m_localStorage->m_db_mutex)); - // open transaction - transaction tr(m_localStorage->sql); - - // shall we try to insert or update? - bool MSk_DHr_Clean = false; // flag use to signal the need for late cleaning in DR_MSk_DHr table - if (m_dbSessionId==0) { // We have no id for this session row, we shall insert a new one - // Build blobs from DR session - blob DHr(m_localStorage->sql); - DHr.write(0, (char *)(m_DHr.data()), m_DHr.size()); - blob DHs(m_localStorage->sql); - DHs.write(0, (char *)(m_DHs.publicKey().data()), m_DHs.publicKey().size()); // DHs holds Public || Private keys in the same field - DHs.write(m_DHs.publicKey().size(), (char *)(m_DHs.privateKey().data()), m_DHs.privateKey().size()); - blob RK(m_localStorage->sql); - RK.write(0, (char *)(m_RK.data()), m_RK.size()); - blob CKs(m_localStorage->sql); - CKs.write(0, (char *)(m_CKs.data()), m_CKs.size()); - blob CKr(m_localStorage->sql); - CKr.write(0, (char *)(m_CKr.data()), m_CKr.size()); - /* this one is written in base only at creation and never updated again */ - blob AD(m_localStorage->sql); - AD.write(0, (char *)(m_sharedAD.data()), m_sharedAD.size()); - - // Check if we have a peer device already in storage - if (m_peerDid == 0) { // no : we must insert it(failure will result in exception being thrown, let it flow up then) - m_peerDid = m_localStorage->store_peerDevice(m_peerDeviceId, m_peerIk); - } else { - // make sure we have no other session active with this pair local,peer DiD - m_localStorage->sql<<"UPDATE DR_sessions SET Status = 0, timeStamp = CURRENT_TIMESTAMP WHERE Did = :Did AND Uid = :Uid", use(m_peerDid), use(m_db_Uid); + try { + if (commit) { + // open transaction + m_localStorage->sql.begin(); } - if (m_X3DH_initMessage.size()>0) { - blob X3DH_initMessage(m_localStorage->sql); - X3DH_initMessage.write(0, (char *)(m_X3DH_initMessage.data()), m_X3DH_initMessage.size()); - m_localStorage->sql<<"INSERT INTO DR_sessions(Ns,Nr,PN,DHr,DHs,RK,CKs,CKr,AD,Did,Uid,X3DHInit) VALUES(:Ns,:Nr,:PN,:DHr,:DHs,:RK,:CKs,:CKr,:AD,:Did,:Uid,:X3DHinit);", use(m_Ns), use(m_Nr), use(m_PN), use(DHr), use(DHs), use(RK), use(CKs), use(CKr), use(AD), use(m_peerDid), use(m_db_Uid), use(X3DH_initMessage); - } else { - m_localStorage->sql<<"INSERT INTO DR_sessions(Ns,Nr,PN,DHr,DHs,RK,CKs,CKr,AD,Did,Uid) VALUES(:Ns,:Nr,:PN,:DHr,:DHs,:RK,:CKs,:CKr,:AD,:Did,:Uid);", use(m_Ns), use(m_Nr), use(m_PN), use(DHr), use(DHs), use(RK), use(CKs), use(CKr), use(AD), use(m_peerDid), use(m_db_Uid); - } - // if insert went well we shall be able to retrieve the last insert id to save it in the Session object - /*** WARNING: unportable section of code, works only with sqlite3 backend ***/ - m_localStorage->sql<<"select last_insert_rowid()",into(m_dbSessionId); - /*** above could should work but it doesn't, consistently return false from .get_last_insert_id... ***/ - /*if (!(sql.get_last_insert_id("DR_sessions", m_dbSessionId))) { - throw; - } */ - - // At session creation, we may have to delete an OPk from storage - if (m_usedOPkId != 0) { - m_localStorage->sql<<"DELETE FROM X3DH_OPK WHERE Uid = :Uid AND OPKid = :OPk_id;", use(m_db_Uid), use(m_usedOPkId); - m_usedOPkId = 0; - } - } else { // we have an id, it shall already be in the db - // Try to update an existing row - try{ //TODO: make sure the update was a success, or we shall signal it + // shall we try to insert or update? + bool MSk_DHr_Clean = false; // flag use to signal the need for late cleaning in DR_MSk_DHr table + if (m_dbSessionId==0) { // We have no id for this session row, we shall insert a new one + // Build blobs from DR session + blob DHr(m_localStorage->sql); + DHr.write(0, (char *)(m_DHr.data()), m_DHr.size()); + blob DHs(m_localStorage->sql); + DHs.write(0, (char *)(m_DHs.publicKey().data()), m_DHs.publicKey().size()); // DHs holds Public || Private keys in the same field + DHs.write(m_DHs.publicKey().size(), (char *)(m_DHs.privateKey().data()), m_DHs.privateKey().size()); + blob RK(m_localStorage->sql); + RK.write(0, (char *)(m_RK.data()), m_RK.size()); + blob CKs(m_localStorage->sql); + CKs.write(0, (char *)(m_CKs.data()), m_CKs.size()); + blob CKr(m_localStorage->sql); + CKr.write(0, (char *)(m_CKr.data()), m_CKr.size()); + /* this one is written in base only at creation and never updated again */ + blob AD(m_localStorage->sql); + AD.write(0, (char *)(m_sharedAD.data()), m_sharedAD.size()); + + // Check if we have a peer device already in storage + if (m_peerDid == 0) { // no : we must insert it(failure will result in exception being thrown, let it flow up then) + m_peerDid = m_localStorage->store_peerDevice(m_peerDeviceId, m_peerIk); + } else { + // make sure we have no other session active with this pair local,peer DiD + m_localStorage->sql<<"UPDATE DR_sessions SET Status = 0, timeStamp = CURRENT_TIMESTAMP WHERE Did = :Did AND Uid = :Uid", use(m_peerDid), use(m_db_Uid); + } + + if (m_X3DH_initMessage.size()>0) { + blob X3DH_initMessage(m_localStorage->sql); + X3DH_initMessage.write(0, (char *)(m_X3DH_initMessage.data()), m_X3DH_initMessage.size()); + m_localStorage->sql<<"INSERT INTO DR_sessions(Ns,Nr,PN,DHr,DHs,RK,CKs,CKr,AD,Did,Uid,X3DHInit) VALUES(:Ns,:Nr,:PN,:DHr,:DHs,:RK,:CKs,:CKr,:AD,:Did,:Uid,:X3DHinit);", use(m_Ns), use(m_Nr), use(m_PN), use(DHr), use(DHs), use(RK), use(CKs), use(CKr), use(AD), use(m_peerDid), use(m_db_Uid), use(X3DH_initMessage); + } else { + m_localStorage->sql<<"INSERT INTO DR_sessions(Ns,Nr,PN,DHr,DHs,RK,CKs,CKr,AD,Did,Uid) VALUES(:Ns,:Nr,:PN,:DHr,:DHs,:RK,:CKs,:CKr,:AD,:Did,:Uid);", use(m_Ns), use(m_Nr), use(m_PN), use(DHr), use(DHs), use(RK), use(CKs), use(CKr), use(AD), use(m_peerDid), use(m_db_Uid); + } + // if insert went well we shall be able to retrieve the last insert id to save it in the Session object + /*** WARNING: unportable section of code, works only with sqlite3 backend ***/ + m_localStorage->sql<<"select last_insert_rowid()",into(m_dbSessionId); + /*** above could should work but it doesn't, consistently return false from .get_last_insert_id... ***/ + /*if (!(sql.get_last_insert_id("DR_sessions", m_dbSessionId))) { + throw; + } */ + + // At session creation, we may have to delete an OPk from storage + if (m_usedOPkId != 0) { + m_localStorage->sql<<"DELETE FROM X3DH_OPK WHERE Uid = :Uid AND OPKid = :OPk_id;", use(m_db_Uid), use(m_usedOPkId); + m_usedOPkId = 0; + } + } else { // we have an id, it shall already be in the db + // Update an existing row switch (m_dirty) { case DRSessionDbStatus::dirty: // dirty case shall actually never occurs as a dirty is set only at creation not loading, first save is processed above case DRSessionDbStatus::dirty_ratchet: // ratchet&decrypt modifies all but also request to delete X3DHInit from storage @@ -717,56 +746,61 @@ LIME_LOGE<<"Double ratchet session saved call on sessionId "<<m_dbSessionId<<" but sessions appears to be clean"; break; } - } catch (...) { - tr.rollback(); - throw; - } - // updatesert went well, do we have any mkskipped row to modify - if (m_usedDHid !=0 ) { // ok, we consumed a key, remove it from db - m_localStorage->sql<<"DELETE from DR_MSk_MK WHERE DHid = :DHid AND Nr = :Nr;", use(m_usedDHid), use(m_usedNr); - MSk_DHr_Clean = true; // flag the cleaning needed in DR_MSk_DH table, we may have to remove a row in it if no more row are linked to it in DR_MSk_MK - } else { // we did not consume a key - if (m_dirty == DRSessionDbStatus::dirty_decrypt || m_dirty == DRSessionDbStatus::dirty_ratchet) { // if we did a message decrypt : - // update the count of posterior messages received in the stored skipped messages keys for this session (all stored chains) - m_localStorage->sql<<"UPDATE DR_MSk_DHr SET received = received + 1 WHERE sessionId = :sessionId", use(m_dbSessionId); + + // updatesert went well, do we have any mkskipped row to modify + if (m_usedDHid !=0 ) { // ok, we consumed a key, remove it from db + m_localStorage->sql<<"DELETE from DR_MSk_MK WHERE DHid = :DHid AND Nr = :Nr;", use(m_usedDHid), use(m_usedNr); + MSk_DHr_Clean = true; // flag the cleaning needed in DR_MSk_DH table, we may have to remove a row in it if no more row are linked to it in DR_MSk_MK + } else { // we did not consume a key + if (m_dirty == DRSessionDbStatus::dirty_decrypt || m_dirty == DRSessionDbStatus::dirty_ratchet) { // if we did a message decrypt : + // update the count of posterior messages received in the stored skipped messages keys for this session (all stored chains) + m_localStorage->sql<<"UPDATE DR_MSk_DHr SET received = received + 1 WHERE sessionId = :sessionId", use(m_dbSessionId); + } } } - } - // Shall we insert some skipped Message keys? - for ( const auto &rChain : m_mkskipped) { // loop all chains of message keys, each one is a DHr associated to an unordered map of MK indexed by Nr to be saved - blob DHr(m_localStorage->sql); - DHr.write(0, (char *)(rChain.DHr.data()), rChain.DHr.size()); - long DHid=0; - m_localStorage->sql<<"SELECT DHid FROM DR_MSk_DHr WHERE sessionId = :sessionId AND DHr = :DHr LIMIT 1;",into(DHid), use(m_dbSessionId), use(DHr); - if (!m_localStorage->sql.got_data()) { // There is no row in DR_MSk_DHr matching this key, we must add it - m_localStorage->sql<<"INSERT INTO DR_MSk_DHr(sessionId, DHr) VALUES(:sessionId, :DHr)", use(m_dbSessionId), use(DHr); - m_localStorage->sql<<"select last_insert_rowid()",into(DHid); // WARNING: unportable code, sqlite3 only, see above for more details on similar issue - } else { // the chain already exists in storage, just reset its counter of newer message received - m_localStorage->sql<<"UPDATE DR_MSk_DHr SET received = 0 WHERE DHid = :DHid", use(DHid); - } - // insert all the skipped key in the chain - uint16_t Nr; - blob MK(m_localStorage->sql); - statement st = (m_localStorage->sql.prepare << "INSERT INTO DR_MSk_MK(DHid,Nr,MK) VALUES(:DHid,:Nr,:Mk)", use(DHid), use(Nr), use(MK)); - - for (const auto &kv : rChain.messageKeys) { // messageKeys is an unordered map of MK indexed by Nr. - Nr=kv.first; - MK.write(0, (char *)kv.second.data(), kv.second.size()); - st.execute(true); + // Shall we insert some skipped Message keys? + for ( const auto &rChain : m_mkskipped) { // loop all chains of message keys, each one is a DHr associated to an unordered map of MK indexed by Nr to be saved + blob DHr(m_localStorage->sql); + DHr.write(0, (char *)(rChain.DHr.data()), rChain.DHr.size()); + long DHid=0; + m_localStorage->sql<<"SELECT DHid FROM DR_MSk_DHr WHERE sessionId = :sessionId AND DHr = :DHr LIMIT 1;",into(DHid), use(m_dbSessionId), use(DHr); + if (!m_localStorage->sql.got_data()) { // There is no row in DR_MSk_DHr matching this key, we must add it + m_localStorage->sql<<"INSERT INTO DR_MSk_DHr(sessionId, DHr) VALUES(:sessionId, :DHr)", use(m_dbSessionId), use(DHr); + m_localStorage->sql<<"select last_insert_rowid()",into(DHid); // WARNING: unportable code, sqlite3 only, see above for more details on similar issue + } else { // the chain already exists in storage, just reset its counter of newer message received + m_localStorage->sql<<"UPDATE DR_MSk_DHr SET received = 0 WHERE DHid = :DHid", use(DHid); + } + // insert all the skipped key in the chain + uint16_t Nr; + blob MK(m_localStorage->sql); + statement st = (m_localStorage->sql.prepare << "INSERT INTO DR_MSk_MK(DHid,Nr,MK) VALUES(:DHid,:Nr,:Mk)", use(DHid), use(Nr), use(MK)); + + for (const auto &kv : rChain.messageKeys) { // messageKeys is an unordered map of MK indexed by Nr. + Nr=kv.first; + MK.write(0, (char *)kv.second.data(), kv.second.size()); + st.execute(true); + } } - } - // Now do the cleaning (remove unused row from DR_MKs_DHr table) if needed - if (MSk_DHr_Clean == true) { - uint16_t Nr; - m_localStorage->sql<<"SELECT Nr from DR_MSk_MK WHERE DHid = :DHid LIMIT 1;", into(Nr), use(m_usedDHid); - if (!m_localStorage->sql.got_data()) { // no more MK with this DHid, remove it - m_localStorage->sql<<"DELETE from DR_MSk_DHr WHERE DHid = :DHid;", use(m_usedDHid); + // Now do the cleaning (remove unused row from DR_MKs_DHr table) if needed + if (MSk_DHr_Clean == true) { + uint16_t Nr; + m_localStorage->sql<<"SELECT Nr from DR_MSk_MK WHERE DHid = :DHid LIMIT 1;", into(Nr), use(m_usedDHid); + if (!m_localStorage->sql.got_data()) { // no more MK with this DHid, remove it + m_localStorage->sql<<"DELETE from DR_MSk_DHr WHERE DHid = :DHid;", use(m_usedDHid); + } } + } catch (...) { + if (commit) { + m_localStorage->sql.rollback(); + } + throw; } - tr.commit(); + if (commit) { + m_localStorage->sql.commit(); + } return true; }; @@ -834,13 +868,13 @@ /* template instanciations for Curves 25519 and 448 */ #ifdef EC25519_ENABLED template bool DR<C255>::session_load(); - template bool DR<C255>::session_save(); + template bool DR<C255>::session_save(bool commit); template bool DR<C255>::trySkippedMessageKeys(const uint16_t Nr, const X<C255, lime::Xtype::publicKey> &DHr, DRMKey &MK); #endif #ifdef EC448_ENABLED template bool DR<C448>::session_load(); - template bool DR<C448>::session_save(); + template bool DR<C448>::session_save(bool commit); template bool DR<C448>::trySkippedMessageKeys(const uint16_t Nr, const X<C448, lime::Xtype::publicKey> &DHr, DRMKey &MK); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/src/lime_localStorage.hpp new/lime-5.0.0/src/lime_localStorage.hpp --- old/lime-4.5.7/src/lime_localStorage.hpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/src/lime_localStorage.hpp 2021-05-11 23:07:21.000000000 +0200 @@ -63,6 +63,9 @@ long int check_peerDevice(const std::string &peerDeviceId, const DSA<Curve, lime::DSAtype::publicKey> &peerIk, const bool updateInvalid=false); template <typename Curve> long int store_peerDevice(const std::string &peerDeviceId, const DSA<Curve, lime::DSAtype::publicKey> &peerIk); + void start_transaction(); + void commit_transaction(); + void rollback_transaction(); }; /* this templates are instanciated once in the lime_localStorage.cpp file, explicitly tell anyone including this header that there is no need to re-instanciate them */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/tester/data/cacert.pem new/lime-5.0.0/tester/data/cacert.pem --- old/lime-4.5.7/tester/data/cacert.pem 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/tester/data/cacert.pem 2021-05-11 23:07:21.000000000 +0200 @@ -18,3 +18,31 @@ FUWGJhPnkrnklmBdVB0l7qXYjR5uf766HDkoDxuLhNifow3IYvsS+L2Y6puRQb9w HLMDE29mBDl0WyoX3h0yR0EiAO15V9A7I10= -----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEuDCCAyCgAwIBAgIUPv3F/G4gZ9tD6b7Ia9v2TPJLasUwDQYJKoZIhvcNAQEL +BQAwbTELMAkGA1UEBhMCRlIxDzANBgNVBAgMBkZyYW5jZTERMA8GA1UEBwwIR3Jl +bm9ibGUxIjAgBgNVBAoMGUJlbGxlZG9ubmUgQ29tbXVuaWNhdGlvbnMxFjAUBgNV +BAMMDUplaGFuIE1vbm5pZXIwHhcNMjAxMjEzMjExMzIxWhcNMzAxMjExMjExMzIx +WjBtMQswCQYDVQQGEwJGUjEPMA0GA1UECAwGRnJhbmNlMREwDwYDVQQHDAhHcmVu +b2JsZTEiMCAGA1UECgwZQmVsbGVkb25uZSBDb21tdW5pY2F0aW9uczEWMBQGA1UE +AwwNSmVoYW4gTW9ubmllcjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB +ANFkmerzuMSYwcIqwD1/FMirIZb7MyXHqnTWBqahh6cVl/mzVb/7WM0Rbh7V9vce +X7F70EEIKOqF6ckbDAY9kP3UTHOE/NhnKRBW5q8FsN2P6N4KCzYbGO3XcxveOnGg +E1yCkqBFfN8HJwpBXrDJFXKKEzaqo0Gdb9PfgWgJy0RVW6MkenF4U3nxwRTCvnem +y4uaQAR/WLLeMQVec27ia6K36zyyyrw4Gr6CaeEVxRw8+P75k4DMkLHzOvfF0YMT +adLMB6m1ij7TbvtsugsWYggZx+JB8bvzsZ7mqFuF+gPKMmAEnrZxaBXYp61Eo3Ay +HrNmXjdJ7MTw0pmvjLeusSzrWXAzA/jH/1SKyCbnhRmJlTyDIadD9BDM4jeAh+bK +1yQ4YzNRQkrf4h4yecF8F778WQuE6GaHEzSC3AWXoj35i9exkagxLMSJs787NwB5 +lUb2OmIW+a2YW4d9LPiYB+b3Vx+gcSXUuE7hpS89uA1YvKUczykpUX1KxhPk7JzZ +nwIDAQABo1AwTjAdBgNVHQ4EFgQUjawORCzNIqz4Fw7ei2N5PffDwQ4wHwYDVR0j +BBgwFoAUjawORCzNIqz4Fw7ei2N5PffDwQ4wDAYDVR0TBAUwAwEB/zANBgkqhkiG +9w0BAQsFAAOCAYEAZZTBykt6WmK41WmKBFJEfe11R/IQJdnYBIusqrkYHsiMkirt +tWGxT9JjqRmQU9iSQPfqCSZ0/lmOAEIKNPRGvWJgkYV20ynyWpQqJEBPsibFCGz/ +kSzQBZJH8p8XJvtROqzCqyNCLMWZ5fA+WvB7afinoOFcrtdFTIxNhh1hblaUG3Pj +F5/uznQw5B0wt4Ek5KHhtdjRlksEhAcomzdBGmkhqv9lIDPJzcdd8dnueG9gxSSR +TFCIw/chalrXI7Ch0YSx7GKMGNNVb+yvKr4w+e2wb6OG9NoYoAPTivhIire1HO9L +KnG7cArBaYE9wmpGkvRFjKVr76/SICIKEiCqq+bU6fIZFCp/oLYftfCBa478kPXR +iXUiZrKeFDNroIQitihSFpDyK27lWSOdiF3Zx2Vqow66D0luPtr1cBtg6C7dF9ye +qJRVEVBDSweYfRLrKhtlhxtcLoPwk/3bP/Z/QTHLBxrYH8EKj0z8T4lPtyL6q8Ev +/TPDdtsWG8e15MVX +-----END CERTIFICATE----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/tester/lime_crypto-tester.cpp new/lime-5.0.0/tester/lime_crypto-tester.cpp --- old/lime-4.5.7/tester/lime_crypto-tester.cpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/tester/lime_crypto-tester.cpp 2021-05-11 23:07:21.000000000 +0200 @@ -305,6 +305,68 @@ LIME_LOGI<<"Bench for Curve 25519:"<<endl; signAndVerify_bench<C255>(BENCH_TIMING_MS); } + + /* pattern self generated as we use a eddsa25519ctx with a zero sized context which is not a common setting */ + constexpr size_t c255_patternsSize = 8; + std::array<std::vector<uint8_t>, c255_patternsSize> c255_secret_keys = {{ + std::vector<uint8_t>{0xd2, 0x1a, 0x80, 0x79, 0x77, 0x5d, 0x9b, 0xfd, 0x99, 0xd8, 0x66, 0xcd, 0x16, 0xa7, 0x59, 0xcc, 0xfe, 0xf5, 0xdb, 0xab, 0x49, 0xc6, 0xf3, 0x0f, 0x09, 0x24, 0xc8, 0x56, 0x95, 0xac, 0x02, 0x97}, + std::vector<uint8_t>{0x42, 0xf8, 0x2c, 0x1a, 0xff, 0x50, 0x39, 0x8b, 0x07, 0x3d, 0x1e, 0x68, 0x2e, 0xf5, 0x9d, 0xda, 0x77, 0x9b, 0x54, 0xea, 0x99, 0xd6, 0x58, 0xf5, 0xd3, 0xeb, 0x88, 0xbb, 0x79, 0xfc, 0x3f, 0x28}, + std::vector<uint8_t>{0x23, 0x74, 0xff, 0xdc, 0xd7, 0x11, 0x73, 0xd8, 0x50, 0xbf, 0x81, 0xdc, 0xce, 0x9f, 0x73, 0x94, 0x08, 0x8f, 0xba, 0xe3, 0xbd, 0x61, 0x9a, 0xb4, 0x77, 0x50, 0xce, 0xd0, 0xc3, 0x53, 0x79, 0x3d}, + std::vector<uint8_t>{0x3c, 0xee, 0xdb, 0x12, 0x17, 0x32, 0xaf, 0xfb, 0xec, 0xb5, 0xf5, 0xca, 0x50, 0xcd, 0x37, 0x22, 0x46, 0xc4, 0xd7, 0x81, 0xcf, 0xed, 0x07, 0x26, 0x14, 0x58, 0x25, 0xe6, 0xea, 0x6e, 0x91, 0xd2}, + std::vector<uint8_t>{0x24, 0x0b, 0xb2, 0x13, 0x55, 0x81, 0x3e, 0x9a, 0x62, 0xc6, 0x3c, 0xac, 0x6d, 0x39, 0xd6, 0xff, 0xc0, 0x76, 0xc2, 0x4e, 0x30, 0x3d, 0xd9, 0x86, 0x92, 0x00, 0xd5, 0x75, 0x90, 0x34, 0xf7, 0xdf}, + std::vector<uint8_t>{0xe8, 0xe9, 0x9a, 0x85, 0x8a, 0xc1, 0x91, 0x14, 0xb9, 0x9c, 0x47, 0x53, 0xa4, 0x9c, 0xd1, 0x4e, 0x15, 0x49, 0x4c, 0xd2, 0x58, 0x23, 0x76, 0xe6, 0x83, 0x40, 0x11, 0x37, 0x08, 0x2e, 0x5e, 0x9e}, + std::vector<uint8_t>{0x6f, 0x85, 0xbc, 0xaa, 0x4d, 0xa8, 0x2d, 0xaf, 0x30, 0xe9, 0x5e, 0x41, 0x02, 0x30, 0x4e, 0xa9, 0x80, 0x05, 0xb2, 0x6e, 0xc4, 0xfe, 0xbf, 0x6b, 0x08, 0xd3, 0xe7, 0xe7, 0x1c, 0x3c, 0x9e, 0xc0}, + std::vector<uint8_t>{0xc0, 0x2a, 0x76, 0x4c, 0xc1, 0xe9, 0x72, 0x44, 0xf5, 0x65, 0x35, 0x84, 0xf0, 0x24, 0xc6, 0x7d, 0x4a, 0x4f, 0x05, 0x38, 0x2b, 0xbf, 0x0e, 0xa4, 0x3b, 0x24, 0x83, 0xa7, 0xd2, 0x2d, 0xdf, 0xb7} + }}; + + std::array<std::vector<uint8_t>, c255_patternsSize> c255_public_keys = {{ + std::vector<uint8_t>{0x34, 0xe5, 0x65, 0x6c, 0x75, 0x48, 0x98, 0x1d, 0x15, 0x52, 0x70, 0x3e, 0x10, 0x53, 0x28, 0xca, 0xde, 0xe4, 0xe6, 0x0c, 0x7f, 0xc2, 0x8e, 0x29, 0x66, 0x89, 0x58, 0xd8, 0x06, 0xc9, 0x2d, 0x80}, + std::vector<uint8_t>{0xf3, 0xc7, 0x50, 0xb7, 0x3c, 0xe2, 0xc6, 0x86, 0x87, 0x5e, 0x32, 0x32, 0x76, 0xa7, 0x41, 0xcf, 0xe7, 0xa4, 0xa4, 0x57, 0xaa, 0x25, 0x2f, 0x49, 0x0a, 0xf9, 0x7f, 0xca, 0x06, 0x91, 0x3b, 0xa6}, + std::vector<uint8_t>{0x4c, 0x37, 0x56, 0x11, 0xb4, 0xe5, 0xe4, 0x87, 0xa9, 0x29, 0x03, 0x87, 0x20, 0x2a, 0x14, 0x7f, 0x87, 0xbf, 0x70, 0xeb, 0x7c, 0x56, 0xf7, 0xed, 0x51, 0x3d, 0x90, 0x79, 0x96, 0x48, 0x3d, 0x57}, + std::vector<uint8_t>{0x90, 0x8a, 0x6b, 0xcc, 0xd5, 0xb4, 0xe8, 0x57, 0xe7, 0x7e, 0xad, 0x4e, 0xfc, 0xe2, 0xc0, 0x6c, 0xf1, 0xdd, 0x6f, 0xf1, 0x93, 0xb9, 0x1a, 0xf8, 0x18, 0xc0, 0x52, 0x94, 0x80, 0x4a, 0x8f, 0xcd}, + std::vector<uint8_t>{0x8c, 0x18, 0x23, 0x4a, 0x76, 0x2a, 0x22, 0xce, 0x37, 0x52, 0xa8, 0x26, 0xe4, 0xde, 0x7d, 0x13, 0xb3, 0x3f, 0x64, 0xd1, 0xe8, 0x74, 0x6b, 0x34, 0x12, 0xa1, 0x06, 0xb4, 0xcb, 0x41, 0xef, 0x00}, + std::vector<uint8_t>{0x73, 0xe5, 0x84, 0x67, 0x9d, 0x34, 0x1c, 0x7a, 0xe3, 0x37, 0x48, 0xf9, 0x56, 0x84, 0x16, 0xb8, 0xaa, 0x18, 0xfd, 0x83, 0x76, 0xe9, 0xcb, 0x39, 0xc0, 0x7b, 0x8a, 0xf6, 0xd5, 0x2a, 0xbc, 0x59}, + std::vector<uint8_t>{0xea, 0x58, 0xe8, 0xa7, 0x09, 0x10, 0xd3, 0x91, 0x76, 0x99, 0xf5, 0x39, 0xf8, 0x05, 0x06, 0xaa, 0x85, 0xc6, 0x3c, 0x9b, 0x99, 0x9f, 0x91, 0xd2, 0xc0, 0x17, 0xc6, 0xcb, 0x17, 0x77, 0x74, 0xf6}, + std::vector<uint8_t>{0x51, 0xb9, 0x39, 0xd3, 0xbc, 0xc7, 0x93, 0x72, 0x6f, 0xdf, 0x90, 0x4e, 0x85, 0x4a, 0x07, 0x20, 0x5b, 0xae, 0xe9, 0x30, 0x9a, 0xe0, 0xf8, 0xc9, 0x89, 0xc0, 0xcd, 0x30, 0x11, 0x24, 0x7b, 0x93} + }}; + + std::array<std::vector<uint8_t>, c255_patternsSize> c255_messages = {{ + std::vector<uint8_t>{}, + std::vector<uint8_t>{0x03}, + std::vector<uint8_t>{0x0c, 0x3e, 0x54, 0x40, 0x74, 0xec, 0x63, 0xb0, 0x26, 0x5e, 0x0c}, + std::vector<uint8_t>{0x64, 0xa6, 0x5f, 0x3c, 0xde, 0xdc, 0xdd, 0x66, 0x81, 0x1e, 0x29, 0x15}, + std::vector<uint8_t>{0x64, 0xa6, 0x5f, 0x3c, 0xde, 0xdc, 0xdd, 0x66, 0x81, 0x1e, 0x29, 0x15, 0xe7}, + std::vector<uint8_t>{0xbd, 0x0f, 0x6a, 0x37, 0x47, 0xcd, 0x56, 0x1b, 0xdd, 0xdf, 0x46, 0x40, 0xa3, 0x32, 0x46, 0x1a, 0x4a, 0x30, 0xa1, 0x2a, 0x43, 0x4c, 0xd0, 0xbf, 0x40, 0xd7, 0x66, 0xd9, 0xc6, 0xd4, 0x58, 0xe5, 0x51, 0x22, 0x04, 0xa3, 0x0c, 0x17, 0xd1, 0xf5, 0x0b, 0x50, 0x79, 0x63, 0x1f, 0x64, 0xeb, 0x31, 0x12, 0x18, 0x2d, 0xa3, 0x00, 0x58, 0x35, 0x46, 0x11, 0x13, 0x71, 0x8d, 0x1a, 0x5e, 0xf9, 0x44}, + std::vector<uint8_t>{0x15, 0x77, 0x75, 0x32, 0xb0, 0xbd, 0xd0, 0xd1, 0x38, 0x9f, 0x63, 0x6c, 0x5f, 0x6b, 0x9b, 0xa7, 0x34, 0xc9, 0x0a, 0xf5, 0x72, 0x87, 0x7e, 0x2d, 0x27, 0x2d, 0xd0, 0x78, 0xaa, 0x1e, 0x56, 0x7c, 0xfa, 0x80, 0xe1, 0x29, 0x28, 0xbb, 0x54, 0x23, 0x30, 0xe8, 0x40, 0x9f, 0x31, 0x74, 0x50, 0x41, 0x07, 0xec, 0xd5, 0xef, 0xac, 0x61, 0xae, 0x75, 0x04, 0xda, 0xbe, 0x2a, 0x60, 0x2e, 0xde, 0x89, 0xe5, 0xcc, 0xa6, 0x25, 0x7a, 0x7c, 0x77, 0xe2, 0x7a, 0x70, 0x2b, 0x3a, 0xe3, 0x9f, 0xc7, 0x69, 0xfc, 0x54, 0xf2, 0x39, 0x5a, 0xe6, 0xa1, 0x17, 0x8c, 0xab, 0x47, 0x38, 0xe5, 0x43, 0x07, 0x2f, 0xc1, 0xc1, 0x77, 0xfe, 0x71, 0xe9, 0x2e, 0x25, 0xbf, 0x03, 0xe4, 0xec, 0xb7, 0x2f, 0x47, 0xb6, 0x4d, 0x04, 0x65, 0xaa, 0xea, 0x4c, 0x7f, 0xad, 0x37, 0x25, 0x36, 0xc8, 0xba, 0x51, 0x6a, 0x60, 0x39, 0xc3, 0xc2, 0xa3, 0x9f, 0x0e, 0x4d, 0x83, 0x2b, 0xe4, 0x32, 0xdf, 0xa9, 0xa7, 0x06, 0xa6, 0xe5, 0xc7, 0xe1, 0x9f, 0x39, 0x79, 0x64, 0xca, 0x42, 0x58, 0x00, 0x2f, 0x7c, 0x05, 0x41, 0xb5, 0x90, 0x31, 0x 6d, 0xbc, 0x56, 0x22, 0xb6, 0xb2, 0xa6, 0xfe, 0x7a, 0x4a, 0xbf, 0xfd, 0x96, 0x10, 0x5e, 0xca, 0x76, 0xea, 0x7b, 0x98, 0x81, 0x6a, 0xf0, 0x74, 0x8c, 0x10, 0xdf, 0x04, 0x8c, 0xe0, 0x12, 0xd9, 0x01, 0x01, 0x5a, 0x51, 0xf1, 0x89, 0xf3, 0x88, 0x81, 0x45, 0xc0, 0x36, 0x50, 0xaa, 0x23, 0xce, 0x89, 0x4c, 0x3b, 0xd8, 0x89, 0xe0, 0x30, 0xd5, 0x65, 0x07, 0x1c, 0x59, 0xf4, 0x09, 0xa9, 0x98, 0x1b, 0x51, 0x87, 0x8f, 0xd6, 0xfc, 0x11, 0x06, 0x24, 0xdc, 0xbc, 0xde, 0x0b, 0xf7, 0xa6, 0x9c, 0xcc, 0xe3, 0x8f, 0xab, 0xdf, 0x86, 0xf3, 0xbe, 0xf6, 0x04, 0x48, 0x19, 0xde, 0x11}, + std::vector<uint8_t>{0x54, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x62, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x68, 0x65, 0x6e, 0x6f, 0x6d, 0x65, 0x6e, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x62, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x73, 0x65, 0x74, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x68, 0x 69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x20, 0x61, 0x74, 0x20, 0x61, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x70, 0x68, 0x65, 0x6e, 0x6f, 0x6d, 0x65, 0x6e, 0x61, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2c, 0x20, 0x69, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x74, 0x75, 0x64, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x7 4, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x77, 0x61, 0x79, 0x20, 0x75, 0x70, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72 , 0x69, 0x63, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x73, 0x65, 0x65, 0x6d, 0x73, 0x20, 0x61, 0x74, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x73, 0x69, 0x67, 0x68, 0x74, 0x20, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x61, 0x63, 0x74, 0x73, 0x20, 0x62, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x74, 0x20, 0x72, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x73, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74, 0x20, 0x61, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x61, 0x77, 0x73, 0x2e, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x77, 0x61, 0x79, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x73, 0x6d, 0x2c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x63, 0x61, 0x72, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x2e, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x74, 0x77, 0 x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x62, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x72, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x 20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x2c, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x6c, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x74, 0x20, 0x61, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x7 9, 0x20, 0x61, 0x74, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x70, 0x75, 0x6c, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x2e, 0x57, 0x2e, 0x20, 0x57, 0x65, 0x62, 0x65, 0x72, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x77, 0x68, 0x6f, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63 , 0x74, 0x72, 0x6f, 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x20, 0x70, 0x68, 0x65, 0x6e, 0x6f, 0x6d, 0x65, 0x6e, 0x61, 0x2e, 0x20, 0x49, 0x6e, 0x20, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x6f, 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x68, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x57, 0x2e, 0x20, 0x57, 0x65, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x2e, 0x20, 0x4e, 0x65, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x5b, 0x32, 0x5d, 0x2c, 0x20, 0x69, 0x73, 0x20, 0x65, 0x78, 0x63, 0x65, 0x65, 0x64, 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x6f, 0x75, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x74, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x68, 0x65, 0x6e, 0x6f, 0x6d, 0x65, 0x6e, 0x61, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x20, 0x61, 0x74, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x61, 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x20, 0x70, 0x68, 0x65, 0x6e, 0x6f, 0x6d, 0x65, 0x6e, 0x61, 0x3b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0 x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x75, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x6f, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x73, 0x6f, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x2c, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x62, 0x79, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x6c, 0x65, 0x 63, 0x74, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x20, 0x68, 0x69, 0x74, 0x68, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2e} + }}; + + std::array<std::vector<uint8_t>, c255_patternsSize> c255_signatures = {{ + std::vector<uint8_t>{0x78, 0x00, 0x4a, 0xfb, 0xc2, 0x80, 0xeb, 0x21, 0x77, 0xb2, 0xc5, 0x6a, 0x9f, 0xd4, 0x41, 0xfd, 0x32, 0xfa, 0xe1, 0x24, 0xf0, 0x5c, 0xb4, 0xf9, 0x8f, 0x17, 0x6f, 0x21, 0xc5, 0x16, 0xbb, 0x6a, 0xdf, 0xed, 0xac, 0x87, 0x37, 0xcf, 0xf4, 0x02, 0xc7, 0x0f, 0xec, 0xb1, 0xee, 0x24, 0x46, 0xc0, 0x55, 0xe2, 0x68, 0x57, 0x3d, 0x79, 0x39, 0x83, 0x8d, 0x1a, 0x5c, 0x9a, 0x71, 0x73, 0x95, 0x0f}, + std::vector<uint8_t>{0x5a, 0x06, 0x0f, 0xcd, 0x42, 0x9f, 0xe7, 0x71, 0x7d, 0xa7, 0xa4, 0x30, 0x22, 0xb8, 0x4c, 0xab, 0x63, 0xad, 0x9e, 0xd5, 0xf7, 0x50, 0x05, 0x57, 0xc2, 0x8f, 0xd7, 0xae, 0x84, 0xe1, 0x68, 0x9e, 0x45, 0x4a, 0x07, 0x45, 0x1d, 0x13, 0x69, 0x6f, 0xc0, 0xa7, 0xde, 0xd4, 0x8e, 0xe3, 0x34, 0x56, 0x2a, 0x17, 0xc6, 0x49, 0x52, 0x0d, 0x72, 0xba, 0x92, 0x59, 0xbe, 0x35, 0x6f, 0xe7, 0xf0, 0x0f}, + std::vector<uint8_t>{0x9c, 0x1a, 0x66, 0xbe, 0x4f, 0x1c, 0x2d, 0x07, 0xa5, 0xc0, 0x4c, 0x06, 0xca, 0x91, 0x8c, 0x5f, 0x35, 0x2c, 0x58, 0x7d, 0x07, 0x2f, 0x54, 0xa7, 0x14, 0x60, 0x79, 0xf4, 0x7f, 0xe8, 0x44, 0xe8, 0xdb, 0xe9, 0x6f, 0x7f, 0x02, 0x81, 0x9a, 0x28, 0x3f, 0x1d, 0x9a, 0x4b, 0xc2, 0xfe, 0xa0, 0x66, 0x46, 0x51, 0x02, 0xd7, 0x14, 0x11, 0x4f, 0x62, 0xaa, 0xed, 0x67, 0xce, 0xc1, 0x9b, 0x85, 0x07}, + std::vector<uint8_t>{0xb9, 0xa5, 0xdc, 0x2f, 0x99, 0xf0, 0x4b, 0xcc, 0xdb, 0xa9, 0xb6, 0x5c, 0x41, 0x25, 0x80, 0xe6, 0x00, 0x3e, 0x5b, 0xcb, 0x87, 0xb5, 0x4d, 0x1a, 0xf6, 0x41, 0xea, 0xbb, 0x09, 0xfd, 0x82, 0xb2, 0x16, 0xae, 0x05, 0x26, 0x27, 0x0b, 0xb7, 0x84, 0xf0, 0xd2, 0xcf, 0x89, 0x76, 0x8c, 0xb0, 0x45, 0x4e, 0x3e, 0x20, 0xf2, 0x2f, 0x33, 0x3b, 0x36, 0xd5, 0x44, 0x33, 0x6a, 0x34, 0xa9, 0xaf, 0x06}, + std::vector<uint8_t>{0x95, 0xf5, 0xca, 0x35, 0xd2, 0x9c, 0xdc, 0x23, 0x4d, 0x68, 0xf1, 0x13, 0xf3, 0xeb, 0xfc, 0x33, 0x5a, 0xb2, 0xfd, 0x90, 0x5d, 0x2c, 0x54, 0x75, 0x7a, 0xac, 0x6b, 0x3d, 0xa7, 0x3d, 0xbf, 0x4f, 0xbb, 0x64, 0x7e, 0xa4, 0x6e, 0x66, 0x58, 0x08, 0x81, 0x5f, 0x4d, 0xfb, 0xa7, 0x66, 0x58, 0xc4, 0x43, 0xc4, 0xb9, 0x58, 0xb4, 0x57, 0x0d, 0x27, 0xb5, 0xb6, 0x7e, 0x5c, 0x01, 0x0c, 0x1e, 0x0e}, + std::vector<uint8_t>{0xcc, 0x05, 0x1f, 0xc2, 0x25, 0x37, 0x09, 0x94, 0xda, 0x08, 0xc1, 0x20, 0xc2, 0x7b, 0x06, 0xa3, 0xef, 0x3c, 0x9f, 0x76, 0x2f, 0x69, 0xcc, 0x58, 0x40, 0x50, 0xbe, 0xc9, 0x4a, 0x56, 0xbb, 0x46, 0xc9, 0xf7, 0xad, 0x4c, 0x2f, 0xc5, 0x9f, 0xe0, 0x31, 0xed, 0x0c, 0x8b, 0x9a, 0x56, 0x1a, 0xe5, 0x23, 0x49, 0x6b, 0x0f, 0x1b, 0xd2, 0x33, 0x84, 0x3c, 0x1e, 0xbc, 0xb7, 0xc4, 0x1c, 0xdf, 0x0b}, + std::vector<uint8_t>{0xac, 0x83, 0x30, 0x89, 0x08, 0x13, 0xdd, 0x26, 0xb4, 0x7f, 0xb6, 0xef, 0x43, 0x04, 0xe5, 0x5a, 0xbd, 0x7d, 0x90, 0x3c, 0x82, 0x08, 0xad, 0x4e, 0x91, 0x16, 0xb8, 0xae, 0xc2, 0xbe, 0x33, 0x6e, 0x2d, 0x34, 0xf3, 0x17, 0xe1, 0xd3, 0xf6, 0x2a, 0x01, 0x11, 0xab, 0xe5, 0x09, 0xe7, 0x3f, 0x0e, 0x4e, 0x3d, 0x8f, 0x58, 0x3d, 0x4c, 0x46, 0x45, 0xe7, 0xc9, 0xd8, 0xa0, 0x5f, 0x5d, 0xff, 0x06}, + std::vector<uint8_t>{0x0b, 0xa4, 0x77, 0xa9, 0xb7, 0xea, 0x08, 0x73, 0x4d, 0x2d, 0xeb, 0xcd, 0x9b, 0xa0, 0xbe, 0x78, 0x9a, 0x1a, 0xb4, 0xaf, 0x2f, 0xab, 0xe5, 0x31, 0x86, 0x30, 0x38, 0xfa, 0x2b, 0x12, 0x03, 0xa6, 0xd7, 0x07, 0x4c, 0x3e, 0xc2, 0x84, 0xfb, 0xfd, 0x26, 0x32, 0x46, 0xb6, 0xc9, 0xc8, 0xf9, 0x97, 0x5f, 0xa5, 0x92, 0x16, 0xc3, 0xd4, 0x7a, 0xe0, 0x74, 0x19, 0x7b, 0x99, 0x71, 0xff, 0x46, 0x0a} + }}; + + for (size_t i=0; i<c255_messages.size(); i++) { + auto Alice = make_Signature<C255>(); + Alice->set_secret(DSA<C255, lime::DSAtype::privateKey> (c255_secret_keys[i].cbegin())); + + Alice->derivePublic(); + BC_ASSERT_TRUE(memcmp(Alice->get_public().data(), c255_public_keys[i].data(), c255_public_keys[i].size())==0); + DSA<C255, lime::DSAtype::signature> signature{}; + Alice->sign(c255_messages[i], signature); + BC_ASSERT_TRUE(memcmp(signature.data(), c255_signatures[i].data(), c255_signatures[i].size())==0); + + auto Vera = make_Signature<C255>(); + Vera->set_public(DSA<C255, lime::DSAtype::publicKey>(c255_public_keys[i].cbegin())); + BC_ASSERT_TRUE(Vera->verify(c255_messages[i], signature)); + } + #endif #ifdef EC448_ENABLED signAndVerify_test<C448>(); @@ -312,6 +374,70 @@ LIME_LOGI<<"Bench for Curve 448:"<<endl; signAndVerify_bench<C448>(BENCH_TIMING_MS); } + + /* pattern from RFC 8032 */ + constexpr size_t c448_patternsSize = 8; + std::array<std::vector<uint8_t>, c448_patternsSize> c448_secret_keys = {{ + std::vector<uint8_t>{0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, 0xd6, 0x32, 0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, 0x6c, 0x92, 0x9f, 0x34, 0xdd, 0xfa, 0x8c, 0x9f, 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3, 0x48, 0xa3, 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e, 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, 0x03, 0x2e, 0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, 0x5b}, + std::vector<uint8_t>{0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6, 0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d, 0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d, 0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a, 0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c, 0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e, 0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27, 0x4e}, + std::vector<uint8_t>{0xcd, 0x23, 0xd2, 0x4f, 0x71, 0x42, 0x74, 0xe7, 0x44, 0x34, 0x32, 0x37, 0xb9, 0x32, 0x90, 0xf5, 0x11, 0xf6, 0x42, 0x5f, 0x98, 0xe6, 0x44, 0x59, 0xff, 0x20, 0x3e, 0x89, 0x85, 0x08, 0x3f, 0xfd, 0xf6, 0x05, 0x00, 0x55, 0x3a, 0xbc, 0x0e, 0x05, 0xcd, 0x02, 0x18, 0x4b, 0xdb, 0x89, 0xc4, 0xcc, 0xd6, 0x7e, 0x18, 0x79, 0x51, 0x26, 0x7e, 0xb3, 0x28}, + std::vector<uint8_t>{0x25, 0x8c, 0xdd, 0x4a, 0xda, 0x32, 0xed, 0x9c, 0x9f, 0xf5, 0x4e, 0x63, 0x75, 0x6a, 0xe5, 0x82, 0xfb, 0x8f, 0xab, 0x2a, 0xc7, 0x21, 0xf2, 0xc8, 0xe6, 0x76, 0xa7, 0x27, 0x68, 0x51, 0x3d, 0x93, 0x9f, 0x63, 0xdd, 0xdb, 0x55, 0x60, 0x91, 0x33, 0xf2, 0x9a, 0xdf, 0x86, 0xec, 0x99, 0x29, 0xdc, 0xcb, 0x52, 0xc1, 0xc5, 0xfd, 0x2f, 0xf7, 0xe2, 0x1b}, + std::vector<uint8_t>{0x7e, 0xf4, 0xe8, 0x45, 0x44, 0x23, 0x67, 0x52, 0xfb, 0xb5, 0x6b, 0x8f, 0x31, 0xa2, 0x3a, 0x10, 0xe4, 0x28, 0x14, 0xf5, 0xf5, 0x5c, 0xa0, 0x37, 0xcd, 0xcc, 0x11, 0xc6, 0x4c, 0x9a, 0x3b, 0x29, 0x49, 0xc1, 0xbb, 0x60, 0x70, 0x03, 0x14, 0x61, 0x17, 0x32, 0xa6, 0xc2, 0xfe, 0xa9, 0x8e, 0xeb, 0xc0, 0x26, 0x6a, 0x11, 0xa9, 0x39, 0x70, 0x10, 0x0e}, + std::vector<uint8_t>{0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08, 0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d, 0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5, 0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf, 0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f, 0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa, 0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f, 0x01}, + std::vector<uint8_t>{0x2e, 0xc5, 0xfe, 0x3c, 0x17, 0x04, 0x5a, 0xbd, 0xb1, 0x36, 0xa5, 0xe6, 0xa9, 0x13, 0xe3, 0x2a, 0xb7, 0x5a, 0xe6, 0x8b, 0x53, 0xd2, 0xfc, 0x14, 0x9b, 0x77, 0xe5, 0x04, 0x13, 0x2d, 0x37, 0x56, 0x9b, 0x7e, 0x76, 0x6b, 0xa7, 0x4a, 0x19, 0xbd, 0x61, 0x62, 0x34, 0x3a, 0x21, 0xc8, 0x59, 0x0a, 0xa9, 0xce, 0xbc, 0xa9, 0x01, 0x4c, 0x63, 0x6d, 0xf5}, + std::vector<uint8_t>{0x87, 0x2d, 0x09, 0x37, 0x80, 0xf5, 0xd3, 0x73, 0x0d, 0xf7, 0xc2, 0x12, 0x66, 0x4b, 0x37, 0xb8, 0xa0, 0xf2, 0x4f, 0x56, 0x81, 0x0d, 0xaa, 0x83, 0x82, 0xcd, 0x4f, 0xa3, 0xf7, 0x76, 0x34, 0xec, 0x44, 0xdc, 0x54, 0xf1, 0xc2, 0xed, 0x9b, 0xea, 0x86, 0xfa, 0xfb, 0x76, 0x32, 0xd8, 0xbe, 0x19, 0x9e, 0xa1, 0x65, 0xf5, 0xad, 0x55, 0xdd, 0x9c, 0xe8} + }}; + + std::array<std::vector<uint8_t>, c448_patternsSize> c448_public_keys = {{ + std::vector<uint8_t>{0x5f, 0xd7, 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, 0x2c, 0xe7, 0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, 0x1d, 0xa1, 0x34, 0x24, 0x85, 0xa7, 0x0e, 0x1f, 0x8a, 0x0e, 0xa7, 0x5d, 0x80, 0xe9, 0x67, 0x78, 0xed, 0xf1, 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06, 0x1b, 0xd6, 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, 0xd1, 0xfa, 0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, 0x80}, + std::vector<uint8_t>{0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45, 0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a, 0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37, 0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86, 0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02, 0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c, 0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94, 0x80}, + std::vector<uint8_t>{0xdc, 0xea, 0x9e, 0x78, 0xf3, 0x5a, 0x1b, 0xf3, 0x49, 0x9a, 0x83, 0x1b, 0x10, 0xb8, 0x6c, 0x90, 0xaa, 0xc0, 0x1c, 0xd8, 0x4b, 0x67, 0xa0, 0x10, 0x9b, 0x55, 0xa3, 0x6e, 0x93, 0x28, 0xb1, 0xe3, 0x65, 0xfc, 0xe1, 0x61, 0xd7, 0x1c, 0xe7, 0x13, 0x1a, 0x54, 0x3e, 0xa4, 0xcb, 0x5f, 0x7e, 0x9f, 0x1d, 0x8b, 0x00, 0x69, 0x64, 0x47, 0x00, 0x14, 0x00}, + std::vector<uint8_t>{0x3b, 0xa1, 0x6d, 0xa0, 0xc6, 0xf2, 0xcc, 0x1f, 0x30, 0x18, 0x77, 0x40, 0x75, 0x6f, 0x5e, 0x79, 0x8d, 0x6b, 0xc5, 0xfc, 0x01, 0x5d, 0x7c, 0x63, 0xcc, 0x95, 0x10, 0xee, 0x3f, 0xd4, 0x4a, 0xdc, 0x24, 0xd8, 0xe9, 0x68, 0xb6, 0xe4, 0x6e, 0x6f, 0x94, 0xd1, 0x9b, 0x94, 0x53, 0x61, 0x72, 0x6b, 0xd7, 0x5e, 0x14, 0x9e, 0xf0, 0x98, 0x17, 0xf5, 0x80}, + std::vector<uint8_t>{0xb3, 0xda, 0x07, 0x9b, 0x0a, 0xa4, 0x93, 0xa5, 0x77, 0x20, 0x29, 0xf0, 0x46, 0x7b, 0xae, 0xbe, 0xe5, 0xa8, 0x11, 0x2d, 0x9d, 0x3a, 0x22, 0x53, 0x23, 0x61, 0xda, 0x29, 0x4f, 0x7b, 0xb3, 0x81, 0x5c, 0x5d, 0xc5, 0x9e, 0x17, 0x6b, 0x4d, 0x9f, 0x38, 0x1c, 0xa0, 0x93, 0x8e, 0x13, 0xc6, 0xc0, 0x7b, 0x17, 0x4b, 0xe6, 0x5d, 0xfa, 0x57, 0x8e, 0x80}, + std::vector<uint8_t>{0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80, 0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a, 0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd, 0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a, 0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd, 0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5, 0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f, 0x00}, + std::vector<uint8_t>{0x79, 0x75, 0x6f, 0x01, 0x4d, 0xcf, 0xe2, 0x07, 0x9f, 0x5d, 0xd9, 0xe7, 0x18, 0xbe, 0x41, 0x71, 0xe2, 0xef, 0x24, 0x86, 0xa0, 0x8f, 0x25, 0x18, 0x6f, 0x6b, 0xff, 0x43, 0xa9, 0x93, 0x6b, 0x9b, 0xfe, 0x12, 0x40, 0x2b, 0x08, 0xae, 0x65, 0x79, 0x8a, 0x3d, 0x81, 0xe2, 0x2e, 0x9e, 0xc8, 0x0e, 0x76, 0x90, 0x86, 0x2e, 0xf3, 0xd4, 0xed, 0x3a, 0x00}, + std::vector<uint8_t>{0xa8, 0x1b, 0x2e, 0x8a, 0x70, 0xa5, 0xac, 0x94, 0xff, 0xdb, 0xcc, 0x9b, 0xad, 0xfc, 0x3f, 0xeb, 0x08, 0x01, 0xf2, 0x58, 0x57, 0x8b, 0xb1, 0x14, 0xad, 0x44, 0xec, 0xe1, 0xec, 0x0e, 0x79, 0x9d, 0xa0, 0x8e, 0xff, 0xb8, 0x1c, 0x5d, 0x68, 0x5c, 0x0c, 0x56, 0xf6, 0x4e, 0xec, 0xae, 0xf8, 0xcd, 0xf1, 0x1c, 0xc3, 0x87, 0x37, 0x83, 0x8c, 0xf4, 0x00} + }}; + + std::array<std::vector<uint8_t>, c448_patternsSize> c448_messages = {{ + std::vector<uint8_t>{}, + std::vector<uint8_t>{0x03}, + std::vector<uint8_t>{0x0c, 0x3e, 0x54, 0x40, 0x74, 0xec, 0x63, 0xb0, 0x26, 0x5e, 0x0c, }, + std::vector<uint8_t>{0x64, 0xa6, 0x5f, 0x3c, 0xde, 0xdc, 0xdd, 0x66, 0x81, 0x1e, 0x29, 0x15}, + std::vector<uint8_t>{0x64, 0xa6, 0x5f, 0x3c, 0xde, 0xdc, 0xdd, 0x66, 0x81, 0x1e, 0x29, 0x15, 0xe7}, + std::vector<uint8_t>{0xbd, 0x0f, 0x6a, 0x37, 0x47, 0xcd, 0x56, 0x1b, 0xdd, 0xdf, 0x46, 0x40, 0xa3, 0x32, 0x46, 0x1a, 0x4a, 0x30, 0xa1, 0x2a, 0x43, 0x4c, 0xd0, 0xbf, 0x40, 0xd7, 0x66, 0xd9, 0xc6, 0xd4, 0x58, 0xe5, 0x51, 0x22, 0x04, 0xa3, 0x0c, 0x17, 0xd1, 0xf5, 0x0b, 0x50, 0x79, 0x63, 0x1f, 0x64, 0xeb, 0x31, 0x12, 0x18, 0x2d, 0xa3, 0x00, 0x58, 0x35, 0x46, 0x11, 0x13, 0x71, 0x8d, 0x1a, 0x5e, 0xf9, 0x44}, + std::vector<uint8_t>{0x15, 0x77, 0x75, 0x32, 0xb0, 0xbd, 0xd0, 0xd1, 0x38, 0x9f, 0x63, 0x6c, 0x5f, 0x6b, 0x9b, 0xa7, 0x34, 0xc9, 0x0a, 0xf5, 0x72, 0x87, 0x7e, 0x2d, 0x27, 0x2d, 0xd0, 0x78, 0xaa, 0x1e, 0x56, 0x7c, 0xfa, 0x80, 0xe1, 0x29, 0x28, 0xbb, 0x54, 0x23, 0x30, 0xe8, 0x40, 0x9f, 0x31, 0x74, 0x50, 0x41, 0x07, 0xec, 0xd5, 0xef, 0xac, 0x61, 0xae, 0x75, 0x04, 0xda, 0xbe, 0x2a, 0x60, 0x2e, 0xde, 0x89, 0xe5, 0xcc, 0xa6, 0x25, 0x7a, 0x7c, 0x77, 0xe2, 0x7a, 0x70, 0x2b, 0x3a, 0xe3, 0x9f, 0xc7, 0x69, 0xfc, 0x54, 0xf2, 0x39, 0x5a, 0xe6, 0xa1, 0x17, 0x8c, 0xab, 0x47, 0x38, 0xe5, 0x43, 0x07, 0x2f, 0xc1, 0xc1, 0x77, 0xfe, 0x71, 0xe9, 0x2e, 0x25, 0xbf, 0x03, 0xe4, 0xec, 0xb7, 0x2f, 0x47, 0xb6, 0x4d, 0x04, 0x65, 0xaa, 0xea, 0x4c, 0x7f, 0xad, 0x37, 0x25, 0x36, 0xc8, 0xba, 0x51, 0x6a, 0x60, 0x39, 0xc3, 0xc2, 0xa3, 0x9f, 0x0e, 0x4d, 0x83, 0x2b, 0xe4, 0x32, 0xdf, 0xa9, 0xa7, 0x06, 0xa6, 0xe5, 0xc7, 0xe1, 0x9f, 0x39, 0x79, 0x64, 0xca, 0x42, 0x58, 0x00, 0x2f, 0x7c, 0x05, 0x41, 0xb5, 0x90, 0x31, 0x 6d, 0xbc, 0x56, 0x22, 0xb6, 0xb2, 0xa6, 0xfe, 0x7a, 0x4a, 0xbf, 0xfd, 0x96, 0x10, 0x5e, 0xca, 0x76, 0xea, 0x7b, 0x98, 0x81, 0x6a, 0xf0, 0x74, 0x8c, 0x10, 0xdf, 0x04, 0x8c, 0xe0, 0x12, 0xd9, 0x01, 0x01, 0x5a, 0x51, 0xf1, 0x89, 0xf3, 0x88, 0x81, 0x45, 0xc0, 0x36, 0x50, 0xaa, 0x23, 0xce, 0x89, 0x4c, 0x3b, 0xd8, 0x89, 0xe0, 0x30, 0xd5, 0x65, 0x07, 0x1c, 0x59, 0xf4, 0x09, 0xa9, 0x98, 0x1b, 0x51, 0x87, 0x8f, 0xd6, 0xfc, 0x11, 0x06, 0x24, 0xdc, 0xbc, 0xde, 0x0b, 0xf7, 0xa6, 0x9c, 0xcc, 0xe3, 0x8f, 0xab, 0xdf, 0x86, 0xf3, 0xbe, 0xf6, 0x04, 0x48, 0x19, 0xde, 0x11}, + std::vector<uint8_t>{0x6d, 0xdf, 0x80, 0x2e, 0x1a, 0xae, 0x49, 0x86, 0x93, 0x5f, 0x7f, 0x98, 0x1b, 0xa3, 0xf0, 0x35, 0x1d, 0x62, 0x73, 0xc0, 0xa0, 0xc2, 0x2c, 0x9c, 0x0e, 0x83, 0x39, 0x16, 0x8e, 0x67, 0x54, 0x12, 0xa3, 0xde, 0xbf, 0xaf, 0x43, 0x5e, 0xd6, 0x51, 0x55, 0x80, 0x07, 0xdb, 0x43, 0x84, 0xb6, 0x50, 0xfc, 0xc0, 0x7e, 0x3b, 0x58, 0x6a, 0x27, 0xa4, 0xf7, 0xa0, 0x0a, 0xc8, 0xa6, 0xfe, 0xc2, 0xcd, 0x86, 0xae, 0x4b, 0xf1, 0x57, 0x0c, 0x41, 0xe6, 0xa4, 0x0c, 0x93, 0x1d, 0xb2, 0x7b, 0x2f, 0xaa, 0x15, 0xa8, 0xce, 0xdd, 0x52, 0xcf, 0xf7, 0x36, 0x2c, 0x4e, 0x6e, 0x23, 0xda, 0xec, 0x0f, 0xbc, 0x3a, 0x79, 0xb6, 0x80, 0x6e, 0x31, 0x6e, 0xfc, 0xc7, 0xb6, 0x81, 0x19, 0xbf, 0x46, 0xbc, 0x76, 0xa2, 0x60, 0x67, 0xa5, 0x3f, 0x29, 0x6d, 0xaf, 0xdb, 0xdc, 0x11, 0xc7, 0x7f, 0x77, 0x77, 0xe9, 0x72, 0x66, 0x0c, 0xf4, 0xb6, 0xa9, 0xb3, 0x69, 0xa6, 0x66, 0x5f, 0x02, 0xe0, 0xcc, 0x9b, 0x6e, 0xdf, 0xad, 0x13, 0x6b, 0x4f, 0xab, 0xe7, 0x23, 0xd2, 0x81, 0x3d, 0xb3, 0x13, 0x6c, 0xfd, 0xe9, 0xb6, 0xd0, 0x 44, 0x32, 0x2f, 0xee, 0x29, 0x47, 0x95, 0x2e, 0x03, 0x1b, 0x73, 0xab, 0x5c, 0x60, 0x33, 0x49, 0xb3, 0x07, 0xbd, 0xc2, 0x7b, 0xc6, 0xcb, 0x8b, 0x8b, 0xbd, 0x7b, 0xd3, 0x23, 0x21, 0x9b, 0x80, 0x33, 0xa5, 0x81, 0xb5, 0x9e, 0xad, 0xeb, 0xb0, 0x9b, 0x3c, 0x4f, 0x3d, 0x22, 0x77, 0xd4, 0xf0, 0x34, 0x36, 0x24, 0xac, 0xc8, 0x17, 0x80, 0x47, 0x28, 0xb2, 0x5a, 0xb7, 0x97, 0x17, 0x2b, 0x4c, 0x5c, 0x21, 0xa2, 0x2f, 0x9c, 0x78, 0x39, 0xd6, 0x43, 0x00, 0x23, 0x2e, 0xb6, 0x6e, 0x53, 0xf3, 0x1c, 0x72, 0x3f, 0xa3, 0x7f, 0xe3, 0x87, 0xc7, 0xd3, 0xe5, 0x0b, 0xdf, 0x98, 0x13, 0xa3, 0x0e, 0x5b, 0xb1, 0x2c, 0xf4, 0xcd, 0x93, 0x0c, 0x40, 0xcf, 0xb4, 0xe1, 0xfc, 0x62, 0x25, 0x92, 0xa4, 0x95, 0x88, 0x79, 0x44, 0x94, 0xd5, 0x6d, 0x24, 0xea, 0x4b, 0x40, 0xc8, 0x9f, 0xc0, 0x59, 0x6c, 0xc9, 0xeb, 0xb9, 0x61, 0xc8, 0xcb, 0x10, 0xad, 0xde, 0x97, 0x6a, 0x5d, 0x60, 0x2b, 0x1c, 0x3f, 0x85, 0xb9, 0xb9, 0xa0, 0x01, 0xed, 0x3c, 0x6a, 0x4d, 0x3b, 0x14, 0x37, 0xf5, 0x20, 0x96, 0xcd, 0x19, 0x56, 0xd0, 0x42, 0xa5, 0x97, 0xd 5, 0x61, 0xa5, 0x96, 0xec, 0xd3, 0xd1, 0x73, 0x5a, 0x8d, 0x57, 0x0e, 0xa0, 0xec, 0x27, 0x22, 0x5a, 0x2c, 0x4a, 0xaf, 0xf2, 0x63, 0x06, 0xd1, 0x52, 0x6c, 0x1a, 0xf3, 0xca, 0x6d, 0x9c, 0xf5, 0xa2, 0xc9, 0x8f, 0x47, 0xe1, 0xc4, 0x6d, 0xb9, 0xa3, 0x32, 0x34, 0xcf, 0xd4, 0xd8, 0x1f, 0x2c, 0x98, 0x53, 0x8a, 0x09, 0xeb, 0xe7, 0x69, 0x98, 0xd0, 0xd8, 0xfd, 0x25, 0x99, 0x7c, 0x7d, 0x25, 0x5c, 0x6d, 0x66, 0xec, 0xe6, 0xfa, 0x56, 0xf1, 0x11, 0x44, 0x95, 0x0f, 0x02, 0x77, 0x95, 0xe6, 0x53, 0x00, 0x8f, 0x4b, 0xd7, 0xca, 0x2d, 0xee, 0x85, 0xd8, 0xe9, 0x0f, 0x3d, 0xc3, 0x15, 0x13, 0x0c, 0xe2, 0xa0, 0x03, 0x75, 0xa3, 0x18, 0xc7, 0xc3, 0xd9, 0x7b, 0xe2, 0xc8, 0xce, 0x5b, 0x6d, 0xb4, 0x1a, 0x62, 0x54, 0xff, 0x26, 0x4f, 0xa6, 0x15, 0x5b, 0xae, 0xe3, 0xb0, 0x77, 0x3c, 0x0f, 0x49, 0x7c, 0x57, 0x3f, 0x19, 0xbb, 0x4f, 0x42, 0x40, 0x28, 0x1f, 0x0b, 0x1f, 0x4f, 0x7b, 0xe8, 0x57, 0xa4, 0xe5, 0x9d, 0x41, 0x6c, 0x06, 0xb4, 0xc5, 0x0f, 0xa0, 0x9e, 0x18, 0x10, 0xdd, 0xc6, 0xb1, 0x46, 0x7b, 0xae, 0xac, 0x5a, 0x36 , 0x68, 0xd1, 0x1b, 0x6e, 0xca, 0xa9, 0x01, 0x44, 0x00, 0x16, 0xf3, 0x89, 0xf8, 0x0a, 0xcc, 0x4d, 0xb9, 0x77, 0x02, 0x5e, 0x7f, 0x59, 0x24, 0x38, 0x8c, 0x7e, 0x34, 0x0a, 0x73, 0x2e, 0x55, 0x44, 0x40, 0xe7, 0x65, 0x70, 0xf8, 0xdd, 0x71, 0xb7, 0xd6, 0x40, 0xb3, 0x45, 0x0d, 0x1f, 0xd5, 0xf0, 0x41, 0x0a, 0x18, 0xf9, 0xa3, 0x49, 0x4f, 0x70, 0x7c, 0x71, 0x7b, 0x79, 0xb4, 0xbf, 0x75, 0xc9, 0x84, 0x00, 0xb0, 0x96, 0xb2, 0x16, 0x53, 0xb5, 0xd2, 0x17, 0xcf, 0x35, 0x65, 0xc9, 0x59, 0x74, 0x56, 0xf7, 0x07, 0x03, 0x49, 0x7a, 0x07, 0x87, 0x63, 0x82, 0x9b, 0xc0, 0x1b, 0xb1, 0xcb, 0xc8, 0xfa, 0x04, 0xea, 0xdc, 0x9a, 0x6e, 0x3f, 0x66, 0x99, 0x58, 0x7a, 0x9e, 0x75, 0xc9, 0x4e, 0x5b, 0xab, 0x00, 0x36, 0xe0, 0xb2, 0xe7, 0x11, 0x39, 0x2c, 0xff, 0x00, 0x47, 0xd0, 0xd6, 0xb0, 0x5b, 0xd2, 0xa5, 0x88, 0xbc, 0x10, 0x97, 0x18, 0x95, 0x42, 0x59, 0xf1, 0xd8, 0x66, 0x78, 0xa5, 0x79, 0xa3, 0x12, 0x0f, 0x19, 0xcf, 0xb2, 0x96, 0x3f, 0x17, 0x7a, 0xeb, 0x70, 0xf2, 0xd4, 0x84, 0x48, 0x26, 0x26, 0x2e, 0x51, 0xb8, 0x02, 0x71, 0x27, 0x20, 0x68, 0xef, 0x5b, 0x38, 0x56, 0xfa, 0x85, 0x35, 0xaa, 0x2a, 0x88, 0xb2, 0xd4, 0x1f, 0x2a, 0x0e, 0x2f, 0xda, 0x76, 0x24, 0xc2, 0x85, 0x02, 0x72, 0xac, 0x4a, 0x2f, 0x56, 0x1f, 0x8f, 0x2f, 0x7a, 0x31, 0x8b, 0xfd, 0x5c, 0xaf, 0x96, 0x96, 0x14, 0x9e, 0x4a, 0xc8, 0x24, 0xad, 0x34, 0x60, 0x53, 0x8f, 0xdc, 0x25, 0x42, 0x1b, 0xee, 0xc2, 0xcc, 0x68, 0x18, 0x16, 0x2d, 0x06, 0xbb, 0xed, 0x0c, 0x40, 0xa3, 0x87, 0x19, 0x23, 0x49, 0xdb, 0x67, 0xa1, 0x18, 0xba, 0xda, 0x6c, 0xd5, 0xab, 0x01, 0x40, 0xee, 0x27, 0x32, 0x04, 0xf6, 0x28, 0xaa, 0xd1, 0xc1, 0x35, 0xf7, 0x70, 0x27, 0x9a, 0x65, 0x1e, 0x24, 0xd8, 0xc1, 0x4d, 0x75, 0xa6, 0x05, 0x9d, 0x76, 0xb9, 0x6a, 0x6f, 0xd8, 0x57, 0xde, 0xf5, 0xe0, 0xb3, 0x54, 0xb2, 0x7a, 0xb9, 0x37, 0xa5, 0x81, 0x5d, 0x16, 0xb5, 0xfa, 0xe4, 0x07, 0xff, 0x18, 0x22, 0x2c, 0x6d, 0x1e, 0xd2, 0x63, 0xbe, 0x68, 0xc9, 0x5f, 0x32, 0xd9, 0x08, 0xbd, 0x89, 0x5c, 0xd7, 0x62, 0x07, 0xae, 0x72, 0x64, 0x87, 0x56, 0x7f, 0x9a, 0x67, 0xda, 0xd7, 0x9a, 0xbe, 0xc3, 0x16, 0xf6, 0x83, 0xb1, 0x7f, 0x2d, 0x02, 0xbf, 0x07, 0xe0, 0xac, 0x8b, 0x5b, 0xc6, 0x16, 0x2c, 0xf9, 0x46, 0x97, 0xb3, 0xc2, 0x7c, 0xd1, 0xfe, 0xa4, 0x9b, 0x27, 0xf2, 0x3b, 0xa2, 0x90, 0x18, 0x71, 0x96, 0x25, 0x06, 0x52, 0x0c, 0x39, 0x2d, 0xa8, 0xb6, 0xad, 0x0d, 0x99, 0xf7, 0x01, 0x3f, 0xbc, 0x06, 0xc2, 0xc1, 0x7a, 0x56, 0x95, 0x00, 0xc8, 0xa7, 0x69, 0x64, 0x81, 0xc1, 0xcd, 0x33, 0xe9, 0xb1, 0x4e, 0x40, 0xb8, 0x2e, 0x79, 0xa5, 0xf5, 0xdb, 0x82, 0x57, 0x1b, 0xa9, 0x7b, 0xae, 0x3a, 0xd3, 0xe0, 0x47, 0x95, 0x15, 0xbb, 0x0e, 0x2b, 0x0f, 0x3b, 0xfc, 0xd1, 0xfd, 0x33, 0x03, 0x4e, 0xfc, 0x62, 0x45, 0xed, 0xdd, 0x7e, 0xe2, 0x08, 0x6d, 0xda, 0xe2, 0x60, 0x0d, 0x8c, 0xa7, 0x3e, 0x21, 0x4e, 0x8c, 0x2b, 0x0b, 0xdb, 0x2b, 0x04, 0x7c, 0x6a, 0x46, 0x4a, 0x56, 0x2e, 0xd7, 0x7b, 0x73, 0xd2, 0xd8, 0x41, 0xc4, 0xb3, 0x49, 0x73, 0x55, 0x12, 0x57, 0x71, 0x3b, 0x75, 0x36, 0x32, 0xef, 0xba, 0x34, 0x81, 0x69, 0xab, 0xc9, 0x0a, 0x68, 0xf4, 0x26, 0x11, 0xa4, 0x01, 0x26, 0xd7, 0xcb, 0x21, 0xb5, 0x86, 0x95, 0x56, 0 x81, 0x86, 0xf7, 0xe5, 0x69, 0xd2, 0xff, 0x0f, 0x9e, 0x74, 0x5d, 0x04, 0x87, 0xdd, 0x2e, 0xb9, 0x97, 0xca, 0xfc, 0x5a, 0xbf, 0x9d, 0xd1, 0x02, 0xe6, 0x2f, 0xf6, 0x6c, 0xba, 0x87} + }}; + + std::array<std::vector<uint8_t>, c448_patternsSize> c448_signatures = {{ + std::vector<uint8_t>{0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25, 0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae, 0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2, 0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f, 0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81, 0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78, 0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39, 0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a, 0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d, 0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41, 0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd, 0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb, 0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26, 0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65, 0x26, 0x00}, + std::vector<uint8_t>{0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89, 0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3, 0x77, 0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35, 0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10, 0xf4, 0x35, 0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7, 0xe1, 0x8f, 0x62, 0xde, 0x8c, 0xcd, 0xf6, 0x33, 0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79, 0x80, 0x5e, 0x0d, 0xbc, 0xc0, 0xaa, 0xe1, 0xcb, 0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36, 0xbc, 0x04, 0xdc, 0xec, 0xbf, 0x15, 0x43, 0x36, 0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29, 0x05, 0xe7, 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f, 0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf, 0xd1, 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0, 0x3a, 0x00}, + std::vector<uint8_t>{0x1f, 0x0a, 0x88, 0x88, 0xce, 0x25, 0xe8, 0xd4, 0x58, 0xa2, 0x11, 0x30, 0x87, 0x9b, 0x84, 0x0a, 0x90, 0x89, 0xd9, 0x99, 0xaa, 0xba, 0x03, 0x9e, 0xaf, 0x3e, 0x3a, 0xfa, 0x09, 0x0a, 0x09, 0xd3, 0x89, 0xdb, 0xa8, 0x2c, 0x4f, 0xf2, 0xae, 0x8a, 0xc5, 0xcd, 0xfb, 0x7c, 0x55, 0xe9, 0x4d, 0x5d, 0x96, 0x1a, 0x29, 0xfe, 0x01, 0x09, 0x94, 0x1e, 0x00, 0xb8, 0xdb, 0xde, 0xea, 0x6d, 0x3b, 0x05, 0x10, 0x68, 0xdf, 0x72, 0x54, 0xc0, 0xcd, 0xc1, 0x29, 0xcb, 0xe6, 0x2d, 0xb2, 0xdc, 0x95, 0x7d, 0xbb, 0x47, 0xb5, 0x1f, 0xd3, 0xf2, 0x13, 0xfb, 0x86, 0x98, 0xf0, 0x64, 0x77, 0x42, 0x50, 0xa5, 0x02, 0x89, 0x61, 0xc9, 0xbf, 0x8f, 0xfd, 0x97, 0x3f, 0xe5, 0xd5, 0xc2, 0x06, 0x49, 0x2b, 0x14, 0x0e, 0x00}, + std::vector<uint8_t>{0x7e, 0xee, 0xab, 0x7c, 0x4e, 0x50, 0xfb, 0x79, 0x9b, 0x41, 0x8e, 0xe5, 0xe3, 0x19, 0x7f, 0xf6, 0xbf, 0x15, 0xd4, 0x3a, 0x14, 0xc3, 0x43, 0x89, 0xb5, 0x9d, 0xd1, 0xa7, 0xb1, 0xb8, 0x5b, 0x4a, 0xe9, 0x04, 0x38, 0xac, 0xa6, 0x34, 0xbe, 0xa4, 0x5e, 0x3a, 0x26, 0x95, 0xf1, 0x27, 0x0f, 0x07, 0xfd, 0xcd, 0xf7, 0xc6, 0x2b, 0x8e, 0xfe, 0xaf, 0x00, 0xb4, 0x5c, 0x2c, 0x96, 0xba, 0x45, 0x7e, 0xb1, 0xa8, 0xbf, 0x07, 0x5a, 0x3d, 0xb2, 0x8e, 0x5c, 0x24, 0xf6, 0xb9, 0x23, 0xed, 0x4a, 0xd7, 0x47, 0xc3, 0xc9, 0xe0, 0x3c, 0x70, 0x79, 0xef, 0xb8, 0x7c, 0xb1, 0x10, 0xd3, 0xa9, 0x98, 0x61, 0xe7, 0x20, 0x03, 0xcb, 0xae, 0x6d, 0x6b, 0x8b, 0x82, 0x7e, 0x4e, 0x6c, 0x14, 0x30, 0x64, 0xff, 0x3c, 0x00}, + std::vector<uint8_t>{0x6a, 0x12, 0x06, 0x6f, 0x55, 0x33, 0x1b, 0x6c, 0x22, 0xac, 0xd5, 0xd5, 0xbf, 0xc5, 0xd7, 0x12, 0x28, 0xfb, 0xda, 0x80, 0xae, 0x8d, 0xec, 0x26, 0xbd, 0xd3, 0x06, 0x74, 0x3c, 0x50, 0x27, 0xcb, 0x48, 0x90, 0x81, 0x0c, 0x16, 0x2c, 0x02, 0x74, 0x68, 0x67, 0x5e, 0xcf, 0x64, 0x5a, 0x83, 0x17, 0x6c, 0x0d, 0x73, 0x23, 0xa2, 0xcc, 0xde, 0x2d, 0x80, 0xef, 0xe5, 0xa1, 0x26, 0x8e, 0x8a, 0xca, 0x1d, 0x6f, 0xbc, 0x19, 0x4d, 0x3f, 0x77, 0xc4, 0x49, 0x86, 0xeb, 0x4a, 0xb4, 0x17, 0x79, 0x19, 0xad, 0x8b, 0xec, 0x33, 0xeb, 0x47, 0xbb, 0xb5, 0xfc, 0x6e, 0x28, 0x19, 0x6f, 0xd1, 0xca, 0xf5, 0x6b, 0x4e, 0x7e, 0x0b, 0xa5, 0x51, 0x92, 0x34, 0xd0, 0x47, 0x15, 0x5a, 0xc7, 0x27, 0xa1, 0x05, 0x31, 0x00}, + std::vector<uint8_t>{0x55, 0x4b, 0xc2, 0x48, 0x08, 0x60, 0xb4, 0x9e, 0xab, 0x85, 0x32, 0xd2, 0xa5, 0x33, 0xb7, 0xd5, 0x78, 0xef, 0x47, 0x3e, 0xeb, 0x58, 0xc9, 0x8b, 0xb2, 0xd0, 0xe1, 0xce, 0x48, 0x8a, 0x98, 0xb1, 0x8d, 0xfd, 0xe9, 0xb9, 0xb9, 0x07, 0x75, 0xe6, 0x7f, 0x47, 0xd4, 0xa1, 0xc3, 0x48, 0x20, 0x58, 0xef, 0xc9, 0xf4, 0x0d, 0x2c, 0xa0, 0x33, 0xa0, 0x80, 0x1b, 0x63, 0xd4, 0x5b, 0x3b, 0x72, 0x2e, 0xf5, 0x52, 0xba, 0xd3, 0xb4, 0xcc, 0xb6, 0x67, 0xda, 0x35, 0x01, 0x92, 0xb6, 0x1c, 0x50, 0x8c, 0xf7, 0xb6, 0xb5, 0xad, 0xad, 0xc2, 0xc8, 0xd9, 0xa4, 0x46, 0xef, 0x00, 0x3f, 0xb0, 0x5c, 0xba, 0x5f, 0x30, 0xe8, 0x8e, 0x36, 0xec, 0x27, 0x03, 0xb3, 0x49, 0xca, 0x22, 0x9c, 0x26, 0x70, 0x83, 0x39, 0x00}, + std::vector<uint8_t>{0xc6, 0x50, 0xdd, 0xbb, 0x06, 0x01, 0xc1, 0x9c, 0xa1, 0x14, 0x39, 0xe1, 0x64, 0x0d, 0xd9, 0x31, 0xf4, 0x3c, 0x51, 0x8e, 0xa5, 0xbe, 0xa7, 0x0d, 0x3d, 0xcd, 0xe5, 0xf4, 0x19, 0x1f, 0xe5, 0x3f, 0x00, 0xcf, 0x96, 0x65, 0x46, 0xb7, 0x2b, 0xcc, 0x7d, 0x58, 0xbe, 0x2b, 0x9b, 0xad, 0xef, 0x28, 0x74, 0x39, 0x54, 0xe3, 0xa4, 0x4a, 0x23, 0xf8, 0x80, 0xe8, 0xd4, 0xf1, 0xcf, 0xce, 0x2d, 0x7a, 0x61, 0x45, 0x2d, 0x26, 0xda, 0x05, 0x89, 0x6f, 0x0a, 0x50, 0xda, 0x66, 0xa2, 0x39, 0xa8, 0xa1, 0x88, 0xb6, 0xd8, 0x25, 0xb3, 0x30, 0x5a, 0xd7, 0x7b, 0x73, 0xfb, 0xac, 0x08, 0x36, 0xec, 0xc6, 0x09, 0x87, 0xfd, 0x08, 0x52, 0x7c, 0x1a, 0x8e, 0x80, 0xd5, 0x82, 0x3e, 0x65, 0xca, 0xfe, 0x2a, 0x3d, 0x00}, + std::vector<uint8_t>{0xe3, 0x01, 0x34, 0x5a, 0x41, 0xa3, 0x9a, 0x4d, 0x72, 0xff, 0xf8, 0xdf, 0x69, 0xc9, 0x80, 0x75, 0xa0, 0xcc, 0x08, 0x2b, 0x80, 0x2f, 0xc9, 0xb2, 0xb6, 0xbc, 0x50, 0x3f, 0x92, 0x6b, 0x65, 0xbd, 0xdf, 0x7f, 0x4c, 0x8f, 0x1c, 0xb4, 0x9f, 0x63, 0x96, 0xaf, 0xc8, 0xa7, 0x0a, 0xbe, 0x6d, 0x8a, 0xef, 0x0d, 0xb4, 0x78, 0xd4, 0xc6, 0xb2, 0x97, 0x00, 0x76, 0xc6, 0xa0, 0x48, 0x4f, 0xe7, 0x6d, 0x76, 0xb3, 0xa9, 0x76, 0x25, 0xd7, 0x9f, 0x1c, 0xe2, 0x40, 0xe7, 0xc5, 0x76, 0x75, 0x0d, 0x29, 0x55, 0x28, 0x28, 0x6f, 0x71, 0x9b, 0x41, 0x3d, 0xe9, 0xad, 0xa3, 0xe8, 0xeb, 0x78, 0xed, 0x57, 0x36, 0x03, 0xce, 0x30, 0xd8, 0xbb, 0x76, 0x17, 0x85, 0xdc, 0x30, 0xdb, 0xc3, 0x20, 0x86, 0x9e, 0x1a, 0x00} + }}; + + + + for (size_t i=0; i<c448_messages.size(); i++) { + auto Alice = make_Signature<C448>(); + Alice->set_secret(DSA<C448, lime::DSAtype::privateKey> (c448_secret_keys[i].cbegin())); + + Alice->derivePublic(); + BC_ASSERT_TRUE(memcmp(Alice->get_public().data(), c448_public_keys[i].data(), c448_public_keys[i].size())==0); + DSA<C448, lime::DSAtype::signature> signature{}; + Alice->sign(c448_messages[i], signature); + BC_ASSERT_TRUE(memcmp(signature.data(), c448_signatures[i].data(), c448_signatures[i].size())==0); + + auto Vera = make_Signature<C448>(); + Vera->set_public(DSA<C448, lime::DSAtype::publicKey>(c448_public_keys[i].cbegin())); + BC_ASSERT_TRUE(Vera->verify(c448_messages[i], signature)); + } + #endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/tester/lime_double_ratchet-tester.cpp new/lime-5.0.0/tester/lime_double_ratchet-tester.cpp --- old/lime-4.5.7/tester/lime_double_ratchet-tester.cpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/tester/lime_double_ratchet-tester.cpp 2021-05-11 23:07:21.000000000 +0200 @@ -91,7 +91,7 @@ recipients[i].emplace_back("bob",alice); std::vector<uint8_t> plaintext{lime_tester::messages_pattern[i].begin(), lime_tester::messages_pattern[i].end()}; std::vector<uint8_t> cipherMessage{}; - encryptMessage(recipients[i], plaintext, "bob", "alice", cipher[i], lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(recipients[i], plaintext, "bob", "alice", cipher[i], lime::EncryptionPolicy::optimizeUploadSize, aliceLocalStorage); bctbx_debug("alice encrypt %d", int(i)); messageSender[i] = 1; @@ -103,7 +103,7 @@ recipients[i].emplace_back("alice",bob); std::vector<uint8_t> plaintext{lime_tester::messages_pattern[i].begin(), lime_tester::messages_pattern[i].end()}; std::vector<uint8_t> cipherMessage{}; - encryptMessage(recipients[i], plaintext, "alice", "bob", cipher[i], lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(recipients[i], plaintext, "alice", "bob", cipher[i], lime::EncryptionPolicy::optimizeUploadSize, bobLocalStorage); bctbx_debug("bob encrypt %d", int(i)); messageSender[i] = 2; @@ -241,7 +241,7 @@ recipients.emplace_back("bob",alice); std::vector<uint8_t> plaintext{lime_tester::messages_pattern[i].begin(), lime_tester::messages_pattern[i].end()}; std::vector<uint8_t> cipherMessage{}; - encryptMessage(recipients, plaintext, "bob", "alice", cipherMessage, lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(recipients, plaintext, "bob", "alice", cipherMessage, lime::EncryptionPolicy::optimizeUploadSize, aliceLocalStorage); // bob decrypt it std::vector<shared_ptr<DR<Curve>>> recipientDRSessions{}; @@ -265,7 +265,7 @@ recipients.emplace_back("alice",bob); std::vector<uint8_t> plaintext{lime_tester::messages_pattern[i].begin(), lime_tester::messages_pattern[i].end()}; std::vector<uint8_t> cipherMessage{}; - encryptMessage(recipients, plaintext, "alice", "bob", cipherMessage, lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(recipients, plaintext, "alice", "bob", cipherMessage, lime::EncryptionPolicy::optimizeUploadSize, bobLocalStorage); // alice decrypt it std::vector<shared_ptr<DR<Curve>>> recipientDRSessions{}; @@ -345,7 +345,7 @@ std::vector<RecipientInfos<Curve>> recipients; recipients.emplace_back("bob",DRsessionAlice); std::vector<uint8_t> plaintextAlice{messageAlice.begin(), messageAlice.end()}; - encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, setEncryptionPolicyAlice); + encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, setEncryptionPolicyAlice, localStorageAlice); if (checkEncryptionPolicy) { bool is_directEncryptionType = lime_tester::DR_message_payloadDirectEncrypt(recipients[0].DRmessage); @@ -371,7 +371,7 @@ recipients.clear(); recipients.emplace_back("alice",DRsessionBob); std::vector<uint8_t> plaintextBob{messageBob.begin(), messageBob.end()}; - encryptMessage(recipients, plaintextBob, "alice", "bob", bobCipher, setEncryptionPolicyBob); + encryptMessage(recipients, plaintextBob, "alice", "bob", bobCipher, setEncryptionPolicyBob, localStorageBob); if (checkEncryptionPolicy) { // we must check Bob encryption type bool is_directEncryptionType = lime_tester::DR_message_payloadDirectEncrypt(recipients[0].DRmessage); @@ -477,7 +477,7 @@ std::vector<uint8_t> cipherMessage; std::vector<uint8_t> plaintext{message.begin(), message.end()}; - encryptMessage(recipients, plaintext, usernames[1], sourceId, cipherMessage, setEncryptionPolicy); + encryptMessage(recipients, plaintext, usernames[1], sourceId, cipherMessage, setEncryptionPolicy, users[0][0][1][0].localStorage); if (checkEncryptionPolicy) { // we must check encryption type bool is_directEncryptionType = lime_tester::DR_message_payloadDirectEncrypt(recipients[0].DRmessage); // check on recipients[0], they shall all be the same @@ -561,7 +561,7 @@ std::vector<uint8_t> plaintextAlice{lime_tester::messages_pattern[1].begin(), lime_tester::messages_pattern[1].end()}; for (auto i=0; i<lime::settings::maxMessageSkip+2; i++) { // we can skip maxMessageSkip, so encrypt +2 and we will skip +1 // alice encrypt a message, just discard it, it's not the point to decrypt it - encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize, localStorageAlice); } // now decrypt the last encrypted message, it shall fail: too much skiped messages @@ -586,7 +586,7 @@ recipients.clear(); recipients.emplace_back("bob",alice); plaintextAlice.assign(lime_tester::messages_pattern[1].begin(), lime_tester::messages_pattern[1].end()); - encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize, localStorageAlice); // bob decrypt it - Bob perform a DH Ratchet and than have receiving chain n, sending chain n+1 recipientDRSessions.clear(); @@ -603,7 +603,7 @@ recipients.clear(); recipients.emplace_back("alice",bob); std::vector<uint8_t> plaintextBob{lime_tester::messages_pattern[2].begin(), lime_tester::messages_pattern[2].end()}; - encryptMessage(recipients, plaintextBob, "alice", "bob", bobCipher, lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(recipients, plaintextBob, "alice", "bob", bobCipher, lime::EncryptionPolicy::optimizeUploadSize, localStorageBob); // alice did not get bob reply, and encrypt maxMessageSkip/2 messages, with sending chain n (receiving chain is still n too)) aliceCipher.clear(); @@ -612,7 +612,7 @@ plaintextAlice.assign(lime_tester::messages_pattern[2].begin(), lime_tester::messages_pattern[2].end()); for (auto i=0; i<lime::settings::maxMessageSkip/2; i++) { // alice encrypt a message, just discard it, it's not the point to decrypt it - encryptMessage(lostRecipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(lostRecipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize, localStorageAlice); } // alice now decrypt bob's message performing a DH ratchet, after that she has sending chain n+1, receiving chain n+1 @@ -632,7 +632,7 @@ plaintextAlice.assign(lime_tester::messages_pattern[2].begin(), lime_tester::messages_pattern[2].end()); for (auto i=0; i<lime::settings::maxMessageSkip/2+3; i++) { // alice encrypt a message, just discard it, it's not the point to decrypt it - encryptMessage(lostRecipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize); + encryptMessage(lostRecipients, plaintextAlice, "bob", "alice", aliceCipher, lime::EncryptionPolicy::optimizeUploadSize, localStorageAlice); } // now decrypt the last encrypted message, it shall fail: bob is on receiving chain n and missed maxMessageSkip/2 on it + maxMessageSkip/2+3 in receiving chain n+1 @@ -803,7 +803,7 @@ std::vector<RecipientInfos<Curve>> recipients; recipients.emplace_back("bob",DRsessionAlice); std::vector<uint8_t> plaintextAlice{lime_tester::messages_pattern[0].begin(), lime_tester::messages_pattern[0].end()}; - encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, encryptionPolicy); + encryptMessage(recipients, plaintextAlice, "bob", "alice", aliceCipher, encryptionPolicy, localStorageAlice); if (encryptionPolicy == lime::EncryptionPolicy::cipherMessage) { // we shall have a cipherMessage, delete it BC_ASSERT_TRUE(aliceCipher.size() > 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/tester/lime_ffi-tester.c new/lime-5.0.0/tester/lime_ffi-tester.c --- old/lime-4.5.7/tester/lime_ffi-tester.c 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/tester/lime_ffi-tester.c 2021-05-11 23:07:21.000000000 +0200 @@ -134,7 +134,7 @@ belle_sip_message_t *message = BELLE_SIP_MESSAGE(event->response); /* all raw data access functions in lime use uint8_t *, so safely cast the body pointer to it, it's just a data stream pointer anyway */ const uint8_t *body = (const uint8_t *)belle_sip_message_get_body(message); - int bodySize = belle_sip_message_get_body_size(message); + int bodySize = (int)belle_sip_message_get_body_size(message); lime_ffi_processX3DHServerResponse((lime_ffi_data_t)userData, code, body, bodySize); } else { lime_ffi_processX3DHServerResponse((lime_ffi_data_t)userData, 0, NULL, 0); @@ -440,7 +440,7 @@ BC_ASSERT_TRUE(lime_ffi_decrypt(bobManager, bobDeviceId, "bob", aliceDeviceId, bobReceivedDRmessage, bobReceivedDRmessageSize, bobReceivedCipherMessage, bobReceivedCipherMessageSize, decryptedMessage, &decryptedMessageSize) == lime_ffi_PeerDeviceStatus_trusted); /* check we got the original message back */ - BC_ASSERT_EQUAL(message_patternSize, decryptedMessageSize, int, "%d"); + BC_ASSERT_EQUAL((int)message_patternSize, (int)decryptedMessageSize, int, "%d"); BC_ASSERT_TRUE(strncmp(message_pattern[0], (char *)decryptedMessage, (message_patternSize<decryptedMessageSize)?message_patternSize:decryptedMessageSize)==0); free(decryptedMessage); @@ -693,7 +693,7 @@ uint8_t *decryptedMessage = malloc(decryptedMessageSize); BC_ASSERT_TRUE(lime_ffi_decrypt(bobManager1, bobDeviceId1, "bob", aliceDeviceId, recipients1[0].DRmessage, recipients1[0].DRmessageSize, cipherMessage1, cipherMessageSize1, decryptedMessage, &decryptedMessageSize) == lime_ffi_PeerDeviceStatus_unknown); /* check we got the original message back */ - BC_ASSERT_EQUAL(message_patternSize1, decryptedMessageSize, int, "%d"); + BC_ASSERT_EQUAL((int)message_patternSize1, (int)decryptedMessageSize, int, "%d"); BC_ASSERT_TRUE(strncmp(message_pattern[0], (char *)decryptedMessage, (message_patternSize1<decryptedMessageSize)?message_patternSize1:decryptedMessageSize)==0); free(decryptedMessage); @@ -702,7 +702,7 @@ decryptedMessage = malloc(decryptedMessageSize); BC_ASSERT_TRUE(lime_ffi_decrypt(bobManager1, bobDeviceId1, "bob", aliceDeviceId, recipients2[0].DRmessage, recipients2[0].DRmessageSize, cipherMessage2, cipherMessageSize2, decryptedMessage, &decryptedMessageSize) == lime_ffi_PeerDeviceStatus_untrusted); /* check we got the original message back */ - BC_ASSERT_EQUAL(message_patternSize2, decryptedMessageSize, int, "%d"); + BC_ASSERT_EQUAL((int)message_patternSize2, (int)decryptedMessageSize, int, "%d"); BC_ASSERT_TRUE(strncmp(message_pattern[1], (char *)decryptedMessage, (message_patternSize2<decryptedMessageSize)?message_patternSize2:decryptedMessageSize)==0); free(decryptedMessage); @@ -712,7 +712,7 @@ decryptedMessage = malloc(decryptedMessageSize); BC_ASSERT_TRUE(lime_ffi_decrypt(bobManager2, bobDeviceId2, "bob", aliceDeviceId, recipients2[1].DRmessage, recipients2[1].DRmessageSize, cipherMessage2, cipherMessageSize2, decryptedMessage, &decryptedMessageSize) == lime_ffi_PeerDeviceStatus_unknown); /* check we got the original message back */ - BC_ASSERT_EQUAL(message_patternSize2, decryptedMessageSize, int, "%d"); + BC_ASSERT_EQUAL((int)message_patternSize2, (int)decryptedMessageSize, int, "%d"); BC_ASSERT_TRUE(strncmp(message_pattern[1], (char *)decryptedMessage, (message_patternSize2<decryptedMessageSize)?message_patternSize2:decryptedMessageSize)==0); free(decryptedMessage); @@ -721,7 +721,7 @@ decryptedMessage = malloc(decryptedMessageSize); BC_ASSERT_TRUE(lime_ffi_decrypt(bobManager2, bobDeviceId2, "bob", aliceDeviceId, recipients1[1].DRmessage, recipients1[1].DRmessageSize, cipherMessage1, cipherMessageSize1, decryptedMessage, &decryptedMessageSize) == lime_ffi_PeerDeviceStatus_untrusted); /* check we got the original message back */ - BC_ASSERT_EQUAL(message_patternSize1, decryptedMessageSize, int, "%d"); + BC_ASSERT_EQUAL((int)message_patternSize1, (int)decryptedMessageSize, int, "%d"); BC_ASSERT_TRUE(strncmp(message_pattern[0], (char *)decryptedMessage, (message_patternSize1<decryptedMessageSize)?message_patternSize1:decryptedMessageSize)==0); free(decryptedMessage); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/tester/lime_lime-tester.cpp new/lime-5.0.0/tester/lime_lime-tester.cpp --- old/lime-4.5.7/tester/lime_lime-tester.cpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/tester/lime_lime-tester.cpp 2021-05-11 23:07:21.000000000 +0200 @@ -1462,7 +1462,7 @@ i++; } aliceManager->delete_user(*aliceDeviceId, callback); - expected_success += 1+bobManagers.size(); + expected_success += 1+(int)bobManagers.size(); BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,expected_success,lime_tester::wait_for_timeout)); remove(dbFilenameAlice.data()); remove(dbFilenameBob.data()); @@ -1526,7 +1526,7 @@ size_t SPkCount=0; uint32_t activeSPkId=0; BC_ASSERT_TRUE(lime_tester::get_SPks(dbFilenameAlice, *aliceDeviceId, SPkCount, activeSPkId)); - BC_ASSERT_EQUAL(SPkCount, SPkExpectedCount, int, "%d"); + BC_ASSERT_EQUAL((int)SPkCount, (int)SPkExpectedCount, int, "%d"); // We will create a bob device and encrypt for each new epoch std::vector<std::unique_ptr<LimeManager>> bobManagers{}; @@ -1572,7 +1572,7 @@ SPkCount=0; activeSPkId=0; BC_ASSERT_TRUE(lime_tester::get_SPks(dbFilenameAlice, *aliceDeviceId, SPkCount, activeSPkId)); - BC_ASSERT_EQUAL(SPkCount, SPkExpectedCount, int, "%d"); + BC_ASSERT_EQUAL((int)SPkCount, (int)SPkExpectedCount, int, "%d"); // create a device for bob and use it to encrypt bobManagers.push_back(std::unique_ptr<LimeManager>(new LimeManager(dbFilenameBob, X3DHServerPost))); @@ -1610,7 +1610,7 @@ SPkCount=0; activeSPkId=0; BC_ASSERT_TRUE(lime_tester::get_SPks(dbFilenameAlice, *aliceDeviceId, SPkCount, activeSPkId)); - BC_ASSERT_EQUAL(SPkCount, SPkExpectedCount, int, "%d"); + BC_ASSERT_EQUAL((int)SPkCount, (int)SPkExpectedCount, int, "%d"); // Try to decrypt all message: the first message must fail to decrypt as we just deleted the SPk needed to create the session std::vector<uint8_t> receivedMessage{}; @@ -1630,7 +1630,7 @@ i++; } aliceManager->delete_user(*aliceDeviceId, callback); - expected_success += 1+bobManagers.size(); + expected_success += 1+(int)bobManagers.size(); BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,expected_success,lime_tester::wait_for_timeout)); remove(dbFilenameAlice.data()); remove(dbFilenameBob.data()); @@ -3901,10 +3901,10 @@ // get a mailbox for each of them, same index auto mailbox = make_shared<std::map<std::string, std::shared_ptr<mth_mailbox>>>(); auto expectedMessageCount = 9*test_multithread_message_number; // each recipient shall get 9 times the number of expedited messages by each encryption thread - mailbox->emplace(std::make_pair(deviceList[0], make_shared<mth_mailbox>(deviceList[0], expectedMessageCount))); - mailbox->emplace(std::make_pair(deviceList[1], make_shared<mth_mailbox>(deviceList[1], expectedMessageCount))); - mailbox->emplace(std::make_pair(deviceList[2], make_shared<mth_mailbox>(deviceList[2], expectedMessageCount))); - mailbox->emplace(std::make_pair(deviceList[3], make_shared<mth_mailbox>(deviceList[3], expectedMessageCount))); + mailbox->emplace(std::make_pair(deviceList[0], make_shared<mth_mailbox>(deviceList[0], (int)expectedMessageCount))); + mailbox->emplace(std::make_pair(deviceList[1], make_shared<mth_mailbox>(deviceList[1], (int)expectedMessageCount))); + mailbox->emplace(std::make_pair(deviceList[2], make_shared<mth_mailbox>(deviceList[2], (int)expectedMessageCount))); + mailbox->emplace(std::make_pair(deviceList[3], make_shared<mth_mailbox>(deviceList[3], (int)expectedMessageCount))); // create Manager auto aliceManager = std::make_shared<LimeManager>(dbFilenameAlice, X3DHServerPost_mutex); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-4.5.7/tester/lime_massive_group-tester.cpp new/lime-5.0.0/tester/lime_massive_group-tester.cpp --- old/lime-4.5.7/tester/lime_massive_group-tester.cpp 2020-12-01 21:56:02.000000000 +0100 +++ new/lime-5.0.0/tester/lime_massive_group-tester.cpp 2021-05-11 23:07:21.000000000 +0200 @@ -142,7 +142,7 @@ * In allTalking mode: * - every device takes turn to send messages to all the others */ -static void group_basic_test(const lime::CurveId curve, const std::string &dbBaseFilename, const std::string &x3dh_server_url, const int deviceNumber, bool oneTalking=false) { +static void group_basic_test(const lime::CurveId curve, const std::string &dbBaseFilename, const std::string &x3dh_server_url, const int deviceNumber, bool oneTalking=false, bool oneDecrypt=false) { auto groupName = make_shared<std::string>("group Name"); @@ -191,7 +191,7 @@ devicesId.push_back(make_shared<std::string>(deviceId)); // create user - manager->create_user(deviceId, x3dh_server_url, curve, lime_tester::OPkInitialBatchSize+i, callback); // give them at least <index> OPk at creation + manager->create_user(deviceId, x3dh_server_url, curve, std::min(lime_tester::OPkInitialBatchSize+i, 200), callback); // give them at least <index> OPk at creation, no more than 200 as the server as a limit on it expected_success++; BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, expected_success,lime_tester::wait_for_timeout)); } @@ -260,20 +260,23 @@ auto receivedMessageString = std::string{receivedMessage.begin(), receivedMessage.end()}; BC_ASSERT_TRUE(receivedMessageString == lime_tester::messages_pattern[messages_pattern_index]); recipientDecryptIndex++; + if (oneDecrypt) { + break; // just decrypt one message + } } if (bench) { if (i==0) { // first run shall be the longest as we have deviceNumber-1 sessions to establish span = bctbx_get_cur_time_ms() - startEncrypt; - LIME_LOGE<<"first message decrypts in "<<to_string(span)<<" ms ("<<to_string(float(span)/float(deviceNumber))<<" ms/recipient)"<<std::endl; + LIME_LOGE<<"first message decrypts in "<<to_string(span)<<" ms ("<<to_string(float(span)/float(oneDecrypt?1:deviceNumber-1))<<" ms/recipient)"<<std::endl; } if (i==1 && senderIndex==0) { // second message in oneTalking mode span = bctbx_get_cur_time_ms() - startEncrypt; - LIME_LOGE<<"second message decrypts in "<<to_string(span)<<" ms ("<<to_string(float(span)/float(deviceNumber))<<" ms/recipient)"<<std::endl; + LIME_LOGE<<"second message decrypts in "<<to_string(span)<<" ms ("<<to_string(float(span)/float(oneDecrypt?1:deviceNumber-1))<<" ms/recipient)"<<std::endl; } if (i==deviceNumber-1) { // last run shall be the shortest as we have no session to establish span = bctbx_get_cur_time_ms() - startEncrypt; - LIME_LOGE<<"last message decrypts round in "<<to_string(span)<<" ms ("<<to_string(float(span)/float(deviceNumber))<<" ms/recipient)"<<std::endl; + LIME_LOGE<<"last message decrypts round in "<<to_string(span)<<" ms ("<<to_string(float(span)/float(oneDecrypt?1:deviceNumber-1))<<" ms/recipient)"<<std::endl; } } } @@ -322,6 +325,7 @@ span = bctbx_get_cur_time_ms() - start; LIME_LOGE<<"Curve 25519 group chat test with "<<to_string(deviceNumber)<<" devices ran in "<<to_string(span)<<" ms"<<std::endl; deviceNumber *= int(std::max(float(maximumBenchTime)/float(span), 1.0f) * 1.2); + deviceNumber += 3; } #endif #ifdef EC448_ENABLED @@ -335,6 +339,38 @@ span = bctbx_get_cur_time_ms() - start; LIME_LOGE<<"Curve 448 group chat test with "<<to_string(deviceNumber)<<" devices ran in "<<to_string(span)<<" ms"<<std::endl; deviceNumber *= int(std::max(float(maximumBenchTime)/float(span), 1.0f) * 1.2); + deviceNumber += 3; + } +#endif +} + +static void group_one_talking_one_decrypt_bench() { + if (!bench) return; + int deviceNumber=10; + uint64_t span=0,start = bctbx_get_cur_time_ms(); +#ifdef EC25519_ENABLED + while (span < maximumBenchTime) { + start = bctbx_get_cur_time_ms(); + group_basic_test(lime::CurveId::c25519, "group_one_talking_one_decrypt", std::string("https://").append(lime_tester::test_x3dh_server_url).append(":").append(lime_tester::test_x3dh_c25519_server_port).data(), deviceNumber, true, true); + // time spent in test is more or less linear to the device number, try to reach the one wich lead to a maximunBenchTime execution + span = bctbx_get_cur_time_ms() - start; + LIME_LOGE<<"Curve 25519 group chat test with "<<to_string(deviceNumber)<<" devices ran in "<<to_string(span)<<" ms"<<std::endl; + deviceNumber *= int(std::max(float(maximumBenchTime)/float(span), 1.0f) * 1.2); + deviceNumber += 3; + } +#endif +#ifdef EC448_ENABLED + deviceNumber=10; + start = bctbx_get_cur_time_ms(); + span = 0; + while (span < maximumBenchTime) { + start = bctbx_get_cur_time_ms(); + group_basic_test(lime::CurveId::c448, "group_one_talking_one_decrypt", std::string("https://").append(lime_tester::test_x3dh_server_url).append(":").append(lime_tester::test_x3dh_c448_server_port).data(), deviceNumber, true, true); + // time spent in test is more or less linear to the device number, try to reach the one wich lead to a maximunBenchTime execution + span = bctbx_get_cur_time_ms() - start; + LIME_LOGE<<"Curve 448 group chat test with "<<to_string(deviceNumber)<<" devices ran in "<<to_string(span)<<" ms"<<std::endl; + deviceNumber *= int(std::max(float(maximumBenchTime)/float(span), 1.0f) * 1.2); + deviceNumber += 3; } #endif } @@ -360,6 +396,7 @@ span = bctbx_get_cur_time_ms() - start; LIME_LOGE<<"Curve 25519 group chat test with "<<to_string(deviceNumber)<<" devices ran in "<<to_string(span)<<" ms"<<std::endl; deviceNumber *= int(std::sqrt(std::max(float(maximumBenchTime)/float(span), 1.0f)) * 1.2); + deviceNumber += 3; } #endif #ifdef EC448_ENABLED @@ -373,6 +410,7 @@ span = bctbx_get_cur_time_ms() - start; LIME_LOGE<<"Curve 448 group chat test with "<<to_string(deviceNumber)<<" devices ran in "<<to_string(span)<<" ms"<<std::endl; deviceNumber *= int(std::sqrt(std::max(float(maximumBenchTime)/float(span), 1.0f)) * 1.2); + deviceNumber += 3; } #endif } @@ -382,6 +420,7 @@ TEST_NO_TAG("One message each Bench", group_all_talking_bench), TEST_NO_TAG("One encrypt to all", group_one_talking), TEST_NO_TAG("One encrypt to all Bench", group_one_talking_bench), + TEST_NO_TAG("One encrypt to all Only one decrypt Bench", group_one_talking_one_decrypt_bench), }; test_suite_t lime_massive_group_test_suite = {
