def test_encode_b64_int(self):

        self.assertEqual(encode_b64_int(0), b'AA==')
        self.assertEqual(encode_b64_int(2 ** 24 - 1), b'////')

        self.assertRaises(ValueError, encode_b64_int, -1)
        self.assertRaises(TypeError, encode_b64_int, '')
        self.assertRaises(TypeError, encode_b64_int, None)
    def test_create_identity_list(self):
        """Test identity list creation"""

        id1 = dandelion.identity.generate()
        id2 = dandelion.identity.generate()
        id3 = dandelion.identity.generate()

        identities = dandelion.protocol.create_identity_list([id1, id2, id3])

        self.assertTrue(len(identities) > 0)
        self.assertEqual(identities.count(';'), 2)
        self.assertTrue(encode_b64_int(id1.rsa_key.n).decode() in identities)
        self.assertTrue(encode_b64_int(id2.rsa_key.e).decode() in identities)
        self.assertTrue(encode_b64_int(id3.dsa_key.q).decode() in identities)

        identities = dandelion.protocol.create_identity_list([])
        self.assertEqual(identities, dandelion.protocol.TERMINATOR)

        self.assertRaises(ValueError, dandelion.protocol.create_identity_list, None)
        self.assertRaises(TypeError, dandelion.protocol.create_identity_list, 1337)
    def add_identities(self, identities):
        """Add a a list of identities to the data base.
        
        Will add all identities, not already in the data base to the data base and return a 
        time cookie (bytes) that represents the point in time after the identities have been added.
        If no identities were added, it just returns the current time cookie. 
        """

        if identities is None or not hasattr(identities, "__iter__"):
            raise TypeError

        cookie = self._add_content(
            self._QUERY_GET_IDENTITY_COUNT,
            self._QUERY_ADD_IDENTITIES,
            [
                (
                    self._encode_id(id.fingerprint),
                    encode_b64_int(id.dsa_key.y),
                    encode_b64_int(id.dsa_key.g),
                    encode_b64_int(id.dsa_key.p),
                    encode_b64_int(id.dsa_key.q),
                    encode_b64_int(id.rsa_key.n),
                    encode_b64_int(id.rsa_key.e),
                    None,
                )
                for id in identities
            ],
        )
        for listener in self._listener_functions:
            listener("identity", identities)
        return cookie
    def add_private_identity(self, identity):
        """Add a private identity to the data base."""

        if identity is None:
            raise TypeError

        if not dandelion.identity.IdentityInfo(self, identity).is_private():
            raise ValueError

        # Add the public part
        self.add_identities([identity])

        # ... and the private part
        with sqlite3.connect(self._db_file) as conn:
            c = conn.cursor()
            c.execute(
                "INSERT INTO private_identities (fingerprint, dsa_x, rsa_d) VALUES (?,?,?)",
                (
                    self._encode_id(identity.fingerprint),
                    encode_b64_int(identity.dsa_key.x),
                    encode_b64_int(identity.rsa_key.d),
                ),
            )
def _message2string(msg):
    """Serialize a message to a DMS string"""

    text = msg.text.encode() if isinstance(msg.text, str) else msg.text # Convert to bytes string
    timestamp = '' if msg.timestamp is None else encode_b64_int(msg.timestamp).decode()
    receiver = b'' if msg.receiver is None else msg.receiver
    sender, signature = (b'', b'') if msg.sender is None else (msg.sender, msg.signature)

    return _SUB_FIELD_SEPARATOR.join([
              encode_b64_bytes(text).decode(),
              timestamp,
              encode_b64_bytes(receiver).decode(),
              encode_b64_bytes(sender).decode(),
              encode_b64_bytes(signature).decode()])
def _identity2string(identity):
    """Serialize a identity to a DMS string"""

    return _SUB_FIELD_SEPARATOR.join([
              encode_b64_int(identity.rsa_key.n).decode(),
              encode_b64_int(identity.rsa_key.e).decode(),
              encode_b64_int(identity.dsa_key.y).decode(),
              encode_b64_int(identity.dsa_key.g).decode(),
              encode_b64_int(identity.dsa_key.p).decode(),
              encode_b64_int(identity.dsa_key.q).decode()])