def decode(self, privateKey): key = [] ln = 32 for i in range(1, ln * 2 + 1): indx = int(i * self.frame_size / (ln * 2 + 3)) label = indx % self.stride column = type(indx)(indx / self.stride) elem1 = self.frame[label][column] & 0x000f wr_opg.add(indx) indx = int(i * self.frame_size / (ln * 2 + 3)) + ln label = indx % self.stride column = type(indx)(indx / self.stride) elem2 = self.frame[label][column] & 0x000f wr_opg.add(indx) key.append(elem1 * 16 + elem2) session_key = rsa.decrypt(bytes(key), privateKey) session_key = session_key.decode(self.coding) self.alg = BBS(key=session_key.split(' ')[1:]) self.msglen = int(session_key.split(' ')[0]) n_symbols = self.msglen string = '' for i in range(n_symbols): sym, indx = self.read_symbol() string += sym + " " result = bytes.fromhex(string).decode(self.coding) return result
def __init__(self, public_key1, public_key2): DH.log_message("Initializing Diffie–Hellman key exchange...") self.bbs = BBS(128) self.public_key1 = public_key1 self.public_key2 = public_key2 self.private_key = self.bbs.next(16) self.shared_key = None self.full_key = None DH.log_message(f'\tPublic key1: {self.public_key1}') DH.log_message(f'\tPublic key2: {self.public_key2}') DH.log_message(f'\tPrivate key: {self.private_key}')
def __init__(self, coding='utf-8', audio: Audio = None, stride=1, algorithm=None, key=None, test=None): if key is not None: self.alg = BBS(key=key.split(' ')[1:]) self.msglen = int(key.split(' ')[0]) else: self.alg = algorithm if test is not None: self.enc = test.split(" ") self.stride = stride self.audio = audio self.coding = coding self.frame_size = len(audio.frame) - (len(audio.frame) % self.stride) self.frame, self.tail = audio.frame[:self.frame_size], \ audio.frame[self.frame_size:] self.frame = np.reshape( self.frame, (self.stride, int(len(self.frame) / self.stride)))
import argparse from Audio import Audio import rsa from Cryptographer import Cryptographer from BBS import BBS parser = argparse.ArgumentParser(description='Encryptor parser') parser.add_argument('-i', type=str, default=r'source.wav') parser.add_argument('-o', type=str, default=r'audio.wav') parser.add_argument('-fmsg', type=str, default=None) parser.add_argument('-msg', type=str, default="Hello world!") parser.add_argument('-enc', type=str, default="utf-8") args = parser.parse_args() if args.fmsg is not None: with open(args.fmsg, "r") as read_text: msg = read_text.read().replace("\n", "*") else: msg = args.msg with open("public_key.txt", "r") as pr: private_str = pr.read().split(" ") public = rsa.PublicKey(int(private_str[0]), int(private_str[1])) audio_test = Audio(filename=args.i) audio = Audio(filename=args.i) encrypter = Cryptographer(audio=audio, algorithm=BBS(), coding=args.enc) encrypter.encrypt(msg, filename=args.o, publicKey=public) audio2 = Audio(filename=args.o) print("Successfully encrypted")
class Cryptographer: def __init__(self, coding='utf-8', audio: Audio = None, stride=1, algorithm=None, key=None, test=None): if key is not None: self.alg = BBS(key=key.split(' ')[1:]) self.msglen = int(key.split(' ')[0]) else: self.alg = algorithm if test is not None: self.enc = test.split(" ") self.stride = stride self.audio = audio self.coding = coding self.frame_size = len(audio.frame) - (len(audio.frame) % self.stride) self.frame, self.tail = audio.frame[:self.frame_size], \ audio.frame[self.frame_size:] self.frame = np.reshape( self.frame, (self.stride, int(len(self.frame) / self.stride))) def encrypt(self, text, filename, publicKey: rsa.PublicKey): n_symbols = len(text) sesskey = "{} {}".format(len(text), self.alg.get_key()).encode('ascii') sesskey = rsa.encrypt(sesskey, pub_key=publicKey) sess_array = np.frombuffer(sesskey, dtype=np.uint8) ln = int(len(sess_array) / 2) for i in range(1, len(sess_array) + 1): elem1 = (sess_array[i - 1] & 0xf0) >> 4 elem2 = sess_array[i - 1] & 0x0f indx = int(i * self.frame_size / (ln * 2 + 3)) label = indx % self.stride column = type(indx)(indx / self.stride) self.frame[label][column] = np.int16(self.frame[label][column] & 0xfff0) | elem1 opg.add(indx) indx = int(i * self.frame_size / (ln * 2 + 3)) + ln label = indx % self.stride column = type(indx)(indx / self.stride) self.frame[label][column] = np.int16(self.frame[label][column] & 0xfff0) | elem2 opg.add(indx) for i in range(n_symbols): self.encrypt_symbol(text[i]) self.frame = np.reshape(self.frame, (1, self.frame_size))[0] if not len(self.tail) == 0: self.frame = list(self.frame) + list(self.tail) self.frame = np.array(self.frame, dtype=np.int16) self.write_frame(filename) def encrypt_symbol(self, symbol): answer = '' symbol_stream = hex(symbol.encode(self.coding)[0])[2:] for i in symbol_stream: indx = self.alg.getdigit(n_bytes=4) % self.frame_size while indx in opg or indx < 1000: indx = self.alg.getdigit(n_bytes=4) % self.frame_size opg.add(indx) label = indx % self.stride column = type(indx)(indx / self.stride) self.frame[label][column] = np.int16(self.frame[label][column] & 0xfff0) | np.int16( int(i, base=16)) answer += hex(int(self.frame[label][column] & 0x000f))[2:] return answer def write_frame(self, name): self.audio.write_to_file(self.frame, name=name) def decode(self, privateKey): key = [] ln = 32 for i in range(1, ln * 2 + 1): indx = int(i * self.frame_size / (ln * 2 + 3)) label = indx % self.stride column = type(indx)(indx / self.stride) elem1 = self.frame[label][column] & 0x000f wr_opg.add(indx) indx = int(i * self.frame_size / (ln * 2 + 3)) + ln label = indx % self.stride column = type(indx)(indx / self.stride) elem2 = self.frame[label][column] & 0x000f wr_opg.add(indx) key.append(elem1 * 16 + elem2) session_key = rsa.decrypt(bytes(key), privateKey) session_key = session_key.decode(self.coding) self.alg = BBS(key=session_key.split(' ')[1:]) self.msglen = int(session_key.split(' ')[0]) n_symbols = self.msglen string = '' for i in range(n_symbols): sym, indx = self.read_symbol() string += sym + " " result = bytes.fromhex(string).decode(self.coding) return result def read_symbol(self): sym = "" indxs = [] for i in range(2): indx = self.alg.getdigit(n_bytes=4) % self.frame_size while indx in wr_opg or indx < 1000: indx = self.alg.getdigit(n_bytes=4) % self.frame_size wr_opg.add(indx) indxs.append(indx) label = indx % self.stride column = type(indx)(indx / self.stride) sym += hex(np.int16(self.frame[label][column] & 0x000f))[2:] return sym, indxs def __str__(self): return """ len frame = {} len tail = {} stride = {}""".format(self.frame.shape, len(self.tail), self.stride)
from BBS import BBS from Tests import Tests bits = BBS(7, 31) bits = bits.generateBits(20000) print(Tests().series(bits)) print(Tests().singleBit(bits))
class DH(object): ''' DH is a the contraction for Diphie-Hellman key exchange algoithm implementation It works by implementing cryptographic shared key interchange to later on send an shared key withi which any message can be decrypted by using a unique generated private key. Cryptographic explanation: Algorithm uses multiplicative group of integers modulo p, where p is prime, and g is a primitive root modulo p. These two values are chosen in this way to ensure that the resulting shared secret can take on any value from 1 to p–1. 1. Users A and B publicly agree to use a modulus p = 23 and base g = 5 ( primitive root modulo 23). 2. A chooses a private key a = 4, then sends to B [ A = g^a mod p = 5^4 mod 23 = 4| 3. B chooses a secret integer b = 3, then sends to A [ B = g^b mod p = 5^3 mod 23 = 10 ] 4. A computes s = B^a mod p [ 104 mod 23 = 18 ] 5. B computes s = A^b mod p [ s = 43 mod 23 = 18 ] 6. A and B now share a secret (the number 18). 7. A and B have arrived at the same values because under mod p, ''' @staticmethod def log_message(message): logger.info(message) def __init__(self, public_key1, public_key2): DH.log_message("Initializing Diffie–Hellman key exchange...") self.bbs = BBS(128) self.public_key1 = public_key1 self.public_key2 = public_key2 self.private_key = self.bbs.next(16) self.shared_key = None self.full_key = None DH.log_message(f'\tPublic key1: {self.public_key1}') DH.log_message(f'\tPublic key2: {self.public_key2}') DH.log_message(f'\tPrivate key: {self.private_key}') @staticmethod def _pad(s): bs = AES.block_size return s + (bs - len(s) % bs) * chr(bs - len(s) % bs) @staticmethod def _unpad(s): return s[:-ord(s[len(s)-1:])] def create_shared_key(self): DH.log_message(f'Creating Shared key...') self.shared_key = (self.public_key1 ** self.private_key) % self.public_key2 DH.log_message(f'\t Shared key created {self.shared_key}') return self.shared_key def create_full_key(self, shared_key): DH.log_message('Creating full key...') self.full_key = (shared_key ** self.private_key) % self.public_key2 DH.log_message(f'\tFull Key created {self.full_key}!') self.full_key = hashlib.sha256(str(self.full_key).encode()).digest() DH.log_message(f'\tAfter SHA Key created {self.full_key}!') return self.full_key def next_key(self): DH.log_message(f'Setting seed for next private key with shared key {self.shared_key}...') self.bbs.setSeed(self.shared_key) self.private_key = self.bbs.next(16) self.create_shared_key() self.full_key = None def encrypt(self, message): DH.log_message('Encrypting message with AES...') DH.log_message(f'\t[{message}]') message = self._pad(message) iv = Random.new().read(AES.block_size) DH.log_message(f'\tInitialization Vector created {iv}!') cipher = AES.new(self.full_key, AES.MODE_CBC, iv) enc = base64.b64encode(iv + cipher.encrypt(message.encode())) DH.log_message(f'\tMessage Encrypted!') DH.log_message(f'\t[{enc}]') return enc def decrypt(self, enc): enc = base64.b64decode(enc) message = '' DH.log_message('Decrypting message...') DH.log_message(f'\t[{enc}]') iv = enc[:AES.block_size] DH.log_message(f'\tInitialization Vector created {iv}!') cipher = AES.new(self.full_key, AES.MODE_CBC, iv) message = self._unpad(cipher.decrypt(enc[AES.block_size:])) message = message.decode('utf-8') DH.log_message(f'Message Decrypted! {message}') return message @staticmethod def primRoots(modulo,size = 1): primRoots = [] coprimes = {n for n in range(1, modulo) if math.gcd(n, modulo) == 1} for g in range(1,modulo): powers = set() for power in range(1,modulo): powers.add(pow(g, power, modulo)) if coprimes == powers: primRoots.append(g) if len(primRoots) == size: return primRoots return primRoots