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 = {

Reply via email to