aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/olm/crypto.h31
-rw-r--r--include/olm/crypto.hh15
-rw-r--r--include/olm/ratchet.hh7
-rw-r--r--src/account.cpp10
-rw-r--r--src/cipher.cpp12
-rw-r--r--src/crypto.cpp4
-rw-r--r--src/olm.cpp10
-rw-r--r--src/ratchet.cpp27
-rw-r--r--src/session.cpp51
-rw-r--r--src/utility.cpp2
-rw-r--r--tests/test_crypto.cpp2
11 files changed, 103 insertions, 68 deletions
diff --git a/include/olm/crypto.h b/include/olm/crypto.h
index 31b9b60..325080e 100644
--- a/include/olm/crypto.h
+++ b/include/olm/crypto.h
@@ -27,7 +27,36 @@
extern "C" {
#endif
-const size_t SHA256_OUTPUT_LENGTH = 32;
+/** length of a sha256 hash */
+#define SHA256_OUTPUT_LENGTH 32
+
+/** length of a public or private Curve25519 key */
+#define CURVE25519_KEY_LENGTH 32
+
+/** length of the shared secret created by a Curve25519 ECDH operation */
+#define CURVE25519_SHARED_SECRET_LENGTH 32
+
+/** amount of random data required to create a Curve25519 keypair */
+#define CURVE25519_RANDOM_LENGTH CURVE25519_KEY_LENGTH
+
+/** length of a public Ed25519 key */
+#define ED25519_PUBLIC_KEY_LENGTH 32
+
+/** length of a private Ed25519 key */
+#define ED25519_PRIVATE_KEY_LENGTH 64
+
+/** amount of random data required to create a Ed25519 keypair */
+#define ED25519_RANDOM_LENGTH 32
+
+/** length of an Ed25519 signature */
+#define ED25519_SIGNATURE_LENGTH 64
+
+/** length of an aes256 key */
+#define AES256_KEY_LENGTH 32
+
+/** length of an aes256 initialisation vector */
+#define AES256_IV_LENGTH 16
+
/** Computes SHA-256 of the input. The output buffer must be a least 32
* bytes long. */
diff --git a/include/olm/crypto.hh b/include/olm/crypto.hh
index 484dc83..13fd7e9 100644
--- a/include/olm/crypto.hh
+++ b/include/olm/crypto.hh
@@ -25,23 +25,18 @@
namespace olm {
-static const std::size_t ED25519_PRIVATE_KEY_LENGTH = 64;
-static const std::size_t KEY_LENGTH = 32;
-static const std::size_t SIGNATURE_LENGTH = 64;
-static const std::size_t IV_LENGTH = 16;
-
struct Curve25519PublicKey {
- std::uint8_t public_key[KEY_LENGTH];
+ std::uint8_t public_key[CURVE25519_KEY_LENGTH];
};
struct Curve25519KeyPair : public Curve25519PublicKey {
- std::uint8_t private_key[KEY_LENGTH];
+ std::uint8_t private_key[CURVE25519_KEY_LENGTH];
};
struct Ed25519PublicKey {
- std::uint8_t public_key[KEY_LENGTH];
+ std::uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH];
};
@@ -93,12 +88,12 @@ bool ed25519_verify(
struct Aes256Key {
- std::uint8_t key[KEY_LENGTH];
+ std::uint8_t key[AES256_KEY_LENGTH];
};
struct Aes256Iv {
- std::uint8_t iv[IV_LENGTH];
+ std::uint8_t iv[AES256_IV_LENGTH];
};
diff --git a/include/olm/ratchet.hh b/include/olm/ratchet.hh
index 13f7097..e91d634 100644
--- a/include/olm/ratchet.hh
+++ b/include/olm/ratchet.hh
@@ -21,8 +21,13 @@ struct _olm_cipher;
namespace olm {
-typedef std::uint8_t SharedKey[olm::KEY_LENGTH];
+/** length of a shared key: the root key R(i), chain key C(i,j), and message key
+ * M(i,j)). They are all only used to stuff into HMACs, so could be any length
+ * for that. The chain key and message key are both derived from SHA256
+ * operations, so their length is determined by that. */
+const std::size_t OLM_SHARED_KEY_LENGTH = SHA256_OUTPUT_LENGTH;
+typedef std::uint8_t SharedKey[OLM_SHARED_KEY_LENGTH];
struct ChainKey {
std::uint32_t index;
diff --git a/src/account.cpp b/src/account.cpp
index ec763f8..9512068 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -49,7 +49,7 @@ std::size_t olm::Account::remove_key(
}
std::size_t olm::Account::new_account_random_length() {
- return 2 * olm::KEY_LENGTH;
+ return ED25519_RANDOM_LENGTH + CURVE25519_RANDOM_LENGTH;
}
std::size_t olm::Account::new_account(
@@ -61,7 +61,7 @@ std::size_t olm::Account::new_account(
}
olm::ed25519_generate_key(random, identity_keys.ed25519_key);
- random += KEY_LENGTH;
+ random += ED25519_RANDOM_LENGTH;
olm::curve25519_generate_key(random, identity_keys.curve25519_key);
return 0;
@@ -137,7 +137,7 @@ std::size_t olm::Account::get_identity_json(
std::size_t olm::Account::signature_length(
) {
- return olm::SIGNATURE_LENGTH;
+ return ED25519_SIGNATURE_LENGTH;
}
@@ -238,7 +238,7 @@ std::size_t olm::Account::max_number_of_one_time_keys(
std::size_t olm::Account::generate_one_time_keys_random_length(
std::size_t number_of_keys
) {
- return olm::KEY_LENGTH * number_of_keys;
+ return CURVE25519_RANDOM_LENGTH * number_of_keys;
}
std::size_t olm::Account::generate_one_time_keys(
@@ -254,7 +254,7 @@ std::size_t olm::Account::generate_one_time_keys(
key.id = ++next_one_time_key_id;
key.published = false;
olm::curve25519_generate_key(random, key.key);
- random += olm::KEY_LENGTH;
+ random += CURVE25519_RANDOM_LENGTH;
}
return number_of_keys;
}
diff --git a/src/cipher.cpp b/src/cipher.cpp
index 8c3de92..8e3d7a5 100644
--- a/src/cipher.cpp
+++ b/src/cipher.cpp
@@ -17,11 +17,13 @@
#include "olm/memory.hh"
#include <cstring>
+const std::size_t HMAC_KEY_LENGTH = 32;
+
namespace {
struct DerivedKeys {
olm::Aes256Key aes_key;
- std::uint8_t mac_key[olm::KEY_LENGTH];
+ std::uint8_t mac_key[HMAC_KEY_LENGTH];
olm::Aes256Iv aes_iv;
};
@@ -31,7 +33,9 @@ static void derive_keys(
std::uint8_t const * key, std::size_t key_length,
DerivedKeys & keys
) {
- std::uint8_t derived_secrets[2 * olm::KEY_LENGTH + olm::IV_LENGTH];
+ std::uint8_t derived_secrets[
+ AES256_KEY_LENGTH + HMAC_KEY_LENGTH + AES256_IV_LENGTH
+ ];
_olm_crypto_hkdf_sha256(
key, key_length,
nullptr, 0,
@@ -81,7 +85,7 @@ size_t aes_sha_256_cipher_encrypt(
);
_olm_crypto_hmac_sha256(
- keys.mac_key, olm::KEY_LENGTH, output, output_length - MAC_LENGTH, mac
+ keys.mac_key, HMAC_KEY_LENGTH, output, output_length - MAC_LENGTH, mac
);
std::memcpy(output + output_length - MAC_LENGTH, mac, MAC_LENGTH);
@@ -113,7 +117,7 @@ size_t aes_sha_256_cipher_decrypt(
derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
_olm_crypto_hmac_sha256(
- keys.mac_key, olm::KEY_LENGTH, input, input_length - MAC_LENGTH, mac
+ keys.mac_key, HMAC_KEY_LENGTH, input, input_length - MAC_LENGTH, mac
);
std::uint8_t const * input_mac = input + input_length - MAC_LENGTH;
diff --git a/src/crypto.cpp b/src/crypto.cpp
index 83493be..0b08c54 100644
--- a/src/crypto.cpp
+++ b/src/crypto.cpp
@@ -31,7 +31,7 @@ namespace {
static const std::uint8_t CURVE25519_BASEPOINT[32] = {9};
static const std::size_t AES_KEY_SCHEDULE_LENGTH = 60;
-static const std::size_t AES_KEY_BITS = 8 * olm::KEY_LENGTH;
+static const std::size_t AES_KEY_BITS = 8 * AES256_KEY_LENGTH;
static const std::size_t AES_BLOCK_LENGTH = 16;
static const std::size_t SHA256_BLOCK_LENGTH = 64;
static const std::uint8_t HKDF_DEFAULT_SALT[32] = {};
@@ -104,7 +104,7 @@ void olm::curve25519_generate_key(
std::uint8_t const * random_32_bytes,
olm::Curve25519KeyPair & key_pair
) {
- std::memcpy(key_pair.private_key, random_32_bytes, KEY_LENGTH);
+ std::memcpy(key_pair.private_key, random_32_bytes, CURVE25519_KEY_LENGTH);
::curve25519_donna(
key_pair.public_key, key_pair.private_key, CURVE25519_BASEPOINT
);
diff --git a/src/olm.cpp b/src/olm.cpp
index 682a84c..10e00fa 100644
--- a/src/olm.cpp
+++ b/src/olm.cpp
@@ -436,8 +436,8 @@ size_t olm_create_outbound_session(
std::size_t id_key_length = their_identity_key_length;
std::size_t ot_key_length = their_one_time_key_length;
- if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH
- || olm::decode_base64_length(ot_key_length) != olm::KEY_LENGTH
+ if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH
+ || olm::decode_base64_length(ot_key_length) != CURVE25519_KEY_LENGTH
) {
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
@@ -483,7 +483,7 @@ size_t olm_create_inbound_session_from(
std::uint8_t const * id_key = from_c(their_identity_key);
std::size_t id_key_length = their_identity_key_length;
- if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
+ if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH) {
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
@@ -554,7 +554,7 @@ size_t olm_matches_inbound_session_from(
std::uint8_t const * id_key = from_c(their_identity_key);
std::size_t id_key_length = their_identity_key_length;
- if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
+ if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH) {
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
@@ -710,7 +710,7 @@ size_t olm_ed25519_verify(
void const * message, size_t message_length,
void * signature, size_t signature_length
) {
- if (olm::decode_base64_length(key_length) != olm::KEY_LENGTH) {
+ if (olm::decode_base64_length(key_length) != CURVE25519_KEY_LENGTH) {
from_c(utility)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
diff --git a/src/ratchet.cpp b/src/ratchet.cpp
index aab5fbb..57cb385 100644
--- a/src/ratchet.cpp
+++ b/src/ratchet.cpp
@@ -49,7 +49,7 @@ static void create_chain_key(
) {
olm::SharedKey secret;
olm::curve25519_shared_secret(our_key, their_key, secret);
- std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
+ std::uint8_t derived_secrets[2 * olm::OLM_SHARED_KEY_LENGTH];
_olm_crypto_hkdf_sha256(
secret, sizeof(secret),
root_key, sizeof(root_key),
@@ -191,7 +191,7 @@ void olm::Ratchet::initialise_as_bob(
std::uint8_t const * shared_secret, std::size_t shared_secret_length,
olm::Curve25519PublicKey const & their_ratchet_key
) {
- std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
+ std::uint8_t derived_secrets[2 * olm::OLM_SHARED_KEY_LENGTH];
_olm_crypto_hkdf_sha256(
shared_secret, shared_secret_length,
nullptr, 0,
@@ -212,7 +212,7 @@ void olm::Ratchet::initialise_as_alice(
std::uint8_t const * shared_secret, std::size_t shared_secret_length,
olm::Curve25519KeyPair const & our_ratchet_key
) {
- std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
+ std::uint8_t derived_secrets[2 * olm::OLM_SHARED_KEY_LENGTH];
_olm_crypto_hkdf_sha256(
shared_secret, shared_secret_length,
nullptr, 0,
@@ -234,7 +234,7 @@ namespace olm {
static std::size_t pickle_length(
const olm::SharedKey & value
) {
- return olm::KEY_LENGTH;
+ return olm::OLM_SHARED_KEY_LENGTH;
}
@@ -242,7 +242,7 @@ static std::uint8_t * pickle(
std::uint8_t * pos,
const olm::SharedKey & value
) {
- return olm::pickle_bytes(pos, value, olm::KEY_LENGTH);
+ return olm::pickle_bytes(pos, value, olm::OLM_SHARED_KEY_LENGTH);
}
@@ -250,7 +250,7 @@ static std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end,
olm::SharedKey & value
) {
- return olm::unpickle_bytes(pos, end, value, olm::KEY_LENGTH);
+ return olm::unpickle_bytes(pos, end, value, olm::OLM_SHARED_KEY_LENGTH);
}
@@ -359,7 +359,7 @@ std::size_t olm::pickle_length(
olm::Ratchet const & value
) {
std::size_t length = 0;
- length += olm::KEY_LENGTH;
+ length += olm::OLM_SHARED_KEY_LENGTH;
length += olm::pickle_length(value.sender_chain);
length += olm::pickle_length(value.receiver_chains);
length += olm::pickle_length(value.skipped_message_keys);
@@ -409,13 +409,13 @@ std::size_t olm::Ratchet::encrypt_output_length(
plaintext_length
);
return olm::encode_message_length(
- counter, olm::KEY_LENGTH, padded, ratchet_cipher->ops->mac_length(ratchet_cipher)
+ counter, CURVE25519_KEY_LENGTH, padded, ratchet_cipher->ops->mac_length(ratchet_cipher)
);
}
std::size_t olm::Ratchet::encrypt_random_length() {
- return sender_chain.empty() ? olm::KEY_LENGTH : 0;
+ return sender_chain.empty() ? CURVE25519_RANDOM_LENGTH : 0;
}
@@ -461,7 +461,8 @@ std::size_t olm::Ratchet::encrypt(
olm::MessageWriter writer;
olm::encode_message(
- writer, PROTOCOL_VERSION, counter, olm::KEY_LENGTH, ciphertext_length,
+ writer, PROTOCOL_VERSION, counter, CURVE25519_KEY_LENGTH,
+ ciphertext_length,
output
);
@@ -529,7 +530,7 @@ std::size_t olm::Ratchet::decrypt(
return std::size_t(-1);
}
- if (reader.ratchet_key_length != olm::KEY_LENGTH) {
+ if (reader.ratchet_key_length != CURVE25519_KEY_LENGTH) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
@@ -539,7 +540,7 @@ std::size_t olm::Ratchet::decrypt(
for (olm::ReceiverChain & receiver_chain : receiver_chains) {
if (0 == std::memcmp(
receiver_chain.ratchet_key.public_key, reader.ratchet_key,
- olm::KEY_LENGTH
+ CURVE25519_KEY_LENGTH
)) {
chain = &receiver_chain;
break;
@@ -559,7 +560,7 @@ std::size_t olm::Ratchet::decrypt(
if (reader.counter == skipped.message_key.index
&& 0 == std::memcmp(
skipped.ratchet_key.public_key, reader.ratchet_key,
- olm::KEY_LENGTH
+ CURVE25519_KEY_LENGTH
)
) {
/* Found the key for this message. Check the MAC. */
diff --git a/src/session.cpp b/src/session.cpp
index 6ca7f36..7bde5d1 100644
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -49,7 +49,7 @@ olm::Session::Session(
std::size_t olm::Session::new_outbound_session_random_length() {
- return olm::KEY_LENGTH * 2;
+ return CURVE25519_RANDOM_LENGTH * 2;
}
@@ -68,7 +68,7 @@ std::size_t olm::Session::new_outbound_session(
olm::curve25519_generate_key(random, base_key);
olm::Curve25519KeyPair ratchet_key;
- olm::curve25519_generate_key(random + olm::KEY_LENGTH, ratchet_key);
+ olm::curve25519_generate_key(random + CURVE25519_RANDOM_LENGTH, ratchet_key);
olm::Curve25519KeyPair const & alice_identity_key_pair = (
local_account.identity_keys.curve25519_key
@@ -79,13 +79,13 @@ std::size_t olm::Session::new_outbound_session(
alice_base_key = base_key;
bob_one_time_key = one_time_key;
- std::uint8_t secret[3 * olm::KEY_LENGTH];
+ // Calculate the shared secret S via triple DH
+ std::uint8_t secret[3 * CURVE25519_SHARED_SECRET_LENGTH];
std::uint8_t * pos = secret;
-
olm::curve25519_shared_secret(alice_identity_key_pair, one_time_key, pos);
- pos += olm::KEY_LENGTH;
+ pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(base_key, identity_key, pos);
- pos += olm::KEY_LENGTH;
+ pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(base_key, one_time_key, pos);
ratchet.initialise_as_alice(secret, sizeof(secret), ratchet_key);
@@ -105,13 +105,13 @@ static bool check_message_fields(
bool ok = true;
ok = ok && (have_their_identity_key || reader.identity_key);
if (reader.identity_key) {
- ok = ok && reader.identity_key_length == olm::KEY_LENGTH;
+ ok = ok && reader.identity_key_length == CURVE25519_KEY_LENGTH;
}
ok = ok && reader.message;
ok = ok && reader.base_key;
- ok = ok && reader.base_key_length == olm::KEY_LENGTH;
+ ok = ok && reader.base_key_length == CURVE25519_KEY_LENGTH;
ok = ok && reader.one_time_key;
- ok = ok && reader.one_time_key_length == olm::KEY_LENGTH;
+ ok = ok && reader.one_time_key_length == CURVE25519_KEY_LENGTH;
return ok;
}
@@ -133,7 +133,7 @@ std::size_t olm::Session::new_inbound_session(
if (reader.identity_key && their_identity_key) {
bool same = 0 == std::memcmp(
- their_identity_key->public_key, reader.identity_key, olm::KEY_LENGTH
+ their_identity_key->public_key, reader.identity_key, CURVE25519_KEY_LENGTH
);
if (!same) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID;
@@ -152,7 +152,7 @@ std::size_t olm::Session::new_inbound_session(
);
if (!message_reader.ratchet_key
- || message_reader.ratchet_key_length != olm::KEY_LENGTH) {
+ || message_reader.ratchet_key_length != CURVE25519_KEY_LENGTH) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
@@ -174,12 +174,13 @@ std::size_t olm::Session::new_inbound_session(
);
olm::Curve25519KeyPair const & bob_one_time_key = our_one_time_key->key;
- std::uint8_t secret[olm::KEY_LENGTH * 3];
+ // Calculate the shared secret S via triple DH
+ std::uint8_t secret[CURVE25519_SHARED_SECRET_LENGTH * 3];
std::uint8_t * pos = secret;
olm::curve25519_shared_secret(bob_one_time_key, alice_identity_key, pos);
- pos += olm::KEY_LENGTH;
+ pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(bob_identity_key, alice_base_key, pos);
- pos += olm::KEY_LENGTH;
+ pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(bob_one_time_key, alice_base_key, pos);
ratchet.initialise_as_bob(secret, sizeof(secret), ratchet_key);
@@ -202,7 +203,7 @@ std::size_t olm::Session::session_id(
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
- std::uint8_t tmp[olm::KEY_LENGTH * 3];
+ std::uint8_t tmp[CURVE25519_KEY_LENGTH * 3];
std::uint8_t * pos = tmp;
pos = olm::store_array(pos, alice_identity_key.public_key);
pos = olm::store_array(pos, alice_base_key.public_key);
@@ -226,20 +227,20 @@ bool olm::Session::matches_inbound_session(
bool same = true;
if (reader.identity_key) {
same = same && 0 == std::memcmp(
- reader.identity_key, alice_identity_key.public_key, olm::KEY_LENGTH
+ reader.identity_key, alice_identity_key.public_key, CURVE25519_KEY_LENGTH
);
}
if (their_identity_key) {
same = same && 0 == std::memcmp(
their_identity_key->public_key, alice_identity_key.public_key,
- olm::KEY_LENGTH
+ CURVE25519_KEY_LENGTH
);
}
same = same && 0 == std::memcmp(
- reader.base_key, alice_base_key.public_key, olm::KEY_LENGTH
+ reader.base_key, alice_base_key.public_key, CURVE25519_KEY_LENGTH
);
same = same && 0 == std::memcmp(
- reader.one_time_key, bob_one_time_key.public_key, olm::KEY_LENGTH
+ reader.one_time_key, bob_one_time_key.public_key, CURVE25519_KEY_LENGTH
);
return same;
}
@@ -266,9 +267,9 @@ std::size_t olm::Session::encrypt_message_length(
}
return encode_one_time_key_message_length(
- olm::KEY_LENGTH,
- olm::KEY_LENGTH,
- olm::KEY_LENGTH,
+ CURVE25519_KEY_LENGTH,
+ CURVE25519_KEY_LENGTH,
+ CURVE25519_KEY_LENGTH,
message_length
);
}
@@ -300,9 +301,9 @@ std::size_t olm::Session::encrypt(
encode_one_time_key_message(
writer,
PROTOCOL_VERSION,
- olm::KEY_LENGTH,
- olm::KEY_LENGTH,
- olm::KEY_LENGTH,
+ CURVE25519_KEY_LENGTH,
+ CURVE25519_KEY_LENGTH,
+ CURVE25519_KEY_LENGTH,
message_body_length,
message
);
diff --git a/src/utility.cpp b/src/utility.cpp
index 67029c9..e33351c 100644
--- a/src/utility.cpp
+++ b/src/utility.cpp
@@ -45,7 +45,7 @@ size_t olm::Utility::ed25519_verify(
std::uint8_t const * message, std::size_t message_length,
std::uint8_t const * signature, std::size_t signature_length
) {
- if (signature_length < olm::SIGNATURE_LENGTH) {
+ if (signature_length < ED25519_SIGNATURE_LENGTH) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
return std::size_t(-1);
}
diff --git a/tests/test_crypto.cpp b/tests/test_crypto.cpp
index 175f66f..56abdcd 100644
--- a/tests/test_crypto.cpp
+++ b/tests/test_crypto.cpp
@@ -70,7 +70,7 @@ olm::curve25519_generate_key(bob_private, bob_pair);
assert_equals(bob_private, bob_pair.private_key, 32);
assert_equals(bob_public, bob_pair.public_key, 32);
-std::uint8_t actual_agreement[olm::KEY_LENGTH] = {};
+std::uint8_t actual_agreement[CURVE25519_SHARED_SECRET_LENGTH] = {};
olm::curve25519_shared_secret(alice_pair, bob_pair, actual_agreement);