diff --git a/cpp/src/lib.rs b/cpp/src/lib.rs
index 81fd57c..4d4dd7a 100644
--- a/cpp/src/lib.rs
+++ b/cpp/src/lib.rs
@@ -1,189 +1,189 @@
 mod account;
 mod group_sessions;
 mod sas;
 mod session;
 mod types;
 
 use account::{account_from_pickle, account_from_libolm_pickle, new_account, olm_message_from_parts, Account, OlmMessage};
 use group_sessions::{
     exported_session_key_from_base64, group_session_from_pickle, group_session_from_libolm_pickle, import_inbound_group_session,
     inbound_group_session_from_pickle, inbound_group_session_from_libolm_pickle, megolm_message_from_base64, new_group_session,
     new_inbound_group_session, session_key_from_base64, ExportedSessionKey, GroupSession,
     InboundGroupSession, MegolmMessage, SessionKey,
 };
 use sas::{mac_from_base64, new_sas, EstablishedSas, Mac, Sas, SasBytes};
 use session::{session_from_pickle, session_from_libolm_pickle, Session};
 use types::{
     curve_key_from_base64, ed25519_key_from_base64, ed25519_signature_from_base64, Curve25519PublicKey, Ed25519PublicKey,
     Ed25519Signature,
 };
 
 #[cxx::bridge]
 mod ffi {
-    #[namespace = "olm"]
+    #[namespace = "vodozemac::olm"]
     struct OlmMessageParts {
         message_type: usize,
         ciphertext: String,
     }
 
-    #[namespace = "olm"]
+    #[namespace = "vodozemac::olm"]
     pub struct InboundCreationResult {
         pub session: Box<Session>,
         pub plaintext: Vec<u8>,
     }
 
-    #[namespace = "olm"]
+    #[namespace = "vodozemac::olm"]
     struct OneTimeKey {
         key_id: String,
         key: Box<Curve25519PublicKey>,
     }
 
-    #[namespace = "olm"]
+    #[namespace = "vodozemac::olm"]
     #[derive(PartialEq, Eq)]
     struct SessionKeys {
         identity_key: Box<Curve25519PublicKey>,
         base_key: Box<Curve25519PublicKey>,
         one_time_key: Box<Curve25519PublicKey>,
     }
 
-    #[namespace = "types"]
+    #[namespace = "vodozemac::types"]
     extern "Rust" {
         type Curve25519PublicKey;
         fn curve_key_from_base64(key: &str) -> Result<Box<Curve25519PublicKey>>;
         fn to_base64(self: &Curve25519PublicKey) -> String;
         type Ed25519PublicKey;
         fn ed25519_key_from_base64(key: &str) -> Result<Box<Ed25519PublicKey>>;
         fn to_base64(self: &Ed25519PublicKey) -> String;
         fn verify(self: &Ed25519PublicKey, message: &str, signature: &Ed25519Signature) -> Result<()>;
         type Ed25519Signature;
         fn ed25519_signature_from_base64(key: &str) -> Result<Box<Ed25519Signature>>;
         fn to_base64(self: &Ed25519Signature) -> String;
     }
 
-    #[namespace = "olm"]
+    #[namespace = "vodozemac::olm"]
     extern "Rust" {
         type Account;
         fn new_account() -> Box<Account>;
         fn ed25519_key(self: &Account) -> Box<Ed25519PublicKey>;
         fn curve25519_key(self: &Account) -> Box<Curve25519PublicKey>;
         fn sign(self: &Account, message: &str) -> Box<Ed25519Signature>;
         fn generate_one_time_keys(self: &mut Account, count: usize);
         fn one_time_keys(self: &Account) -> Vec<OneTimeKey>;
         fn generate_fallback_key(self: &mut Account);
         fn fallback_key(self: &Account) -> Vec<OneTimeKey>;
         fn mark_keys_as_published(self: &mut Account);
         fn max_number_of_one_time_keys(self: &Account) -> usize;
         fn account_from_pickle(pickle: &str, pickle_key: &[u8; 32]) -> Result<Box<Account>>;
         fn account_from_libolm_pickle(pickle: &str, pickle_key: &[u8]) -> Result<Box<Account>>;
         fn pickle(self: &Account, pickle_key: &[u8; 32]) -> String;
         fn create_outbound_session(
             self: &Account,
             identity_key: &Curve25519PublicKey,
             one_time_key: &Curve25519PublicKey,
         ) -> Result<Box<Session>>;
         fn create_inbound_session(
             self: &mut Account,
             identity_key: &Curve25519PublicKey,
             message: &OlmMessage,
         ) -> Result<InboundCreationResult>;
 
         type Session;
         fn session_id(self: &Session) -> String;
         fn session_keys(self: &Session) -> SessionKeys;
         fn session_matches(self: &Session, message: &OlmMessage) -> bool;
         fn encrypt(self: &mut Session, plaintext: &str) -> Box<OlmMessage>;
         fn decrypt(self: &mut Session, message: &OlmMessage) -> Result<Vec<u8>>;
         fn session_from_pickle(pickle: &str, pickle_key: &[u8; 32]) -> Result<Box<Session>>;
         fn session_from_libolm_pickle(pickle: &str, pickle_key: &[u8]) -> Result<Box<Session>>;
         fn pickle(self: &Session, pickle_key: &[u8; 32]) -> String;
 
         type OlmMessage;
         fn to_parts(self: &OlmMessage) -> OlmMessageParts;
         fn olm_message_from_parts(parts: &OlmMessageParts) -> Result<Box<OlmMessage>>;
     }
 
-    #[namespace = "megolm"]
+    #[namespace = "vodozemac::megolm"]
     struct DecryptedMessage {
         plaintext: Vec<u8>,
         message_index: u32,
     }
 
-    #[namespace = "megolm"]
+    #[namespace = "vodozemac::megolm"]
     extern "Rust" {
         type MegolmMessage;
         fn megolm_message_from_base64(message: &str) -> Result<Box<MegolmMessage>>;
         fn to_base64(self: &MegolmMessage) -> String;
 
         type SessionKey;
         fn session_key_from_base64(key: &str) -> Result<Box<SessionKey>>;
         fn to_base64(self: &SessionKey) -> String;
 
         type ExportedSessionKey;
         fn exported_session_key_from_base64(key: &str) -> Result<Box<ExportedSessionKey>>;
         fn to_base64(self: &ExportedSessionKey) -> String;
 
         type GroupSession;
         fn new_group_session() -> Box<GroupSession>;
         fn encrypt(self: &mut GroupSession, plaintext: &str) -> Box<MegolmMessage>;
         fn session_id(self: &GroupSession) -> String;
         fn session_key(self: &GroupSession) -> Box<SessionKey>;
         fn message_index(self: &GroupSession) -> u32;
         fn pickle(self: &GroupSession, pickle_key: &[u8; 32]) -> String;
         fn group_session_from_pickle(
             pickle: &str,
             pickle_key: &[u8; 32],
         ) -> Result<Box<GroupSession>>;
         fn group_session_from_libolm_pickle(
             pickle: &str,
             pickle_key: &[u8],
         ) -> Result<Box<GroupSession>>;
 
         type InboundGroupSession;
         fn new_inbound_group_session(session_key: &SessionKey) -> Box<InboundGroupSession>;
         fn import_inbound_group_session(
             session_key: &ExportedSessionKey,
         ) -> Box<InboundGroupSession>;
         fn decrypt(
             self: &mut InboundGroupSession,
             message: &MegolmMessage,
         ) -> Result<DecryptedMessage>;
         fn session_id(self: &InboundGroupSession) -> String;
         fn first_known_index(self: &InboundGroupSession) -> u32;
         fn export_at(
             self: &mut InboundGroupSession,
             message_index: u32,
         ) -> Result<Box<ExportedSessionKey>>;
         fn pickle(self: &InboundGroupSession, pickle_key: &[u8; 32]) -> String;
         fn inbound_group_session_from_pickle(
             pickle: &str,
             pickle_key: &[u8; 32],
         ) -> Result<Box<InboundGroupSession>>;
         fn inbound_group_session_from_libolm_pickle(
             pickle: &str,
             pickle_key: &[u8],
         ) -> Result<Box<InboundGroupSession>>;
     }
 
-    #[namespace = "sas"]
+    #[namespace = "vodozemac::sas"]
     extern "Rust" {
         type Mac;
         fn mac_from_base64(mac: &str) -> Result<Box<Mac>>;
         fn to_base64(self: &Mac) -> String;
         type Sas;
         fn new_sas() -> Box<Sas>;
         fn public_key(self: &Sas) -> Box<Curve25519PublicKey>;
         fn diffie_hellman(
             self: &mut Sas,
             other_public_key: &Curve25519PublicKey,
         ) -> Result<Box<EstablishedSas>>;
 
         type EstablishedSas;
         fn bytes(self: &EstablishedSas, info: &str) -> Box<SasBytes>;
         fn calculate_mac(self: &EstablishedSas, input: &str, info: &str) -> Box<Mac>;
         fn verify_mac(self: &EstablishedSas, input: &str, info: &str, mac: &Mac) -> Result<()>;
 
         type SasBytes;
         fn emoji_indices(self: &SasBytes) -> [u8; 7];
         fn decimals(self: &SasBytes) -> [u16; 3];
     }
 }
diff --git a/cpp/tests/account.cpp b/cpp/tests/account.cpp
index 6c517db..89b94c3 100644
--- a/cpp/tests/account.cpp
+++ b/cpp/tests/account.cpp
@@ -1,123 +1,124 @@
 #include "../../target/cxxbridge/vodozemac/src/lib.rs.h"
 #include <string>
 #include <unordered_set>
 #include <olm/olm.h>
 #include <boost/json.hpp>
 #include "gtest/gtest.h"
 #include "util.hpp"
 
 using namespace rust;
+using namespace vodozemac;
 
 TEST(AccountTest, AccountCreation) {
   auto alice = olm::new_account();
   auto key = alice->ed25519_key();
   auto encoded_key = key->to_base64();
 
   EXPECT_NE(encoded_key.length(), 0);
 }
 
 TEST(AccountTest, OneTimeKeyGeneration) {
   auto alice = olm::new_account();
 
   EXPECT_EQ(alice->one_time_keys().size(), 0);
 
   alice->generate_one_time_keys(10);
   EXPECT_EQ(alice->one_time_keys().size(), 10);
 
   alice->mark_keys_as_published();
   EXPECT_EQ(alice->one_time_keys().size(), 0);
 }
 
 TEST(AccountTest, FallbackKeyGeneration) {
   auto alice = olm::new_account();
   EXPECT_EQ(alice->fallback_key().size(), 0);
 
   alice->generate_fallback_key();
   EXPECT_EQ(alice->fallback_key().size(), 1);
 
   alice->mark_keys_as_published();
   EXPECT_EQ(alice->one_time_keys().size(), 0);
 }
 
 TEST(AccountTest, MaxKeysTest) {
   auto alice = olm::new_account();
   auto max_keys = alice->max_number_of_one_time_keys();
 
   EXPECT_GT(max_keys, 0);
   EXPECT_LT(max_keys, 1000);
 }
 
 TEST(AccountTest, PickleTest) {
   auto alice = olm::new_account();
 
   auto pickle = alice->pickle(PICKLE_KEY);
 
   auto unpickled = olm::account_from_pickle(pickle, PICKLE_KEY);
 
   EXPECT_EQ(alice->curve25519_key()->to_base64(),
             unpickled->curve25519_key()->to_base64());
 }
 
 TEST(AccountTest, PickleFromLibolmTest) {
   auto [data, alice] = new_olm_account();
   auto random = gen_random(olm_account_generate_one_time_keys_random_length(alice, 10));
   check_olm_error(olm_account_generate_one_time_keys(alice, 10, random.data(), random.size()));
 
   auto pickle = std::string(olm_pickle_account_length(alice), '\0');
   check_olm_error(olm_pickle_account(alice, OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size(), pickle.data(), pickle.size()));
 
   auto unpickled = olm::account_from_libolm_pickle(pickle, Slice<const unsigned char>(OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size()));
 
   {
     auto identity_keys = std::string(olm_account_identity_keys_length(alice), '\0');
     check_olm_error(olm_account_identity_keys(alice, identity_keys.data(), identity_keys.size()));
     auto parsed_keys = boost::json::parse(identity_keys).as_object();
     auto curve25519_key = String(as_std_string(parsed_keys.at("curve25519").as_string()));
     auto ed25519_key = String(as_std_string(parsed_keys.at("ed25519").as_string()));
 
     EXPECT_EQ(curve25519_key,
       unpickled->curve25519_key()->to_base64());
     EXPECT_EQ(ed25519_key,
       unpickled->ed25519_key()->to_base64());
   }
 
   {
     auto one_time_keys = std::string(olm_account_one_time_keys_length(alice), '\0');
     check_olm_error(olm_account_one_time_keys(alice, one_time_keys.data(), one_time_keys.size()));
     auto parsed_keys = boost::json::parse(one_time_keys).as_object().at("curve25519").as_object();
     // The key id will change from libolm to vodozemac, but the key themselves won't.
     auto one_time_keys_set = std::unordered_set<std::string>();
     for (const auto &pair : parsed_keys) {
       one_time_keys_set.insert(as_std_string(pair.value().as_string()));
     }
 
     auto unpickled_one_time_keys = unpickled->one_time_keys();
     auto unpickled_one_time_keys_set = std::unordered_set<std::string>();
     for (const auto &k : unpickled_one_time_keys) {
       unpickled_one_time_keys_set.insert(static_cast<std::string>(k.key->to_base64()));
     }
 
     EXPECT_EQ(one_time_keys_set, unpickled_one_time_keys_set);
   }
 }
 
 TEST(AccountTest, SignAndVerify) {
   auto alice = olm::new_account();
   auto key = alice->ed25519_key();
   std::string str = "{}";
   auto signature = alice->sign(Str(str));
   EXPECT_NO_THROW(key->verify(Str(str), *signature));
   {
     auto cloned_signature = types::ed25519_signature_from_base64(signature->to_base64());
     EXPECT_NO_THROW(key->verify(Str(str), *cloned_signature));
   }
   {
     auto cloned_key = types::ed25519_key_from_base64(key->to_base64());
     EXPECT_NO_THROW(cloned_key->verify(Str(str), *signature));
   }
 
   std::string str2 = "{\"foo\": \"bar\"}";
   auto signature2 = alice->sign(Str(str2));
   EXPECT_ANY_THROW(key->verify(Str(str2), *signature));
   EXPECT_ANY_THROW(key->verify(Str(str), *signature2));
 }
diff --git a/cpp/tests/group_session.cpp b/cpp/tests/group_session.cpp
index f06c198..8acb49d 100644
--- a/cpp/tests/group_session.cpp
+++ b/cpp/tests/group_session.cpp
@@ -1,184 +1,185 @@
 #include "../../target/cxxbridge/vodozemac/src/lib.rs.h"
 #include <olm/outbound_group_session.h>
 #include <olm/inbound_group_session.h>
 #include "gtest/gtest.h"
 #include "util.hpp"
 
 using namespace rust;
+using namespace vodozemac;
 
 struct SessionCreationResult {
   Box<megolm::GroupSession> outbound;
   Box<megolm::InboundGroupSession> inbound;
 };
 
 SessionCreationResult create_session() {
   auto outbound = megolm::new_group_session();
   auto session_key = outbound->session_key();
   auto inbound = megolm::new_inbound_group_session(*session_key);
 
   auto ret = SessionCreationResult{
       std::move(outbound),
       std::move(inbound),
   };
 
   return ret;
 }
 
 struct LibolmSessionCreationResult {
   std::vector<uint8_t> outbound_data;
   OlmOutboundGroupSession *outbound;
   std::vector<uint8_t> inbound_data;
   OlmInboundGroupSession *inbound;
 };
 
 LibolmSessionCreationResult create_libolm_session() {
   LibolmSessionCreationResult res{
     std::vector<uint8_t>(olm_outbound_group_session_size()),
     0,
     std::vector<uint8_t>(olm_inbound_group_session_size()),
     0,
   };
 
   res.outbound = olm_outbound_group_session(res.outbound_data.data());
   auto random = gen_random(olm_init_outbound_group_session_random_length(res.outbound));
   check_olm_error(olm_init_outbound_group_session(res.outbound, random.data(), random.size()));
   auto session_key = std::vector<uint8_t>(olm_outbound_group_session_key_length(res.outbound));
   check_olm_error(olm_outbound_group_session_key(res.outbound, session_key.data(), session_key.size()));
 
   res.inbound = olm_inbound_group_session(res.inbound_data.data());
   olm_init_inbound_group_session(res.inbound, session_key.data(), session_key.size());
   return res;
 }
 
 TEST(GroupSessionTest, Creation) {
   auto [outbound, inbound] = create_session();
 
   auto outbound_id = outbound->session_id();
   auto inbound_id = inbound->session_id();
 
   EXPECT_NE(outbound_id.length(), 0);
   EXPECT_STREQ(outbound_id.c_str(), inbound_id.c_str());
 }
 
 TEST(GroupSessionTest, MessageIndex) {
   auto [outbound, inbound] = create_session();
 
   EXPECT_EQ(outbound->message_index(), 0);
   EXPECT_EQ(inbound->first_known_index(), 0);
 
   outbound->encrypt("Hello");
   auto inbound2 = megolm::new_inbound_group_session(*outbound->session_key());
 
   EXPECT_EQ(outbound->message_index(), 1);
   EXPECT_EQ(inbound2->first_known_index(), 1);
 }
 
 TEST(GroupSessionTest, Pickle) {
   auto session = megolm::new_group_session();
 
   auto pickle = session->pickle(PICKLE_KEY);
   auto unpickled = megolm::group_session_from_pickle(pickle, PICKLE_KEY);
 
   ASSERT_STREQ(session->session_id().c_str(), unpickled->session_id().c_str());
   EXPECT_EQ(session->message_index(), unpickled->message_index());
 }
 
 TEST(GroupSessionTest, PickleLibolm) {
   auto [_1, outbound, _2, inbound] = create_libolm_session();
 
   auto pickle = std::string(olm_pickle_outbound_group_session_length(outbound), '\0');
   check_olm_error(olm_pickle_outbound_group_session(outbound, OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size(), pickle.data(), pickle.size()));
   auto unpickled = megolm::group_session_from_libolm_pickle(String(pickle), Slice<const unsigned char>(OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size()));
 
   auto session_id = std::vector<uint8_t>(olm_outbound_group_session_id_length(outbound));
   check_olm_error(olm_outbound_group_session_id(outbound, session_id.data(), session_id.size()));
 
   ASSERT_EQ(as_std_string(session_id), static_cast<std::string>(unpickled->session_id()));
 
   auto message_index = olm_outbound_group_session_message_index(outbound);
 
   EXPECT_EQ(message_index, unpickled->message_index());
 }
 
 TEST(GroupSessionTest, PickleInbound) {
   auto [outbound, inbound] = create_session();
 
   auto pickle = inbound->pickle(PICKLE_KEY);
   auto unpickled =
       megolm::inbound_group_session_from_pickle(pickle, PICKLE_KEY);
 
   ASSERT_STREQ(inbound->session_id().c_str(), unpickled->session_id().c_str());
   EXPECT_EQ(inbound->first_known_index(), unpickled->first_known_index());
 }
 
 TEST(GroupSessionTest, PickleInboundLibolm) {
   auto [_1, outbound, _2, inbound] = create_libolm_session();
 
   auto pickle = std::string(olm_pickle_inbound_group_session_length(inbound), '\0');
   check_olm_error(olm_pickle_inbound_group_session(inbound, OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size(), pickle.data(), pickle.size()));
 
   auto unpickled =
       megolm::inbound_group_session_from_libolm_pickle(pickle, Slice<const unsigned char>(OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size()));
 
   auto session_id = std::vector<uint8_t>(olm_inbound_group_session_id_length(inbound));
   check_olm_error(olm_inbound_group_session_id(inbound, session_id.data(), session_id.size()));
 
   ASSERT_EQ(as_std_string(session_id), static_cast<std::string>(unpickled->session_id()));
 
   auto first_known_index = olm_inbound_group_session_first_known_index(inbound);
 
   EXPECT_EQ(first_known_index, unpickled->first_known_index());
 }
 
 TEST(GroupSessionTest, UnpicklingFail) {
   EXPECT_ANY_THROW(megolm::group_session_from_pickle("", PICKLE_KEY));
   EXPECT_ANY_THROW(megolm::inbound_group_session_from_pickle("", PICKLE_KEY));
 }
 
 TEST(GroupSessionTest, DecryptionFail) {
   auto [outbound, inbound] = create_session();
 
   auto outbound2 = megolm::new_group_session();
   auto message = outbound2->encrypt("Hello");
 
   EXPECT_ANY_THROW(inbound->decrypt(*message));
 }
 
 TEST(GroupSessionTest, Encryption) {
   auto [outbound, inbound] = create_session();
 
   auto plaintext = "It's a secret to everybody";
   auto message = outbound->encrypt(plaintext);
   auto decrypted = inbound->decrypt(*message);
 
   EXPECT_EQ(as_std_string(decrypted.plaintext), std::string(plaintext));
   EXPECT_EQ(decrypted.message_index, 0);
 
   plaintext = "Another secret";
   message = outbound->encrypt(plaintext);
   decrypted = inbound->decrypt(*message);
 
   EXPECT_EQ(as_std_string(decrypted.plaintext), std::string(plaintext));
   EXPECT_EQ(decrypted.message_index, 1);
 }
 
 TEST(GroupSessionTest, SessionExport) {
   auto [outbound, inbound] = create_session();
   auto imported = megolm::import_inbound_group_session(*inbound->export_at(0));
 
   EXPECT_STREQ(outbound->session_id().c_str(), imported->session_id().c_str());
 
   auto plaintext = "It's a secret to everybody";
   auto message = outbound->encrypt(plaintext);
   auto decrypted = imported->decrypt(*message);
 
   EXPECT_EQ(as_std_string(decrypted.plaintext), std::string(plaintext));
   EXPECT_EQ(decrypted.message_index, 0);
 
   plaintext = "Another secret";
   message = outbound->encrypt(plaintext);
   decrypted = imported->decrypt(*message);
 
   EXPECT_EQ(as_std_string(decrypted.plaintext), std::string(plaintext));
   EXPECT_EQ(decrypted.message_index, 1);
 }
diff --git a/cpp/tests/sas.cpp b/cpp/tests/sas.cpp
index 7e1de46..f5364ec 100644
--- a/cpp/tests/sas.cpp
+++ b/cpp/tests/sas.cpp
@@ -1,62 +1,63 @@
 #include "../../target/cxxbridge/vodozemac/src/lib.rs.h"
 #include "gtest/gtest.h"
 
 using namespace rust;
+using namespace vodozemac;
 
 TEST(SasTest, Creation) {
   auto alice = sas::new_sas();
   auto bob = sas::new_sas();
 
   auto alice_key = alice->public_key()->to_base64();
   auto bob_key = bob->public_key()->to_base64();
 
   EXPECT_STRNE(alice_key.c_str(), bob_key.c_str());
 }
 
 TEST(SasTest, SharedSecret) {
   auto alice = sas::new_sas();
   auto bob = sas::new_sas();
 
   auto alice_key = alice->public_key();
   auto bob_key = bob->public_key();
 
   auto alice_established = alice->diffie_hellman(*bob_key);
   auto bob_established = bob->diffie_hellman(*alice_key);
 }
 
 TEST(SasTest, ShortAuthString) {
   auto alice = sas::new_sas();
   auto bob = sas::new_sas();
 
   auto alice_key = alice->public_key();
   auto bob_key = bob->public_key();
 
   auto alice_established = alice->diffie_hellman(*bob_key);
   auto bob_established = bob->diffie_hellman(*alice_key);
 
   auto alice_bytes = alice_established->bytes("");
   auto bob_bytes = bob_established->bytes("");
 
   ASSERT_EQ(alice_bytes->emoji_indices(), bob_bytes->emoji_indices());
   ASSERT_EQ(alice_bytes->decimals(), bob_bytes->decimals());
 }
 
 TEST(SasTest, CalculateMac) {
   auto alice = sas::new_sas();
   auto bob = sas::new_sas();
 
   auto alice_key = alice->public_key();
   auto bob_key = bob->public_key();
 
   auto alice_established = alice->diffie_hellman(*bob_key);
   auto bob_established = bob->diffie_hellman(*alice_key);
 
   auto alice_mac = alice_established->calculate_mac("Hello", "world");
   auto bob_mac = bob_established->calculate_mac("Hello", "world");
 
   ASSERT_STREQ(alice_mac->to_base64().c_str(), bob_mac->to_base64().c_str());
 
   EXPECT_NO_THROW(alice_established->verify_mac("Hello", "world", *bob_mac));
   EXPECT_NO_THROW(bob_established->verify_mac("Hello", "world", *alice_mac));
   EXPECT_ANY_THROW(bob_established->verify_mac("", "", *alice_mac));
 }
diff --git a/cpp/tests/session.cpp b/cpp/tests/session.cpp
index b991e39..04745ba 100644
--- a/cpp/tests/session.cpp
+++ b/cpp/tests/session.cpp
@@ -1,192 +1,193 @@
 #include "../../target/cxxbridge/vodozemac/src/lib.rs.h"
 #include "gtest/gtest.h"
 #include <boost/json.hpp>
 #include "util.hpp"
 
 using namespace rust;
+using namespace vodozemac;
 
 struct SessionCreationResult {
   Box<olm::Account> alice;
   Box<olm::Account> bob;
   Box<olm::Session> session;
 };
 
 SessionCreationResult create_session() {
   Box<olm::Account> alice = olm::new_account();
   auto bob = olm::new_account();
 
   bob->generate_one_time_keys(1);
 
   auto one_time_keys = bob->one_time_keys();
   auto [key_id, one_time_key] = std::move(one_time_keys.front());
 
   auto identity_key = bob->curve25519_key();
 
   auto session = alice->create_outbound_session(*identity_key, *one_time_key);
 
   auto ret = SessionCreationResult{
       std::move(alice),
       std::move(bob),
       std::move(session),
   };
 
   return ret;
 }
 
 TEST(SessionTest, Creation) {
   auto [alice, bob, session] = create_session();
 
   auto session_id = session->session_id();
 
   EXPECT_NE(session_id.length(), 0);
 }
 
 TEST(SessionTest, IdUniqueness) {
   auto [alice1, bob1, session] = create_session();
   auto [alice2, bob2, session2] = create_session();
 
   auto session_id = session->session_id();
   auto session2_id = session2->session_id();
 
   EXPECT_STRNE(session_id.c_str(), session2_id.c_str());
 }
 
 TEST(SessionTest, Pickle) {
   auto [alice, bob, session] = create_session();
 
   auto pickle = session->pickle(PICKLE_KEY);
   auto unpickled = olm::session_from_pickle(pickle, PICKLE_KEY);
 
   auto session_id = session->session_id();
   auto session2_id = unpickled->session_id();
 
   EXPECT_STREQ(session_id.c_str(), session2_id.c_str());
 }
 
 TEST(SessionTest, PickleFromLibolm) {
   auto [_1, alice] = new_olm_account();
   auto [_2, bob] = new_olm_account();
 
   auto random = gen_random(olm_account_generate_one_time_keys_random_length(bob, 1));
   check_olm_error(olm_account_generate_one_time_keys(bob, 1, random.data(), random.size()));
 
   auto one_time_keys = std::string(olm_account_one_time_keys_length(bob), '\0');
   check_olm_error(olm_account_one_time_keys(bob, one_time_keys.data(), one_time_keys.size()));
   auto parsed_keys = boost::json::parse(one_time_keys).as_object().at("curve25519").as_object();
   auto key_id = as_std_string(parsed_keys.begin()->key());
   auto one_time_key = as_std_string(parsed_keys.begin()->value().as_string());
 
   auto identity_keys = std::string(olm_account_identity_keys_length(alice), '\0');
   check_olm_error(olm_account_identity_keys(alice, identity_keys.data(), identity_keys.size()));
   parsed_keys = boost::json::parse(identity_keys).as_object();
   auto identity_key = String(as_std_string(parsed_keys.at("curve25519").as_string()));
 
   auto data = std::vector<uint8_t>(olm_session_size());
   auto session = olm_session(data.data());
   random = gen_random(olm_create_outbound_session_random_length(session));
   check_olm_error(olm_create_outbound_session(session, alice, identity_key.data(), identity_key.size(), one_time_key.data(), one_time_key.size(), random.data(), random.size()));
 
   auto pickle = std::string(olm_pickle_session_length(session), '\0');
   check_olm_error(olm_pickle_session(session, OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size(), pickle.data(), pickle.size()));
 
   auto unpickled = olm::session_from_libolm_pickle(pickle, Slice<const unsigned char>(OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size()));
 
   auto session_id = std::string(olm_session_id_length(session), '\0');
   check_olm_error(olm_session_id(session, session_id.data(), session_id.size()));
   auto session2_id = unpickled->session_id();
 
   EXPECT_STREQ(session_id.c_str(), session2_id.c_str());
 }
 
 TEST(SessionTest, InvalidPickle) {
   EXPECT_ANY_THROW(olm::session_from_pickle("", PICKLE_KEY));
 }
 
 TEST(SessionTest, Encryption) {
   auto [alice, bob, session] = create_session();
 
   auto alice_key = alice->curve25519_key();
   auto plaintext = "It's a secret to everybody";
 
   auto message = session->encrypt(plaintext);
 
   auto [bob_session, decrypted] =
       bob->create_inbound_session(*alice_key, *message);
 
   EXPECT_STREQ(session->session_id().c_str(),
                bob_session->session_id().c_str());
 
   EXPECT_EQ(std::string(plaintext), as_std_string(decrypted));
 }
 
 TEST(SessionTest, InvalidDecryption) {
   auto parts = olm::OlmMessageParts{
       0,
       "",
   };
 
   EXPECT_ANY_THROW(olm::olm_message_from_parts(parts));
 }
 
 TEST(SessionTest, MultipleMessageDecryption) {
   auto [alice, bob, session] = create_session();
 
   auto alice_key = alice->curve25519_key();
   auto plaintext = "It's a secret to everybody";
 
   auto message = session->encrypt(plaintext);
 
   auto [bob_session, decrypted] =
       bob->create_inbound_session(*alice_key, *message);
 
   EXPECT_STREQ(session->session_id().c_str(),
                bob_session->session_id().c_str());
 
   EXPECT_EQ(std::string(plaintext), as_std_string(decrypted));
 
   plaintext = "Grumble grumble";
 
   message = bob_session->encrypt(plaintext);
   decrypted = session->decrypt(*message);
 
   EXPECT_EQ(std::string(plaintext), as_std_string(decrypted));
 }
 
 TEST(SessionTest, PreKeyMatches) {
   auto [alice, bob, session] = create_session();
 
   auto alice_key = alice->curve25519_key();
   auto plaintext = "It's a secret to everybody";
 
   auto message = session->encrypt(plaintext);
 
   auto [bob_session, decrypted] =
       bob->create_inbound_session(*alice_key, *message);
 
   plaintext = "Grumble grumble";
   message = session->encrypt(plaintext);
 
   EXPECT_TRUE(bob_session->session_matches(*message));
 }
 
 TEST(SessionTest, PreKeyDoesNotMatch) {
   auto [alice, bob, session] = create_session();
   auto [alice2, bob2, session2] = create_session();
 
   auto alice_key = alice->curve25519_key();
   auto plaintext = "It's a secret to everybody";
 
   auto message = session->encrypt(plaintext);
 
   auto [bob_session, decrypted] =
       bob->create_inbound_session(*alice_key, *message);
 
   plaintext = "Grumble grumble";
   message = session2->encrypt(plaintext);
 
   EXPECT_FALSE(bob_session->session_matches(*message));
 }
 
 TEST(SessionTest, InvalidOneTimeKey) {
   EXPECT_ANY_THROW(types::curve_key_from_base64(""));
 }