Decentralized Instant Messaging Protocol (Python)
Talk is cheap, show you the codes!
Dependencies
pip3 install dimp
Common Extensions
facebook.py
class Facebook(Barrack):
""" Access database to load/save user's private key, meta and profiles """
def save_private_key(self, private_key: PrivateKey, identifier: ID) -> bool:
# TODO: save private key into safety storage
pass
def save_meta(self, meta: Meta, identifier: ID) -> bool:
if not meta.match_identifier(identifier):
return False
# TODO: save meta to local/persistent storage
pass
def save_profile(self, profile: Profile) -> bool:
if not self.verify_profile(profile):
return False
# TODO: save to local storage
pass
def verify_profile(self, profile: Profile) -> bool:
if profile is None:
return False
elif profile.valid:
# already verified
return True
identifier = profile.identifier
meta = None
if identifier.type.is_user():
# verify with user's meta.key
meta = self.meta(identifier=identifier)
elif identifier.type.is_group():
# verify with group owner's meta.key
group = self.group(identifier=identifier)
if group is not None:
meta = self.meta(identifier=group.owner)
if meta is not None:
return profile.verify(public_key=meta.key)
#
# SocialNetworkDelegate
#
def user(self, identifier: ID) -> User:
entity = super().user(identifier=identifier)
if entity is not None:
return entity
meta = self.meta(identifier=identifier)
if meta is not None:
key = self.private_key_for_signature(identifier=identifier)
if key is None:
entity = User(identifier=identifier)
else:
entity = LocalUser(identifier=identifier)
self.cache_user(user=entity)
return entity
def group(self, identifier: ID) -> Group:
entity = super().group(identifier=identifier)
if entity is not None:
return entity
meta = self.meta(identifier=identifier)
if meta is not None:
entity = Group(identifier=identifier)
self.cache_group(group=entity)
return entity
#
# global
#
facebook = Facebook()
keystore.py
class KeyStore(KeyCache):
""" For reuse symmetric key """
def save_keys(self, key_map: dict) -> bool:
# TODO: save to local cache
pass
def load_keys(self) -> dict:
# TODO: load from local cache
pass
#
# global
#
keystore = KeyStore()
messenger.py
class Messenger(Transceiver, MessengerDelegate):
""" Transform and send message """
def __init__(self):
super().__init__()
self.delegate = self
#
# MessengerDelegate
#
def send_package(self, data: bytes, handler: CompletionHandler) -> bool:
# TODO: Send out a data package onto network
pass
def upload_data(self, data: bytes, msg: InstantMessage) -> str:
# TODO: Upload encrypted data to CDN
pass
def download_data(self, url: str, msg: InstantMessage) -> bytes:
# TODO: Download encrypted data from CDN
pass
#
# global
#
messenger = Messenger()
messenger.barrack = facebook
messenger.key_cache = keystore
User Account
register.py
def register(username: str) -> User:
# 1. generate private key
sk = PrivateKey({'algorithm': 'RSA'})
# 2. generate meta with username(as seed) and private key
meta = Meta.generate(private_key=sk, seed=username)
# 3. generate ID with network type by meta
identifier = meta.generate_identifier(network=network)
# 4. save private key and meta info
facebook.save_private_key(private_key=sk, identifier=identifier)
facebook.save_meta(meta=meta, identifier=identifier)
# 5. create user with ID
return facebook.user(identifier)
Messaging
send.py
def pack(content: Content, sender: ID, receiver: ID) -> ReliableMessage:
msg = InstantMessage.new(content=content, sender=sender, receiver=receiver)
return messenger.encrypt_sign(msg)
if __name__ == '__main__':
moki = ID("moki@4WDfe3zZ4T7opFSi3iDAKiuTnUHjxmXekk");
hulk = ID("hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj");
content = TextContent.new(text='Hello world!')
msg = pack(content=content, sender=moki, receiver=hulk)
# TODO: send out the request data
request = json.dumps(msg) + '\n'
data = request.encode('utf-8')
receive.py
def receive(pack: bytes) -> InstantMessage:
msg = json.loads(pack.decode('utf-8'))
r_msg = ReliableMessage(msg)
i_msg = messenger.verify_decrypt(r_msg)
# TODO: process message content
pass
Copyright © 2019 Albert Moky
Metadata
Release files for dimp 0.7.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| dimp-0.7.6.tar.gz | 17.9 kB | Without provenance | Details for dimp-0.7.6.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| dimp-0.7.6-py3-none-any.whl | Python 3 | none | any | Details for dimp-0.7.6-py3-none-any.whl |
Total release size: 49.9 kB
Release files / dimp-0.7.6.tar.gz
| Download URL | dimp-0.7.6.tar.gz |
|---|---|
| Size | 17.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e0e14254f517da785c3d627999476664dc578eb52da6a7a3ec0360ce3d63419f
|
|
BLAKE2b-256 checksum How to use checksums |
5ad3abf0a842f43b5c19151a931eb53ce74a93235b1a065c4a14dd86d7950123
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.29.0 CPython/3.7.2
|
Release files / dimp-0.7.6-py3-none-any.whl
| Download URL | dimp-0.7.6-py3-none-any.whl |
|---|---|
| Size | 32.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02b90285fab856c22ec637e172c1b3ab552716cb388f399f71c0112b25e51b9c
|
|
BLAKE2b-256 checksum How to use checksums |
0b9ebf9c64afa593bec0841da5cbd3556bb596b0f8fed15b967b4719f4545bd5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.29.0 CPython/3.7.2
|
Security for dimp 0.7.6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.