def create_tx(self, msg_type, msg, rec_key): global time, urandom if msg_type == "00": tx = "00" + self.dh_public_key_hex + hex(int( time()))[2:] + rec_key + self.public_key_hex tx = bytes.fromhex(tx) else: print(f"msg: {msg}") raw_msg = msg msg = msg.encode("utf-8") nonce = "" if msg_type == "01": logging.debug(f"rec_key: {rec_key}") for i in self.pub_keys: logging.debug(f"{i}: {self.pub_keys[i]}") if rec_key == i: key = self.pub_keys[i][1] if key == "no" or key == "sent": self.ui_in.put([ "warning", "S použivateľom ešte neprebehla výmena kľúčov" ]) return key = bytes.fromhex(key) break nonce = urandom(16) algorithm = ChaCha20(key, nonce) cipher = Cipher(algorithm, mode=None, backend=backend) encryptor = cipher.encryptor() msg = encryptor.update(msg) nonce = nonce.hex() msg = msg.hex() print(f"msg hex: {msg}") if len(msg) <= 2000: msg_size = self.fill(hex(len(bytes.fromhex(msg)))[2:], 4) current_time = int(time()) timestamp = hex(current_time)[2:] print(f"nonce: {nonce}") tx = msg_type + nonce + msg_size + msg + timestamp + rec_key + self.public_key_hex tx = bytes.fromhex(tx) self.c_m.execute( f"INSERT INTO '{rec_key}' VALUES (?,?,?,?);", (current_time, raw_msg, 1, int(not int(msg_type) - 1))) self.conn_m.commit() else: #tu treba dat aj self.ui_in.put(["warning", "Správa je príliš dlhá"]) signature = self.private_key.sign(tx) tx = tx + signature #na toto verify sa treba pozret ked dorobim verify_tx if self.verify_tx(tx.hex()) == True: return tx else: logging.debug("vytvorena tx je zla") return False
def tx_content(self, tx): if tx[-256:-192] == self.public_key_hex: tx_type = tx[:2] logging.debug(f"{tx_type}") peer_pub_key = tx[-192:-128] try: user = self.pub_keys[peer_pub_key] except KeyError: self.save_key(peer_pub_key) user = self.pub_keys[peer_pub_key] logging.debug(f"user: {user}") if tx_type == "00": logging.debug("som v 00") dh_peer_key = X25519PublicKey.from_public_bytes( bytes.fromhex(tx[2:66])) shared_key = self.dh_private_key.exchange(dh_peer_key) derived_key = HKDF( algorithm=SHA256(), length=32, salt=None, info=b'blockchain', backend=backend, ).derive(shared_key) if user[1] == "no": #mozno by som nemal prijimat tx pocas syncovania self.send_message("send", cargo=["", peer_pub_key, "00"]) self.pub_keys[peer_pub_key][1] = derived_key.hex() logging.debug("posuvam do edit key files") self.edit_key_file(peer_pub_key, derived_key.hex(), 2) #musim kukat aj tx od seba ktore nemam elif tx_type == "01": nonce = bytes.fromhex(tx[2:34]) msg_size = int(tx[34:38], 16) * 2 msg = bytes.fromhex(tx[38:msg_size + 38]) if user[1] == "no" or user[1] == "sent": if user[0] == "__unknown" and user[1] == "no": self.del_pub_key(peer_pub_key) del self.pub_keys[peer_pub_key] print("sifrovana sprava ale neprebehla vymena klucov") return False encryption_key = bytes.fromhex(user[1]) algorithm = ChaCha20(encryption_key, nonce) cipher = Cipher(algorithm, mode=None, backend=backend) decryptor = cipher.decryptor() msg = decryptor.update(msg) msg = msg.decode("utf-8") print(f"e {user[0]}: {msg}") elif tx_type == "02": msg_size = int(tx[2:6], 16) * 2 msg = bytes.fromhex(tx[6:msg_size + 6]).decode("utf-8") print(f"{user[0]}: {msg}")
def create_tx(self, msg_type, msg, rec_key): global time, urandom if msg_type == "00": tx = "00" + self.dh_public_key_hex + hex(int( time()))[2:] + rec_key + self.public_key_hex tx = bytes.fromhex(tx) else: msg = msg.encode("utf-8") if msg_type == "01": logging.debug(f"rec_key: {rec_key}") for i in self.pub_keys: logging.debug(f"{i}: {self.pub_keys[i]}") if rec_key == i: key = self.pub_keys[i][1] if key == "no" or key == "sent": print( "s pouzivatelom este neprebehla vymena klucov") return key = bytes.fromhex(key) break nonce = urandom(16) algorithm = ChaCha20(key, nonce) cipher = Cipher(algorithm, mode=None, backend=backend) encryptor = cipher.encryptor() msg = encryptor.update(msg) msg = msg.hex() if len(msg) <= 2000: msg_size = self.fill(hex(len(bytes.fromhex(msg)))[2:], 4) timestamp = hex(int(time()))[2:] tx = msg_size + msg + timestamp + rec_key + self.public_key_hex if msg_type == "01": tx = "01" + nonce.hex() + tx else: tx = "02" + tx tx = bytes.fromhex(tx) else: #tu treba dat aj print("sprava je prilis velka") signature = self.private_key.sign(tx) tx = tx + signature #na toto verify sa treba pozret ked dorobim verify_tx if self.verify_tx(tx.hex()) == True: return tx else: logging.debug("vytvorena tx je zla") return False
def __init__(self, key: bytes, iv: bytes, decrypt: bool = False, aad: bytes = b''): super().__init__(decrypt) self.cipher = Cipher(ChaCha20(key, iv), None, default_backend()).encryptor() # Initialize MAC key mac_key = self.cipher.update(bytes(64))[:32] self.mac = Poly1305(mac_key & b'\xff\xff\xff\x0f\xfc\xff\xff\x0f' b'\xfc\xff\xff\x0f\xfc\xff\xff\x0f' b'\xff\xff\xff\xff\xff\xff\xff\xff' b'\xff\xff\xff\xff\xff\xff\xff\xff') # if AAD exists, update AAD to self.mac if not aad: return self.aad_len = len(aad) pad1_len = 16 - (self.aad_len % 16) % 16 self.mac.update(aad + bytes(pad1_len))
def tx_content(self, tx): sender = False if tx[-192:-128] == self.public_key_hex: sender = True if tx[-256:-192] == self.public_key_hex or sender: tx_type = tx[:2] logging.debug(f"{tx_type}") if sender: peer_pub_key = tx[-256:-192] else: peer_pub_key = tx[-192:-128] timestamp = int(tx[-264:-256], 16) try: user = self.pub_keys[peer_pub_key] except KeyError: self.save_key(peer_pub_key) user = self.pub_keys[peer_pub_key] self.c_m.execute(f"""CREATE TABLE '{peer_pub_key}' ( timestamp INTEGER, message TEXT, sender INTEGER, encryption INTEGER) """) init_msg = "Komunikácia bola zahájená druhou stranou, ešte nemôžeš posielať šifrované správy" self.c_m.execute( f"INSERT INTO '{peer_pub_key}' VALUES (?,?,?,?);", (int(time()), init_msg, 3, 1)) self.conn_m.commit() logging.debug(f"user: {user}") if tx_type == "00": if sender: if user[1] == "no": user[1] = "sent" return logging.debug("som v 00") dh_peer_key = X25519PublicKey.from_public_bytes( bytes.fromhex(tx[2:66])) shared_key = self.dh_private_key.exchange(dh_peer_key) derived_key = HKDF( algorithm=SHA256(), length=32, salt=None, info=b'blockchain', backend=backend, ).derive(shared_key) if user[1] == "no": #mozno by som nemal prijimat tx pocas syncovania self.send_message("send", cargo=["", peer_pub_key, "00"]) self.pub_keys[peer_pub_key][1] = derived_key.hex() logging.debug("posuvam do edit key files") self.edit_key_file(peer_pub_key, derived_key.hex(), 2) #musim kukat aj tx od seba ktore nemam exchange_msg = "Výmena kľúčov prebehla úspešne odteraz môžeš správy posielať šifrované" self.c_m.execute( f"INSERT INTO '{peer_pub_key}' VALUES (?,?,?,?);", (timestamp, exchange_msg, 3, 1)) self.conn_m.commit() self.ui_in.put([ "new", [timestamp, exchange_msg, "Info", 1, peer_pub_key] ]) return elif tx_type == "01": nonce = bytes.fromhex(tx[2:34]) msg_size = int(tx[34:38], 16) * 2 msg = bytes.fromhex(tx[38:msg_size + 38]) if user[1] == "no" or user[1] == "sent": if user[0] == "__unknown" and user[ 1] == "no" and not sender: self.del_pub_key(peer_pub_key) del self.pub_keys[peer_pub_key] print("sifrovana sprava ale neprebehla vymena klucov") return False encryption_key = bytes.fromhex(user[1]) algorithm = ChaCha20(encryption_key, nonce) cipher = Cipher(algorithm, mode=None, backend=backend) decryptor = cipher.decryptor() msg = decryptor.update(msg) msg = msg.decode("utf-8") print(f"{user[0]}: {msg}") elif tx_type == "02": msg_size = int(tx[2:6], 16) * 2 msg = bytes.fromhex(tx[6:msg_size + 6]).decode("utf-8") print(f"{user[0]}: {msg}") msg_sender = 0 name = user[0] if sender: msg_sender = 1 name = "Me" self.c_m.execute( f"INSERT INTO '{peer_pub_key}' VALUES (?,?,?,?);", (timestamp, msg, msg_sender, int(not int(tx_type) - 1))) self.conn_m.commit() self.ui_in.put([ "new", [timestamp, msg, user[0], not int(tx_type) - 1, peer_pub_key] ])
def chacha_stream_xor(m, n, k): assert len(n) == 12 alg = ChaCha20(k, bytearray([0] * 4) + n) cipher = Cipher(alg, mode=None, backend=default_backend()) return cipher.encryptor().update(m)
def chacha(i, k): assert len(i) == 16 alg = ChaCha20(k, i) cipher = Cipher(alg, mode=None, backend=default_backend()) return cipher.encryptor().update(ZERO64)
def chacha20(key, data, nonce, ctr): """Encrypt/decrypt a block of data with the ChaCha20 cipher""" return Cipher(ChaCha20(key, (_CTR_1 if ctr else _CTR_0) + nonce), mode=None, backend=backend).encryptor().update(data)