def get_rsa_key(bits): [e, n, d] = generate_key(bits) public_key = construct((n, e)).export_key().decode("utf-8") public_key = public_key.replace("-----BEGIN PUBLIC KEY-----\n", "") public_key = public_key.replace("\n-----END PUBLIC KEY-----", "") private_key = construct((n, e, d)).export_key().decode("utf-8") private_key = private_key.replace("-----BEGIN RSA PRIVATE KEY-----\n", "") private_key = private_key.replace("\n-----END RSA PRIVATE KEY-----", "") return [public_key, private_key]
def export_key(sk, pk): # Export *unshared* private key and public key to PEM file from Crypto.PublicKey.RSA import construct # unmaintained pubkey = construct((long(pk['n']), long(pk['e']))) privkey = construct((long(pk['n']), long(pk['e']), long(sk['d']), long(sk['p']), long(sk['q']))) print "RSA public key:" print pubkey.exportKey() print "RSA unshared private key: " print privkey.exportKey(format="PEM", pkcs=8)
def __init__(self, filebytes): self.signature = Signature(filebytes) self.certificate = self.CertificateStruct().unpack( filebytes[len(self.signature): len(self.signature) + len(self.CertificateStruct())] ) pubkey_length = utils.get_key_length(self.certificate.key_type) if pubkey_length == 0x200 + 0x4 + 0x34: self.pubkey_struct = self.PubKeyRSA4096() elif pubkey_length == 0x100 + 0x4 + 0x34: self.pubkey_struct = self.PubKeyRSA2048() elif pubkey_length == 0x3C + 0x3C: self.pubkey_struct = self.PubKeyECC() else: raise Exception("Unknown Public Key type") # Should never happen self.pubkey_struct = self.pubkey_struct.unpack( filebytes[len(self.signature) + len(self.certificate): len(self.signature) + len(self.certificate) + pubkey_length] ) if pubkey_length != 0x3C + 0x3C: self.pubkey = construct( (int.from_bytes(self.pubkey_struct.modulus, byteorder="big"), self.pubkey_struct.exponent) ) self.signer = PKCS1_v1_5.new(self.pubkey) else: self.pubkey = None self.signer = None
def main(chunklist, public_key_loc): with open(public_key_loc, "rb") as key: key.seek(0) pubkey = key.read(256) reversed_key = int.from_bytes( pubkey, 'little') #Little endian encoding (so bytes get reversed) key.close() with open(chunklist, "rb") as chunk: chunk.seek(28) sig_offset = int.from_bytes(chunk.read(2), 'little') chunk.seek(0) digest = chunk.read( sig_offset ) #Digest = header, filesize & SHA256 hash of DMG) are used for hash digest creation chunk.seek(sig_offset) signature = chunk.read(256) chunk.close() # Reverse Signature reversed_sig = np.flip( np.frombuffer(bytearray(signature), dtype=np.uint8, count=-1, offset=0), 0).tobytes() #Exponent & Key e = 0x010001 n = reversed_key key = construct((n, e)) h = SHA256.new(digest) verified = PKCS1_v1_5.new(key).verify(h, reversed_sig) print('Verification = ', verified)
def generate_pal(self, pub_keys): res = {} for j in range(len(pub_keys)): pal_pub_ij, pal_priv_ij = paillier.generate_paillier_keypair() j_public_e = pub_keys[j][1] j_public_n = pub_keys[j][0] pubkey = construct(tuple(pub_keys[j])) cipher = PKCS1_OAEP.new(pubkey) #convert priv_ij to binary (encrypt (p,q) and then rebuild private key on decryption #convert pub_ij to binary. Send (g,n) and then rebuild public key on decryption private_p = pickle.dumps(pal_priv_ij.p) private_q = pickle.dumps(pal_priv_ij.q) #private_bytes = pickle.dumps((pal_priv_ij.p, pal_priv_ij.q)) #print("DEBUG - private_bytes ({}) = {}".format(len(private_bytes), private_bytes)) ciphertext_p = cipher.encrypt(private_p) ciphertext_q = cipher.encrypt(private_q) pal_priv_ij_encrypt = str((ciphertext_p, ciphertext_q)) pal_pub_str = str((pal_pub_ij.g, pal_pub_ij.n)) # Save unencrypted pallier keys tagged with public key of other user self.pall_keys[pub_keys[j]] = (pal_pub_ij, pal_priv_ij) #output pal_priv_ij_encrypt res[str(pub_keys[j])] = (pal_pub_ij, pal_priv_ij_encrypt) return res
def getRsaPublicKey(self): n = int( "A44960441C7E83BB27898156ECB13C8AFAF05D284A4D1155F255CD22D3176CDE50482F2F27F71348E4D2EB5F57BF9671EF15C9224E042B1B567AC1066E06691143F6C50F88787F68CF42716B210CBEF0F59D53405A0A56138A6872212802BB0AEEA6376305DBD428831E8F61A232EFEDD8DBA377305EF972321E1352B5F64630993E5549C64FCB563CDC97DA2124B925DDEA12ADFD00138910F66937FAB68486AE43BFE203C4A617F9F232B5458A9AB409BAC8EDADEF685545F9B013986747737B3FD76A9BAC121516226981EA67225577D15D0F082B8207EAF7CDCB13123937CB12145837648C2F3A65018162315E77EAD2D2DD5986E46251764A43B9BA8F79", 16) e = int("3", 16) rsa_key = construct((n, e)) return rsa_key
def decrypt_vote(encrypted_vote, rsa_modulus, priv_exp): encrypted_vote = encrypted_vote.to_bytes(256, 'little') priv_key = import_key(construct((rsa_modulus, 65537, priv_exp)).exportKey()) cipher_rsa = PKCS1_OAEP.new(priv_key) decrypted_vote = str(cipher_rsa.decrypt(encrypted_vote), 'utf-8')[:66] return decrypted_vote
def encrypt_vote(candidate_id, rsa_modulus): candidate_id = str(candidate_id) pub_key = construct((rsa_modulus, 65537)) salt = str(random.getrandbits(128)) vote = ''.join([candidate_id, salt]).encode('utf-8') cipher_rsa = PKCS1_OAEP.new(pub_key) encrypted_vote = cipher_rsa.encrypt(vote) return int.from_bytes(encrypted_vote, 'little')
def __init__(self, file): if isinstance(file, str): # Load file try: file = open(file, 'rb').read() except FileNotFoundError: raise FileNotFoundError('File not found') self.pubkey_struct = self.PubKeyRSA4096().unpack(file) self.pubkey = construct( (int.from_bytes(self.pubkey_struct.modulus, byteorder="big"), self.pubkey_struct.exponent) ) self.signer = PKCS1_v1_5.new(self.pubkey)
def rsa_encrypt(rsae, rsan, data): if data is None or data == '': return '' N = long(rsan, 16) E = long(rsae, 16) b64data = base64.b64encode(data) pubkey = construct((N, E)) cipher = PKCS1_v1_5.new(pubkey) blocks = int(math.ceil(len(b64data) / 245.0)) result = [] for i in range(blocks): block = b64data[i * 245:(i + 1) * 245] d = cipher.encrypt(block) result.append(d) result = hexlify(''.join(result)) if (len(result) & 1) == 0: return result else: return '0' + result
def _get_pub_key(self): # Get the modulu and exponent from the router url = 'http://{}/cgi/getParm'.format(self.host) referer = 'http://{}'.format(self.host) response = requests.post(url, headers={'REFERER': referer}) if not response.status_code == 200: return False ee = self._get_field_from_router_response(response.text, 'ee') nn = self._get_field_from_router_response(response.text, 'nn') try: e = int(ee, 16) n = int(nn, 16) #snipped for brevity except ValueError: return False pubkey = construct((n, e)) self.pubkey = PKCS1_v1_5.new(pubkey) return True
def parse_mcs_conn_resp(packet): # 4.1.4 Server MCS Connect Response PDU with GCC Conference Create Response # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/d23f7725-876c-48d4-9e41-8288896a19d3 # 2.2.1.4.3.1.1.1 RSA Public Key (RSA_PUBLIC_KEY) # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/fe93545c-772a-4ade-9d02-ad1e0d81b6af # all the next slicing makes sense when looking at above two links # find headerType serverSecurityData (0x0c02) header_offset = packet.find(b'\x02\x0c') sec_data = packet[header_offset:] ran_len = int.from_bytes(sec_data[12:12 + 4], byteorder='little') server_ran = sec_data[20:20 + ran_len] # magic number server_cert_offset = packet.find(b'\x52\x53\x41\x31') server_cert = packet[server_cert_offset:] key_len = int.from_bytes(server_cert[4:8], byteorder='little') bit_len = int.from_bytes(server_cert[8:12], byteorder='little') rsa_pub_exp = int.from_bytes(server_cert[16:20], byteorder='little') rsa_pub_mod = int.from_bytes(server_cert[20:20 + key_len], byteorder='little') #print('pub_mod = %s' % binascii.hexlify(server_cert[20:20+key_len])) #print('keylen: %d' % key_len) #print('bitlen: %d' % bit_len) #print('pub exp: %d' % rsa_pub_exp) pubkey = construct((rsa_pub_mod, rsa_pub_exp)) crypt = [] crypt.append(server_ran) crypt.append(pubkey) crypt.append(bit_len) return crypt
def credit_balance(connection, amount): # first request the user infos infos = request_user_infos(connection) if infos is None: return False # then request a challenge from the card enc = None Le = 0x0 data, sw1, sw2 = connection.transmit( [CLA, INS_REQUEST_CHALLENGE, P1, P2, Le]) if sw1 == 0x90 and sw2 == 0x00: conn = connect("../res/paystival.sqlite") cur = conn.cursor() userid = to2hex(infos[2][0]) + to2hex(infos[2][1]) + to2hex( infos[2][2]) + to2hex(infos[2][3]) cur.execute("SELECT exponent, modulus FROM public_keys WHERE userid=?", (userid, )) r = cur.fetchall() cur.close() conn.close() try: pubkey = construct((int(r[0][1], 10), r[0][0])) except: return False num = int.from_bytes(data, "big") enc = pubkey.encrypt(num, 0)[0] enc = list(enc.to_bytes(64, "big")) # now credit the card Le = 0x42 data, sw1, sw2 = connection.transmit( [CLA, INS_CREDIT_BALANCE, P1, P2, Le] + [(amount >> 8) & 0xFF, amount & 0xFF] + enc) if sw1 == 0x90 and sw2 == 0x00: return True else: print_ret_codes(sw1, sw2) return False else: return False
def password_encryption_based_ras(origin_password, keys_str, mods_str): """将原始密码 RSA 加密,作为 POST 中的表单数据 Example: var rsa = {"e":"10001", "n":"d3f513f0..."}; keys_str = rsa["e"] mods_str = rsa["n"] :param origin_password: 原始密码 :param keys_str: 公钥 :param mods_str: 模数 :return: RSA 加密后的十六进制密码(Unicode) """ from Crypto.PublicKey.RSA import construct keys = long(keys_str, 16) mods = long(mods_str, 16) pub_key = construct((mods, keys)) encode_password = pub_key.encrypt(bytes(origin_password[::-1]), None) return unicode(encode_password[0].encode('hex'))
# COMPLETE CHALLENGE enc = None Le = 0x0 data, sw1, sw2 = connection.transmit([CLA, INS_REQUEST_CHALLENGE, P1, P2, Le]) if sw1 == 0x90 and sw2 == 0x00: conn = connect("../res/paystival.sqlite") cur = conn.cursor() userid = to2hex(infos[2][0]) + to2hex(infos[2][1]) + to2hex( infos[2][2]) + to2hex(infos[2][3]) cur.execute("SELECT exponent, modulus FROM public_keys WHERE userid=?", (userid, )) r = cur.fetchall() cur.close() conn.close() pubkey = construct((int(r[0][1], 10), r[0][0])) num = int.from_bytes(data, "big") enc = pubkey.encrypt(num, 0)[0] enc = list(enc.to_bytes(64, "big")) else: print_ret_codes(sw1, sw2) print("no operation 8") Le = 0x42 data, sw1, sw2 = connection.transmit([CLA, INS_CREDIT_BALANCE, P1, P2, Le] + [0x0, 0x02] + enc) if sw1 == 0x90 and sw2 == 0x00: print("test credit done") else: print_ret_codes(sw1, sw2) print("no operation 9")
#!/usr/bin/env python3 ##### #Command to verify the contents of the public key generate from this program #using openssl #openssl rsa -text -inform PEM -pubin -in id_rsa_constructed.pub ##### from Crypto.PublicKey.RSA import construct f = open("modExponent", 'r') data = f.read() data = data.split("#") modulus = (data[0].split("="))[1] exponent = (data[1].split("="))[1] print("modulus=" + modulus) print("exponent=" + exponent) n = int(modulus, 16) e = int(exponent, 16) rsakey = construct((n, e)) exported_key = rsakey.exportKey() f = open("id_rsa_constructed.pub", 'wb') f.write(exported_key) f.close()
from __future__ import print_function, unicode_literals import base64 import sys from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 from Crypto.PublicKey.RSA import construct # prepare public key e = int('10001', 16) n = int(sys.stdin.read(), 16) pubkey = construct((n, e)) # create a cipher via PKCS1.5 cipher = PKCS1_v1_5.new(pubkey) # encrypt cipher_text = cipher.encrypt(b"Hello RSA!") # do base64 encode cipher_text = base64.b64encode(cipher_text) print(cipher_text.decode('utf-8'))
def load_eik(pub_mod): global eik e = int('10001', 16) n = int(hexlify(pub_mod), 16) eik = construct((n, e))
euler_n = target.n - (p + q - 1) def inverse(a, n): t = 0 r = n newt = 1 newr = a while newr != 0: q = r // newr t, newt = newt, t - q * newt r, newr = newr, r - q * newr if r > 1: raise "a is not invertible" if t < 0: t = t + n return t # Compute private exponent d = inverse(target.e, euler_n) # Generate private key private_key = construct((target.n, target.e, d, p, q)) print(private_key.exportKey().decode('utf-8')) # To decrypt: # openssl rsautl -decrypt -in hector.ramon_RSA_RW.enc -out hector.ramon_RSA_RW.txt -inkey hector.ramon_privkeyRSA_RW.pem
return p, q else: A = A - 1 C = C + (1 << (m * 2)) return crack_it(m, A, B, C) p, q = crack_it(m, A, B, C) assert(n == p * q) print(n) print() print(p * q) d = number.inverse(e, (p - 1) * (q - 1)) private_key = construct((n, e, d)) KEY_FILENAME = 'mi_clave_privada_RSA_pseudo.pem' with open(KEY_FILENAME, 'wb') as f: f.write(private_key.exportKey('PEM')) print('RSA private key generated.') # Decrypt RSA DEC_FILENAME = 'dec_RSA_pseudo.key' ENC_FILENAME = 'margarita.geleta_RSA_pseudo.enc' # openssl rsautl -decrypt -inkey mi_clave_privada_RSA.pem -in margarita.geleta_RSA_RW.enc -out dec_RSA.key run(['openssl', 'rsautl', '-decrypt', '-inkey', KEY_FILENAME, '-in', ENC_FILENAME,
if t < 0: t = t + n return t # To extract n and e: # openssl rsa -pubin -inform PEM -text -noout < hector.ramon_pubkeyRSA_pseudo.pemopenssl rsa -pubin -inform PEM -text -noout < hector.ramon_pubkeyRSA_pseudo.pem # Factor n and change this values P = (9734708213678047339, 16) Q = (237722232539831678160480975771558179669, 8) e = 65537 # Compute private key p = P[0] ** P[1] q = Q[0] ** Q[1] euler_p = P[0] ** (P[1] - 1) * (P[0] - 1) euler_q = Q[0] ** (Q[1] - 1) * (Q[0] - 1) n = p * q euler_n = euler_p * euler_q d = inverse(e, euler_n) private_key = construct((n, e, d, p, q)) print(private_key.exportKey().decode('utf-8')) # To decrypt: # openssl rsautl -decrypt -in hector.ramon_RSA_pseudo.enc -out hector.ramon_RSA_pseudo.txt -inkey hector.ramon_privkeyRSA_pseudo.pem
def form_valid(self, form): instance = form.save(commit=False) context = super().get_context_data() try: xml = instance.caf.read() soup = BeautifulSoup(xml, 'xml') root = etree.fromstring(xml) rut = root.xpath('//AUTORIZACION/CAF/DA/RE/text()')[0] razon_social_caf = root.xpath('//AUTORIZACION/CAF/DA/RS/text()')[0] idk = root.xpath('//AUTORIZACION/CAF/DA/IDK/text()')[0] firma_da = root.xpath('//AUTORIZACION/CAF/FRMA/text()')[0] tipo_de_documento = root.xpath('//AUTORIZACION/CAF/DA/TD/text()')[0] rango_desde = root.xpath('//AUTORIZACION/CAF/DA/RNG/D/text()')[0] rango_hasta = root.xpath('//AUTORIZACION/CAF/DA/RNG/H/text()')[0] folios_disponibles = (int(rango_hasta) - int(rango_desde)) + 1 fecha_de_autorizacion = root.xpath('//AUTORIZACION/CAF/DA/FA/text()')[0] pk_modulo = root.xpath('//AUTORIZACION/CAF/DA/RSAPK/M/text()')[0] pk_exponente = root.xpath('//AUTORIZACION/CAF/DA/RSAPK/E/text()')[0] pem_private = root.xpath('//AUTORIZACION/RSASK/text()')[0] pem_public = root.xpath('//AUTORIZACION/RSAPUBK/text()')[0] assert pem_public, "Error de obtencion de clave publica" assert pem_private, "Error de obtencion de clave privada" except: messages.error(self.request, 'Algo anda mal con el CAF') return super().form_invalid(form) try: decoded_exponent = int.from_bytes(b64decode(pk_exponente), 'big') decoded_modulus = int.from_bytes(b64decode(pk_modulo), 'big') assert decoded_modulus assert decoded_exponent sii_pub = construct((decoded_modulus,decoded_exponent)) sii_final = sii_pub.exportKey('PEM').decode('ascii') sii_final = sii_final.replace('\n','').replace('\t','').replace('\r','') pem_public = pem_public.replace('\n','').replace('\t','').replace('\r','') print(sii_final) print(pem_public) assert sii_final == pem_public except: messages.error(self.request, 'La clave publica no fue validada correctamente') return super().form_invalid(form) try: RSAprivatekey = RSA.importKey(pem_private) private_signer = PKCS1_v1_5.new(RSAprivatekey) digest = SHA.new() digest.update(b'mensaje de prueba') sign = private_signer.sign(digest) sign = b64encode(sign) public_signer = PKCS1_v1_5.new(sii_pub) verification = public_signer.verify(digest, b64decode(sign)) assert verification except: messages.error(self.request, 'Clave publica y clave privada no coinciden') return super().form_invalid(form) try: compania = Compania.objects.get(razon_social=instance.empresa) if compania and compania.rut.split('-') == rut.split('-'): instance.rut = rut else: raise ValueError except: messages.error(self.request, 'El CAF no corresponde con la compañía asignada') return super().form_invalid(form) date_list = fecha_de_autorizacion.split('-') fecha_de_autorizacion = timezone.make_aware(datetime.datetime(int(date_list[0]),int(date_list[1]),int(date_list[2]))) # fecha_de_autorizacion = datetime.datetime(int(date_list[0]),int(date_list[1]),int(date_list[2])) instance.tipo_de_documento = int(tipo_de_documento) instance.rango_desde = int(rango_desde) instance.rango_hasta = int(rango_hasta) instance.folio_actual = rango_desde instance.folios_disponibles = folios_disponibles instance.fecha_de_autorizacion = fecha_de_autorizacion instance.pk_modulo = pk_modulo instance.pk_exponente = pk_exponente instance.pem_public = pem_public instance.pem_private = pem_private instance.razon_social = razon_social_caf instance.idk = idk instance.firma = firma_da try: hash_ = instance.hacer_hash() if Folio.objects.filter(unique_hash=hash_).exists(): raise IntegrityError else: instance.unique_hash = hash_ instance.save() except: messages.error(self.request, 'El archivo CAF ya existe') return super().form_invalid(form) messages.success(self.request, 'Archivo CAF añadido exitosamente') return super().form_valid(form)
''' rsakey = RSA.importKey(pub_key) signer = PKCS1_v1_5.new(rsakey) digest = SHA256.new() # Assumes the data is base64 encoded to begin with digest.update(b64decode(data)) if signer.verify(digest, b64decode(signature)): return True return False # http://stackoverflow.com/questions/40094108/i-have-a-rsa-public-key-exponent-and-modulus-how-can-i-encrypt-a-string-using-p modulus = 132014992946851317628321108822184364863563257578174555813409401134257485091016568808351080087191570957978528479437568482885991726617458842578017613352322660969645156597141779386157600232772803000093782179823643344946683602358622484533804213014960185007035142552526386910993194802007914025290782677761336471601 e = 65537L n = modulus # http://stackoverflow.com/questions/34279901/python-rsa-encryption pubkey = construct((n, e)).exportKey() #print pubkey haystack_str = open("./haystack.json", "r").read() data = json.loads(haystack_str)['haystack'] for count, item in enumerate(data): signature = item['signature'] data = item['data'] result = verify_sign_direct(pubkey, signature, data) if result is False: print count, result print "Signature:", signature print "Data:", data
default=False, action="store_true", ) args = parser.parse_args() if args.key: with open(args.key, "r") as f: key = importKey(f.read()) else: p = 11201792995931324012013272950175336896908788202447968408429424207812076636563926070123654735189823803846891279528352720272949563135129697494110095639122437 q = 12781417713775747037727068123145570128249631182737575375399994695663395859430871867605127422779176268198497033603094868069070024963533157740922475694191731 e = 65537 n = p * q phi = (p - 1) * (q - 1) d = inverse(e, phi) key = construct((n, e, d)) cipher = PKCS1_v1_5.new(key) B = 1 << 8 * (key.size_in_bytes() - 2) if args.encrypt: with open(args.file, "r") as f: content = bytes(f.read(), "utf-8") basename = ".".join(args.file.split(".")[:-1]) source = basename + "_rsa.enc" with open(source, "wb") as out: out.write(cipher.encrypt(content)) else: source = args.file with open(source, "rb") as f:
raise "Error computing p and q" euler_n = target_key.n - (p + q - 1) def inverse(a, n): t = 0 r = n newt = 1 newr = a while newr != 0: q = r // newr t, newt = newt, t - q * newt r, newr = newr, r - q * newr if r > 1: raise "a is not invertible" if t < 0: t = t + n return t # Compute private exponent d = inverse(target_key.e, euler_n) # Generate private key private_key = construct((target_key.n, target_key.e, d, p, q)) print(private_key.exportKey().decode('utf-8'))
from Crypto.Util.number import getPrime, isPrime, bytes_to_long from Crypto.PublicKey.RSA import construct from secret import flag def getNextPrime(number): while not isPrime(number): number += 1 return number p = getPrime(2048) q = getNextPrime(p + 1) n = p * q e = 65537 encrypted_flag = pow(bytes_to_long(flag.encode('utf-16')), e, n) print("Public Key = \n{}".format( construct((n, e)).publickey().exportKey().decode())) print("Encrypted Flag = {}".format(hex(encrypted_flag)))
try: (options, args) = parser.parse_args() privkey = None if options.p and options.q: if not gmpy.is_prime(options.p) or not gmpy.is_prime(options.q): raise ValueError( "Supplied p and or supplied q is not a prime number!") print('Using (p, q) to initialise RSA instance\n') n = options.p * options.q if options.p != options.q: phi = (options.p - 1) * (options.q - 1) else: phi = (options.p**2) - options.p d = modinv(options.e, phi) privkey = construct((n, options.e, d)) elif options.n and options.d: print('Using (n, d) to initialise RSA instance\n') privkey = construct((options.n, options.e, options.d)) else: parser.print_help() parser.error('Either (p, q) or (n, d) needs to be specified') if privkey: print(f"n = {privkey.n}") print(f"e = {privkey.e}") print(f"d = {privkey.d}") print(f"p = {privkey.p}") print(f"q = {privkey.q}") keystring = privkey.exportKey() if options.format == 'DER':
def complete_trade(self, trade_id, other_trade_id, other_pub_key): # First generate new pallier key-pair to maintain volume-secrecy # Now create bit representation of trade volume volume = self.waiting_trades[trade_id][ 'amt'] #Note: Max volume checked during trade send print("ORIG VOL: {}".format(volume)) lower_vol = 0 other_pub_key = construct(other_pub_key) perf_time = time.clock() # Buyer initiates (i.e. volume > 0) if volume > 0: pall_pub, pall_priv = paillier.generate_paillier_keypair() table = self.generate_table(volume, pall_pub) #print("DEBUG: volume_bits = {}\n table = {}".format(volume_bits, table)) msg = { 'method': 'send_table', 'params': [(other_pub_key.n, other_pub_key.e), (trade_id, other_trade_id), table] } # Wait to recieve dummy table print("DEBUG: Sending table") self.send_message(msg) # Send fake c vector print("DEBUG: Sending fake_c") fake_c = [ pall_pub.encrypt( random.randint(-pall_pub.n // 3, pall_pub.n // 3)) for i in range(VOLUME_NUM_BITS) ] msg = {'method': 'send_c', 'params': [fake_c]} # Recieve real result vector c = self.send_message(msg) # Decrypt c vector greater = False vals = [] for i in range(VOLUME_NUM_BITS): # In this case we don't care about overflow, only values that lead to 0 try: vals.append(pall_priv.decrypt_encoded(c[i]).decode()) except OverflowError as e: pass print("DEBUG: vals = {}".format(vals)) for val in vals: if val == 0: greater = True break print("DEBUG: Sending volume") if greater == True: # Buy > Sell (i.e. x > y) # Send 0 to indicate that y should send the lower value msg = { 'method': 'notify_volume', 'params': [other_pub_key.encrypt(0, None)[0]] } self.send_message(msg) print("Buy is greater") else: # Send the lower value to the other client msg = { 'method': 'notify_volume', 'params': [other_pub_key.encrypt(volume, None)[0]] } self.send_message(msg) lower_vol = volume print("Sell is greater") # Send fake volume notification msg = { 'method': 'send_min_volume', 'params': [other_pub_key.encrypt(lower_vol, None)[0]] } resp = self.send_message(msg) if lower_vol == 0: lower_vol = self.rsa_priv.decrypt(resp) print("CLIENT: (buyer) Completed trade {} with final volume = {}". format(self.waiting_trades[trade_id], lower_vol)) else: # Seller waits for buyer to send table, sends fake table to hide selling fake_pall_pub, fake_pall_priv = paillier.generate_paillier_keypair( ) fake_table = self.generate_table(random.randint(-1000000, 1000000), fake_pall_pub) msg = { 'method': 'send_table', 'params': [(other_pub_key.n, other_pub_key.e), (trade_id, other_trade_id), fake_table] } #Wait to recieve real table table = self.send_message(msg) pall_pub = table[0][0].public_key # Compute c vector y_volume_bits = auth_getvolumebits(abs(volume)) c = [] #[None]*VOLUME_NUM_BITS zero_enc = zero_encode(y_volume_bits) for t in zero_enc: n = len(y_volume_bits) - 1 x = None k = paillier.EncodedNumber.encode( pall_pub, random.randint(-pall_pub.n // 3, pall_pub.n // 3)) for i in range(len(t)): if x is None: x = table[t[0]][i] else: x += table[t[i]][i] c.append(x * k) while len(c) < len(y_volume_bits): c.append( pall_pub.encrypt( random.randint(-pall_pub.n // 3, pall_pub.n // 3))) #for i in range(VOLUME_NUM_BITS): # if y_volume_bits[i] == 0: # val = table[1][i] # k = random.randint(-pall_pub.n//3, pall_pub.n//3) # for j in range(i+1, VOLUME_NUM_BITS): # val += table[y_volume_bits[j]][j] # val *= k # c[i] = val # else: # c[i] = pall_pub.encrypt(random.randint(-pall_pub.n//3, pall_pub.n//3)) random.shuffle(c) msg = {'method': 'send_c', 'params': [c]} # Recieve fake c vector fake_c = self.send_message(msg) # Send fake volume notification to get response from other client msg = { 'method': 'notify_volume', 'params': [other_pub_key.encrypt(0, None)[0]] } buyer_notify = self.rsa_priv.decrypt(self.send_message(msg)) # Send minimum volume if we need to if buyer_notify == 0: msg = { 'method': 'send_min_volume', 'params': [other_pub_key.encrypt(abs(volume), None)[0]] } lower_vol = abs(volume) self.send_message(msg) print("(seller) Buy is Greater") else: msg = { 'method': 'send_min_volume', 'params': [other_pub_key.encrypt(0, None)[0]] } lower_vol = self.rsa_priv.decrypt(self.send_message(msg)) print("(seller) Sell is Greater") print("CLIENT: (seller) Completed trade {} with final volume = {}". format(self.waiting_trades[trade_id], lower_vol)) print("PERF: Volume Calc time: {}".format(time.clock() - perf_time)) if lower_vol != 0: msg = {'method': 'finish_trade', 'params': [trade_id]} self.send_message(msg) return raise RuntimeError("Trade Matched, but not completed")