def Prove(pk1, X1, Y1, pk2, X2, Y2, r1, r2, v): sr = SystemRandom() #Prover Stage 1 a1 = sr.getrandbits(256) a2 = sr.getrandbits(256) b = sr.getrandbits(256) A1 = bn128.multiply(pk1, a1) A2 = bn128.multiply(pk2, a2) B1 = bn128.add(bn128.multiply(bn128.G1, a1), bn128.multiply(H, b)) B2 = bn128.add(bn128.multiply(bn128.G1, a2), bn128.multiply(H, b)) #Fiat Shamir hasher = keccak_256() hasher.update(A1[0].n.to_bytes(32, 'big')) hasher.update(A1[1].n.to_bytes(32, 'big')) hasher.update(A2[0].n.to_bytes(32, 'big')) hasher.update(A2[1].n.to_bytes(32, 'big')) hasher.update(B1[0].n.to_bytes(32, 'big')) hasher.update(B1[1].n.to_bytes(32, 'big')) hasher.update(B2[0].n.to_bytes(32, 'big')) hasher.update(B2[1].n.to_bytes(32, 'big')) e = int.from_bytes(hasher.digest(), 'big') #Prover Stage 2 z1 = (a1 + e * r1) % bn128.curve_order z2 = (a2 + e * r2) % bn128.curve_order z3 = (b + e * v) % bn128.curve_order return (z1, z2, z3)
def randomKey(entropy): """ 256 bit number from equally strong urandom, user entropy, and timer parts """ if entropy.bit_length() < 250: print('Insufficient entropy parameter to generate key') return False from random import SystemRandom osrndi = SystemRandom() entstr = enc.encode(entropy, 16) + enc.encode(osrndi.getrandbits(512), 256) + str(clockrnd()) osrnd = SystemRandom(entstr) privkey = 0 while privkey < 1 or privkey > elip.N: privkey = enc.decode(hashlib.sha256(enc.encode(osrnd.getrandbits(512), 256)).digest(), 256) ^ osrnd.getrandbits( 256) for lbit in xrange(clockrnd() % 64 + 64): clockstr = hex(clockrnd()) + str(clockrnd()) + entstr # Slice a moving 256 bit window out of SHA512 clock32 = hashlib.sha512(clockstr).digest()[1 + (lbit % 29): 33 + (lbit % 29)] randhash = hashlib.sha512(enc.encode(osrnd.getrandbits(512), 256)).digest()[ 0 + (lbit % 31): 32 + (lbit % 31)] privkey ^= enc.decode(randhash, 256) ^ enc.decode(clock32, 256) ^ osrndi.getrandbits(256) osrnd = SystemRandom(hashlib.sha512(clock32 + randhash + entstr).digest()) # reseed return privkey
def randomKey(entropy): """ 256 bit number from equally strong urandom, user entropy, and timer parts """ if entropy.bit_length() < 250: print('Insufficient entropy parameter to generate key') return False from random import SystemRandom osrndi = SystemRandom() entstr = enc.encode(entropy, 16) + enc.encode(osrndi.getrandbits(512), 256) + str(clockrnd()) osrnd = SystemRandom(entstr) privkey = 0 while privkey < 1 or privkey > elip.N: privkey = enc.decode( hashlib.sha256(enc.encode(osrnd.getrandbits(512), 256)).digest(), 256) ^ osrnd.getrandbits(256) for lbit in xrange(clockrnd() % 64 + 64): clockstr = hex(clockrnd()) + str(clockrnd()) + entstr # Slice a moving 256 bit window out of SHA512 clock32 = hashlib.sha512(clockstr).digest()[1 + (lbit % 29):33 + (lbit % 29)] randhash = hashlib.sha512( enc.encode(osrnd.getrandbits(512), 256)).digest()[0 + (lbit % 31):32 + (lbit % 31)] privkey ^= enc.decode(randhash, 256) ^ enc.decode( clock32, 256) ^ osrndi.getrandbits(256) osrnd = SystemRandom( hashlib.sha512(clock32 + randhash + entstr).digest()) # reseed return privkey
def createPrime(bits): i = 2 rand = SystemRandom() prime = rand.getrandbits(bits) while i <= sqrt(prime): if prime % i == 0: i = 1 prime = rand.getrandbits(bits) i += 1 return prime
def stealth_generate(filename): #Check to see if file is valid and does not already exist if type(filename) != str or len(filename) == 0: print("Stealth Address Generation Failed!") print("Please enter valid filename!") return if os.path.exists(filename): print("Stealth Address Generation Failed!") print("File \"" + filename + "\" already exists!") return #Get password for new keypair password = getpass() #Generate private keys print("Generating stealth address key pair...", end="") rng = SystemRandom() scan_key = (rng.getrandbits(256) % secp256k1.N).to_bytes(32, "big") pub_scan_key = secp256k1.privtopub(scan_key) js_scan = create_keyfile_json(scan_key, bytes(password, 'utf')) del scan_key spend_key = (rng.getrandbits(256) % secp256k1.N).to_bytes(32, "big") pub_spend_key = secp256k1.privtopub(spend_key) js_spend = create_keyfile_json(spend_key, bytes(password, 'utf')) del spend_key del password #Calculate Stealth Address and write to file with key pairs stealth_address = int.from_bytes( GetStealthAddressFromKeys(pub_scan_key, pub_spend_key), 'big') print("DONE!") print("New Stealth Address: " + hex(stealth_address)) print("Writing keystore file \"" + filename + "\"...", end="") with open(filename, mode='w') as file: js = "{\"stealth_address\":\"" + hex(stealth_address) + "\"," js += "\"scan_key\":" file.write(js) json.dump(js_scan, file) js = ",\"spend_key\":" file.write(js) json.dump(js_spend, file) js = "}" file.write(js) print("Done!")
def getPrime(bits): i = 2 rand = SystemRandom() prime = rand.getrandbits(bits) primesqrt = sqrt(prime) while i <= primesqrt: if prime % i == 0: i = 1 prime = rand.getrandbits(bits) primesqrt = sqrt(prime) i += 1 return prime
def getRandom(count=1): from random import SystemRandom sr = SystemRandom() if (count == 1): out = sr.getrandbits(256) else: out = [] for i in range(0, count): out = out + [sr.getrandbits(256)] return out
class chall: def __init__(self, size): self.rnd = SystemRandom() self.size = size def get_key(self): p = next_prime(self.rnd.getrandbits(self.size // 2)) q = next_prime(self.rnd.getrandbits(self.size // 2)) e = 0x10001 n = p * q phi = (p - 1) * (q - 1) d_p = inverse(e, p - 1) d_q = inverse(e, q - 1) inv_q = inverse(q, p) pubkey = (n, e) privkey = (p, q, d_p, d_q, inv_q) return (pubkey, privkey) def sign(self, msg, privkey): p, q, d_p, d_q, inv_q = privkey s_p = pow(msg, d_p, p) s_q = pow(msg, d_q, q) s = s_q + q * ((inv_q * (s_p - s_q)) % p) return s def verify(self, sgn, pubkey, target): n, e = pubkey return sgn == pow(target, e, n)
def __init__(self, platform): self.intro = ModuleDoc("""Test for bitstream insertion of BRAM initialization contents""") platform.toolchain.attr_translate["KEEP"] = ("KEEP", "TRUE") platform.toolchain.attr_translate["DONT_TOUCH"] = ("DONT_TOUCH", "TRUE") import binascii self.address = CSRStorage(8, name="address", description="address for ROM") self.data = CSRStatus(32, name="data", description="data from ROM") rng = SystemRandom() with open("rom.db", "w") as f: for bit in range(0,32): lutsel = Signal(4) for lut in range(4): if lut == 0: lutname = 'A' elif lut == 1: lutname = 'B' elif lut == 2: lutname = 'C' else: lutname = 'D' romval = rng.getrandbits(64) # print("rom bit ", str(bit), lutname, ": ", binascii.hexlify(romval.to_bytes(8, byteorder='big'))) rom_name = "KEYROM" + str(bit) + lutname # X36Y99 and counting down if bit % 2 == 0: platform.toolchain.attr_translate[rom_name] = ("LOC", "SLICE_X36Y" + str(50 + bit // 2)) else: platform.toolchain.attr_translate[rom_name] = ("LOC", "SLICE_X37Y" + str(50 + bit // 2)) platform.toolchain.attr_translate[rom_name + 'BEL'] = ("BEL", lutname + '6LUT') platform.toolchain.attr_translate[rom_name + 'LOCK'] = ( "LOCK_PINS", "I5:A6, I4:A5, I3:A4, I2:A3, I1:A2, I0:A1" ) self.specials += [ Instance( "LUT6", name=rom_name, # p_INIT=0x0000000000000000000000000000000000000000000000000000000000000000, p_INIT=romval, i_I0= self.address.storage[0], i_I1= self.address.storage[1], i_I2= self.address.storage[2], i_I3= self.address.storage[3], i_I4= self.address.storage[4], i_I5= self.address.storage[5], o_O= lutsel[lut], attr=("KEEP", "DONT_TOUCH", rom_name, rom_name + 'BEL', rom_name + 'LOCK') ) ] # record the ROM LUT locations in a DB and annotate the initial random value given f.write("KEYROM " + str(bit) + ' ' + lutname + ' ' + platform.toolchain.attr_translate[rom_name][1] + ' ' + str(binascii.hexlify(romval.to_bytes(8, byteorder='big'))) + '\n') self.comb += [ If( self.address.storage[6:] == 0, self.data.status[bit].eq(lutsel[2])) .Elif(self.address.storage[6:] == 1, self.data.status[bit].eq(lutsel[3])) .Elif(self.address.storage[6:] == 2, self.data.status[bit].eq(lutsel[0])) .Else(self.data.status[bit].eq(lutsel[1])) ]
def gen_temp_key(): # Generate a temporary key rand = SystemRandom() extra_chars = rand.choice([b'oS', b'pR', b'aZ', b'kI', b'eV', b'ml']) bits = rand.getrandbits(256) digest = sha256(str(bits).encode()).digest() return b64encode(digest, extra_chars)
def create_auth_key_test(connection, loop): from random import SystemRandom rand = SystemRandom() req_pq = scheme.req_pq(nonce=rand.getrandbits(128)) print(req_pq) yield from connection.send_insecure_message(req_pq) response = yield from connection.get_ingress() resPQ = response.get_message() print(resPQ)
def des3_encrypt(self): rand = SystemRandom() iv = rand.getrandbits(64) encryptor = self._make_des3_encryptor(self.key, iv) pad_len = 8 - len(self.data) % 8 #length of padding padding = chr(pad_len) * pad_len #PKCS5 padding content self.data += padding return encryptor.encrypt(self.data), iv
def create_random_totp_secret(secret_length: int = 72) -> bytes: """ Generate a random TOTP secret :param int secret_length: How long should the secret be? :rtype: bytes :returns: A random secret """ random = SystemRandom() return bytes(random.getrandbits(8) for _ in range(secret_length))
def __init__(self, state=None, seq=DEFAULT_SEQUENCE): ''' Initialize a new PCGRandom engine. If no seed is specified use urandom and if no sequene is specified use an arbitrary sequece ''' self._rng_state = ffi.new("pcg32_random_t*"); #If the state is none then get a random state from system entropy if state == None: system_random = SystemRandom() state = system_random.getrandbits(64) c_interface.pcg32_srandom_r(self._rng_state, state, seq)
def __init__(self, state=None, seq=DEFAULT_SEQUENCE): ''' Initialize a new PCGRandom engine. If no seed is specified use urandom and if no sequene is specified use an arbitrary sequece ''' self._rng_state = ffi.new("pcg32_random_t*") #If the state is none then get a random state from system entropy if state == None: system_random = SystemRandom() state = system_random.getrandbits(64) c_interface.pcg32_srandom_r(self._rng_state, state, seq)
def __init__(self, reproduceable=False): self.intro = ModuleDoc("""Place and route seed. Set to a fixed number for reproduceable builds. Use a random number or your own number if you are paranoid about hardware implants that target fixed locations within the FPGA.""") if reproduceable: seed_reset = "4" # chosen by fair dice roll. guaranteed to be random. else: rng = SystemRandom() seed_reset = rng.getrandbits(64) self.seed = CSRStatus(64, name="seed", description="Seed used for the build", reset=seed_reset)
class TRNG(): def __init__(self): self._rng = SystemRandom() def make_nonce(self, size): noncefmt = '{0:0' + str(size) / 4 + 'x}' nonce = self._rng.getrandbits(size) return noncefmt.format(nonce) def choose_index(max): SystemRandom().randint(1, max)
def keygen(cls, p, q, g): N = q.bit_length() L = p.bit_length() assert N % 8 == 0 rand = SystemRandom() c = rand.getrandbits(N + 64) x = (c % (q - 1)) + 1 assert 1 <= x and x <= q - 1 y = modexp(g, x, p) return x, y
def CreateStealthTx(pub_scan_key, pub_spend_key): from random import SystemRandom rnd = SystemRandom() r = rnd.getrandbits(256) R = CompressPoint(curve.multiply(curve.G, r)) ss = GetSharedSecret(pub_scan_key, r) addr = GetAddrFromSharedSecret(ss, pub_spend_key) R = hex(int.from_bytes(R, 'big')) addr = hex(int.from_bytes(addr, 'big')) return R, addr
def create_auth_key(self): from random import SystemRandom rand = SystemRandom() req_pq = scheme.req_pq(nonce=rand.getrandbits(128)) log.debug(req_pq) yield from self.connection.send_insecure_message(req_pq) response = yield from self.connection.get_ingress() resPQ = response.get_message() log.debug(resPQ) pq = int.from_bytes(resPQ.pq.data, 'big') p, q = prime.primefactors(pq, True)
def probable_prime(k, b=1000): success = False n = 0 rand = SystemRandom() while not success: divisible = True while divisible: # We force the first and last bits to be set to 1 # Thus we can ensure to have an odd number on k bits n = int('1' + bin(rand.getrandbits(k - 2))[2:] + '1', 2) divisible = trial_division(n, b) if rabin_miller(n): success = True return n
def test_varint(self): from .varint import encode_stream, decode_stream from random import SystemRandom from io import BytesIO random = SystemRandom() enb = BytesIO() bits = (8, 4 * 8, 444 * 8, 4444 * 8) ints = [random.getrandbits(b) for b in bits] for i in ints: encode_stream(enb, i) deb = BytesIO(enb.getvalue()) for i in ints: j = decode_stream(deb) self.assertEqual(i, j) self.assertEqual(deb.read(), b"")
class NUID: """ NUID is an implementation of the approach for fast generation of unique identifiers used for inboxes in NATS. """ def __init__(self): self._srand = SystemRandom() self._prand = Random(self._srand.randint(0, MaxInt)) self._seq = self._prand.randint(0, MAX_SEQ) self._inc = MIN_INC + self._prand.randint(0, INC) self._prefix = b'' self.randomize_prefix() def next(self): self._seq += self._inc if self._seq >= MAX_SEQ: self.randomize_prefix() self.reset_sequential() l = self._seq prefix = self._prefix[:] def _next(): nonlocal l a = DIGITS[int(l) % BASE] l /= BASE return a suffix = bytearray(_next() for i in range(SEQ_LENGTH)) prefix.extend(suffix) return prefix def randomize_prefix(self): random_bytes = ( self._srand.getrandbits(8) for i in range(PREFIX_LENGTH) ) self._prefix = bytearray(DIGITS[c % BASE] for c in random_bytes) def reset_sequential(self): self._seq = self._prand.randint(0, MAX_SEQ) self._inc = MIN_INC + self._prand.randint(0, INC)
class NUID(object): """ NUID is an implementation of the approach for fast generation of unique identifiers used for inboxes in NATS. """ def __init__(self): self._srand = SystemRandom() self._prand = Random(self._srand.randint(0, MaxInt)) self._seq = self._prand.randint(0, MAX_SEQ) self._inc = MIN_INC + self._prand.randint(0, INC) self._prefix = b'' self.randomize_prefix() def next(self): self._seq += self._inc if self._seq >= MAX_SEQ: self.randomize_prefix() self.reset_sequential() prefix = self._prefix[:] def _next(): a = DIGITS[int(_next.l) % BASE] _next.l /= BASE return a _next.l = self._seq suffix = bytearray(_next() for i in range(SEQ_LENGTH)) prefix.extend(suffix) return prefix def randomize_prefix(self): random_bytes = (self._srand.getrandbits(8) for i in range(PREFIX_LENGTH)) self._prefix = bytearray(DIGITS[c % BASE] for c in random_bytes) def reset_sequential(self): self._seq = self._prand.randint(0, MAX_SEQ) self._inc = MIN_INC + self._prand.randint(0, INC)
def run_test_bits(self, r, level): """Test based on Norm distribution Xi ~ 1, or -1 with equal possibility X = (X1 + ... + Xn) / n E(Xi) = 0 E(Xi^2)= 1 Var(X) = Var(Xi)/n = 1 / n set n = 10000 EX = 0 Var(X) = 0.0001 """ sum = 0 n = 1000 r2 = SystemRandom() r.seed(r2.getrandbits(1024)) sigma = 1 / sqrt(n) for i in range(n): sum = sum + r.getrandbits(1) diff = abs(n - 2 * sum) / n self._logger.debug('diff is {0} sigma'.format(diff / sigma)) # 2 sigma , p = 95.45% # 3 sigma , p = 99.73% self.assertEqual(diff < level * sigma, True)
def run_test_bits(self, r, level): """Test based on Norm distribution Xi ~ 1, or -1 with equal possibility X = (X1 + ... + Xn) / n E(Xi) = 0 E(Xi^2)= 1 Var(X) = Var(Xi)/n = 1 / n set n = 10000 EX = 0 Var(X) = 0.0001 """ sum = 0 n = 1000 r2 = SystemRandom() r.seed(r2.getrandbits(1024)) sigma = 1 / sqrt(n) for i in range(n): sum = sum + r.getrandbits(1) diff = abs(n - 2 * sum) / n self._logger.debug('diff is {0} sigma'.format(diff/sigma)) # 2 sigma , p = 95.45% # 3 sigma , p = 99.73% self.assertEqual(diff < level * sigma, True)
def main(): bloom = ScalableBloomFilter(mode=ScalableBloomFilter.SMALL_SET_GROWTH) random = SystemRandom() print('Sample hashes:') for i in range(0, 10000): random_hash = hex(random.getrandbits(256)) bloom.add(random_hash) if i % 1000 == 0: print(random_hash) print(f'~{len(bloom)} hashes added to bloom filter.') print() try: while True: user_hash = input('Enter hash to check: ') if not user_hash: break print(user_hash in bloom) except (EOFError, KeyboardInterrupt): pass
# SOFTWARE. # Python2.5+ from flask import Flask, request, session, g, redirect, url_for, \ abort, render_template, flash from random import SystemRandom from base64 import b64encode import runner rng = SystemRandom() # configuration DEBUG = False SECRET_KEY = b64encode(str(rng.getrandbits(256))) USERNAME = b64encode(str(rng.getrandbits(256))) PASSWORD = b64encode(str(rng.getrandbits(256))) app = Flask(__name__) app.config.from_object(__name__) @app.route('/', methods=['GET']) def classify_upload(): if request.method == 'GET': filename = request.args.get('fileid') or None if filename is not None: return runner.class_img(filename)
class ActionLog: """ The pySUMO action log. The SyntaxController queues a new log entry before every operation that makes changes to an Ontology, if the change is successful it OKs the entry in the log queue and the entry is written out. Log entries that are not OKed time out and are removed from the queue. Variables: - log_io: The io object for this log. - queue: A queue of actions that have not yet successfully completed. - actionlog: A list of actions that have completed successfully. - redolog: A list of actions that have been undone successfully. - current: The current state of the Ontology. Methods: - queue_log: Create a log entry and append it to the log queue. - ok_log_item: Move log entry from log queue to actual log. - undo: Undoes the last action. - redo: Redoes the last undone action. """ def __init__(self, name, path=None): """ Initializes the action log and instantiates variables. """ self.log_io = LogIO(name, path) self.current, self.actionlog, self.redolog = self.log_io.read() self.queue = (None, None) self._rand = SystemRandom() def __getstate__(self): state = self.__dict__.copy() del state['_rand'] return state def __setstate__(self, state): self.__dict__.update(state) self._rand = SystemRandom() def _rand_lognum(self): """ Returns a log entry number that is not already in the queue. """ lognum = self._rand.getrandbits(32) return lognum if lognum not in self.queue else self._rand_lognum() def queue_log(self, data): """ Create a log entry and queue it for addition to self.actionlog. Args: - data: the data to be placed in the log Returns: - int. The log_queue_ok_num """ num = self._rand_lognum() self.queue = (num, data) return num def ok_log_item(self, log_queue_ok_num): """ Appends the item in self.queue with log_queue_ok_num to self.actionlog and calls self.log_io.append_write_queue on it. Args: - log_queue_ok_num: the number of the queue item to okay Raises: - KeyError """ num, entry = self.queue if not num == log_queue_ok_num: raise KeyError(num) if self.current is None: self.current = BytesIO() diff = self.log_io.diff(self.current, entry) self.current = self.log_io.redo(self.current, diff) self.actionlog.append(diff) self.redolog.clear() self.log_io.clear('redo') self.queue = (None, None) def undo(self): """ Undoes the last action and appends it to self.redolog. """ self.log_io.flush_write_queues(None, None) try: diff = self.actionlog.pop() except IndexError: return self.current self.current = self.log_io.undo(self.current, diff) self.redolog.append(diff) return self.current def redo(self): """ Redoes the last undone action, appends it to self.undolog and removes it from self.redolog. """ self.log_io.flush_write_queues(None, None) try: diff = self.redolog.pop() except IndexError: return self.current self.current = self.log_io.redo(self.current, diff, clean=True) self.actionlog.append(diff) return self.current
import csv import cfg from random import SystemRandom from puf import Challenge from database import database device = database['1234'] rnd = SystemRandom() with open('outputs/1234.out.csv', 'w') as out: csvout = csv.writer(out) for _ in range(2048): i = rnd.getrandbits(cfg.RSP_LEN) c = Challenge(('{0:0' + str(cfg.RSP_LEN) + 'b}') .format(i)) r = device.f(c) csvout.writerow(list(c.to01()) + [r])
numberPoints = 115792089237316195423570985008687907852837564279074904382605163141518161494337 print("The order of E is: ", numberPoints) print("-" * 80) print("The point we're using is:") P = ( int("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16), int("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)) print(P) print("The order of this point is:") print(numberPoints) print("The order of the point is prime.") b = rand.getrandbits(256) % numberPoints a = rand.getrandbits(256) % numberPoints bP = ec.multiply(b, P) aP = ec.multiply(a, P) abP = ec.multiply(a * b, P) print("Alice's private key is: ", format(a, 'x')) print("Alice's public key is: ({:x}, {:x} ) ".format(aP[0], aP[1])) print("Bob's private key is: ", format(b, 'x')) print("Bob's public key is: ({:x}, {:x} ) ".format(bP[0], bP[1])) print("The exchanged value is: ({:x}, {:x} ) ".format(abP[0], abP[1])) print("Alice, enter your message to be encrypted: \n") message_in = '\n'.join(iter(input, "")) print("The encrypted message is:") encrypted = encrypt(message_in, str(abP[0]))
def handler_hash(args): rand = SystemRandom() salt = rand.getrandbits(16) salt_str = format(salt, "x") hash_str = hash_password(salt_str, args.password) print(salt_str + " " + hash_str)
def _create_hash(): rand = SystemRandom() return hashlib.sha512(str(rand.getrandbits(512))).hexdigest()
def __init__(self, platform): self.intro = ModuleDoc( """Bitstream-patchable key ROM set for keys that are "baked in" to the FPGA image""" ) platform.toolchain.attr_translate["KEEP"] = ("KEEP", "TRUE") platform.toolchain.attr_translate["DONT_TOUCH"] = ("DONT_TOUCH", "TRUE") import binascii self.address = CSRStorage(8, name="address", description="address for ROM") self.data = CSRStatus(32, name="data", description="data from ROM") self.lockaddr = CSRStorage( 8, name="lockaddr", description= "address of the word to lock. Address locked on write, and cannot be undone." ) self.lockstat = CSRStatus( 1, name="lockstat", description= "If set, the requested address word is locked and will always return 0." ) lockmem = Memory(1, 256, init=[0] * 256) self.specials += lockmem self.specials.lockrd = lockmem.get_port(write_capable=False, mode=WRITE_FIRST, async_read=True) self.specials.lockwr = lockmem.get_port(write_capable=True, mode=WRITE_FIRST) self.comb += [ self.lockwr.adr.eq(self.lockaddr.storage), self.lockwr.dat_w.eq(1), self.lockwr.we.eq(self.lockaddr.re), ] rawdata = Signal(32) rng = SystemRandom() with open("rom.db", "w") as f: for bit in range(0, 32): lutsel = Signal(4) for lut in range(4): if lut == 0: lutname = 'A' elif lut == 1: lutname = 'B' elif lut == 2: lutname = 'C' else: lutname = 'D' romval = rng.getrandbits(64) # print("rom bit ", str(bit), lutname, ": ", binascii.hexlify(romval.to_bytes(8, byteorder='big'))) rom_name = "KEYROM" + str(bit) + lutname # X36Y99 and counting down if bit % 2 == 0: platform.toolchain.attr_translate[rom_name] = ( "LOC", "SLICE_X36Y" + str(50 + bit // 2)) else: platform.toolchain.attr_translate[rom_name] = ( "LOC", "SLICE_X37Y" + str(50 + bit // 2)) platform.toolchain.attr_translate[rom_name + 'BEL'] = ("BEL", lutname + '6LUT') platform.toolchain.attr_translate[rom_name + 'LOCK'] = ( "LOCK_PINS", "I5:A6, I4:A5, I3:A4, I2:A3, I1:A2, I0:A1") self.specials += [ Instance( "LUT6", name=rom_name, # p_INIT=0x0000000000000000000000000000000000000000000000000000000000000000, p_INIT=romval, i_I0=self.address.storage[0], i_I1=self.address.storage[1], i_I2=self.address.storage[2], i_I3=self.address.storage[3], i_I4=self.address.storage[4], i_I5=self.address.storage[5], o_O=lutsel[lut], attr=("KEEP", "DONT_TOUCH", rom_name, rom_name + 'BEL', rom_name + 'LOCK')) ] # record the ROM LUT locations in a DB and annotate the initial random value given f.write("KEYROM " + str(bit) + ' ' + lutname + ' ' + platform.toolchain.attr_translate[rom_name][1] + ' ' + str( binascii.hexlify( romval.to_bytes(8, byteorder='big'))) + '\n') self.comb += [ If(self.address.storage[6:] == 0, rawdata[bit].eq(lutsel[2])).Elif( self.address.storage[6:] == 1, rawdata[bit].eq(lutsel[3])).Elif( self.address.storage[6:] == 2, rawdata[bit].eq( lutsel[0])).Else(rawdata[bit].eq(lutsel[1])) ] allow_read = Signal() self.comb += [ allow_read.eq(~self.lockrd.dat_r), self.lockrd.adr.eq(self.address.storage), ] self.sync += [ If( allow_read, self.data.status.eq(rawdata), ).Else(self.data.status.eq(0), ), self.lockstat.status.eq(allow_read) ] platform.add_platform_command("create_pblock keyrom") platform.add_platform_command( 'resize_pblock [get_pblocks keyrom] -add ' + '{{SLICE_X36Y50:SLICE_X37Y65}}') #platform.add_platform_command("set_property CONTAIN_ROUTING true [get_pblocks keyrom]") # should be fine to mingle the routing for this pblock platform.add_platform_command( "add_cells_to_pblock [get_pblocks keyrom] [get_cells KEYROM*]")
class Datacenter: DATA_VERSION = 4 DCs = [ "149.154.175.50", "149.154.167.51", "149.154.175.100", "149.154.167.91", "149.154.171.5", ] DCs_ipv6 = [ "2001:b28:f23d:f001::a", "2001:67c:4e8:f002::a", "2001:b28:f23d:f003::a", "2001:67c:4e8:f004::a", "2001:b28:f23f:f005::a", ] DCs_test = [ "149.154.175.10", "149.154.167.40", "149.154.175.117", ] DCs_test_ipv6 = [ "2001:b28:f23d:f001::e", "2001:67c:4e8:f002::e", "2001:b28:f23d:f003::e", ] def __init__(self, dc_id, ipaddr, port, rsa_key): self.random = SystemRandom() self.session_id = None self.resPQ = None self.p_q_inner_data = None self.server_DH_params = None self.server_DH_inner_data = None self.client_DH_inner_data = None tmp_aes_key = None tmp_aes_iv = None self.set_client_DH_params_answer = None self.ipaddr = ipaddr self.port = port self.datacenter_id = dc_id self.auth_server_salt_set = [] self._socket = socket() self._socket.connect((ipaddr, port)) self._socket.settimeout(5.0) self.socket = self._socket.makefile(mode='rwb', buffering=0) self.message_queue = [] self.last_message_id = 0 self.timedelta = 0 self.number = 0 self.authorized = False self.auth_key = MTProtoAuthKey() self.server_salt = None self.server_time = None self.MAX_RETRY = 5 self.AUTH_MAX_RETRY = 5 self.rsa_key = rsa_key self.b = self.random.getrandbits(2048) # Handshake self.create_auth_key() # self.test_api() def test_api(self): getNearestDc = tl.help_getNearestDc() print(getNearestDc) self.send_encrypted_message(getNearestDc.to_bytes()) self.recv_encrypted_message() # nearestDc = tl.NearestDc(self.recv_plaintext_message(True)) # print(nearestDc) """ g = public (prime) base, known to Alice, Bob, and Eve. g = 5 p = public (prime) number, known to Alice, Bob, and Eve. p = 23 a = Alice's private key, known only to Alice. a = 6 b = Bob's private key known only to Bob. b = 15 """ def _req_pq(self): nonce = tl.int128_c(self.random.getrandbits(128)) request = tl.req_pq(nonce) # raise Exception() self.send_plaintext_message(request.to_bytes()) res_pq = tl.ResPQ.from_stream(BytesIO(self.recv_plaintext_message())) # print(res_pq, ...) raise Exception() assert nonce == res_pq.nonce return res_pq def _create_p_q_inner_data(self): pq = self.resPQ.pq.to_int('big') p, q = prime.primefactors(pq) if p > q: p, q = q, p assert p * q == pq and p < q p_string = tl.string_c.from_int(p, byteorder='big') q_string = tl.string_c.from_int(q, byteorder='big') new_nonce = tl.int256_c(self.random.getrandbits(256)) p_q_inner_data = tl.p_q_inner_data_c( pq=self.resPQ.pq, p=p_string, q=q_string, nonce=self.resPQ.nonce, server_nonce=self.resPQ.server_nonce, new_nonce=new_nonce) assert p_q_inner_data.nonce == self.resPQ.nonce return p_q_inner_data def _req_DH_params(self): key = RSA.importKey(self.rsa_key.strip()) public_key_fingerprint = self.resPQ.server_public_key_fingerprints[0] data = self.p_q_inner_data.to_boxed_bytes() sha_digest = SHA1(data) # get padding of random data to fill what is left after data and sha_digest random_bytes = os.urandom(255 - len(data) - len(sha_digest)) to_encrypt = sha_digest + data + random_bytes # encrypt cat of sha_digest, data, and padding encrypted_data = tl.string_c(key.encrypt( to_encrypt, 0)[0]) # rsa encrypt (key == RSA.key) # Presenting proof of work; Server authentication req_DH_params = tl.req_DH_params( nonce=self.p_q_inner_data.nonce, server_nonce=self.p_q_inner_data.server_nonce, p=self.p_q_inner_data.p, q=self.p_q_inner_data.q, public_key_fingerprint=public_key_fingerprint, encrypted_data=encrypted_data) self.send_plaintext_message(req_DH_params.to_bytes()) server_DH_params = tl.Server_DH_Params.from_stream( BytesIO(self.recv_plaintext_message())) assert server_DH_params.number == tl.server_DH_params_ok_c.number, "failed to get params" assert self.resPQ.nonce == server_DH_params.nonce assert self.resPQ.server_nonce == server_DH_params.server_nonce return server_DH_params def _create_tmp_aes_keys(self): tmp_aes_key = SHA1(self.p_q_inner_data.new_nonce.to_bytes() + self.server_DH_params.server_nonce.to_bytes()) tmp_aes_key += SHA1(self.server_DH_params.server_nonce.to_bytes() + self.p_q_inner_data.new_nonce.to_bytes())[:12] tmp_aes_iv = SHA1(self.server_DH_params.server_nonce.to_bytes() + self.p_q_inner_data.new_nonce.to_bytes())[12:20] tmp_aes_iv += SHA1(self.p_q_inner_data.new_nonce.to_bytes() + self.p_q_inner_data.new_nonce.to_bytes()) tmp_aes_iv += self.p_q_inner_data.new_nonce.to_bytes()[0:4] return tmp_aes_key, tmp_aes_iv def _decrypt_Server_DH_inner_data(self): answer_with_hash = crypt.ige_decrypt( self.server_DH_params.encrypted_answer, self.tmp_aes_key, self.tmp_aes_iv) answer = answer_with_hash[20:] # decrypted at this point server_DH_inner_data = tl.Server_DH_inner_data.from_stream( BytesIO(answer)) assert self.server_DH_params.nonce == server_DH_inner_data.nonce assert self.server_DH_params.server_nonce == server_DH_inner_data.server_nonce return server_DH_inner_data def _create_client_DH_inner_data(self): dh_prime = self.server_DH_inner_data.dh_prime.to_int(byteorder='big') g = self.server_DH_inner_data.g g_a = self.server_DH_inner_data.g_a.to_int(byteorder='big') server_time = self.server_DH_inner_data.server_time self.timedelta = server_time - time( ) # keep in mind delta is used somewhere later assert prime.isprime(dh_prime) retry_id = tl.long_c(0) b = self.b g_b = pow(g, b, dh_prime) g_b_str = tl.bytes_c.from_int(g_b, byteorder='big') client_DH_inner_data = tl.client_DH_inner_data_c( nonce=self.server_DH_inner_data.nonce, server_nonce=self.server_DH_inner_data.server_nonce, retry_id=retry_id, g_b=g_b_str) return client_DH_inner_data def create_auth_key(self): self.resPQ = self._req_pq() print(self.resPQ) self.p_q_inner_data = self._create_p_q_inner_data() print(self.p_q_inner_data) self.server_DH_params = self._req_DH_params() print(self.server_DH_params) self.tmp_aes_key, self.tmp_aes_iv = self._create_tmp_aes_keys() self.server_DH_inner_data = self._decrypt_Server_DH_inner_data() print(self.server_DH_inner_data) self.client_DH_inner_data = self._create_client_DH_inner_data() print(self.client_DH_inner_data) data = self.client_DH_inner_data.to_boxed_bytes() data_with_sha = SHA1(data) + data data_with_sha_padded = data_with_sha + os.urandom( -len(data_with_sha) % 16) encrypted_data = crypt.ige_encrypt(data_with_sha_padded, self.tmp_aes_key, self.tmp_aes_iv) g_a = self.server_DH_inner_data.g_a.to_int(byteorder='big') dh_prime = self.server_DH_inner_data.dh_prime.to_int(byteorder='big') b = self.b new_nonce = self.p_q_inner_data.new_nonce.to_bytes() for i in range( 1, self.AUTH_MAX_RETRY): # retry when dh_gen_retry or dh_gen_fail set_client_DH_params = tl.set_client_DH_params( nonce=self.resPQ.nonce, server_nonce=self.resPQ.server_nonce, encrypted_data=tl.bytes_c(encrypted_data)) self.send_plaintext_message(set_client_DH_params.to_bytes()) self.set_client_DH_params_answer = tl.Set_client_DH_params_answer.from_stream( BytesIO(self.recv_plaintext_message())) set_client_DH_params_answer = self.set_client_DH_params_answer # print set_client_DH_params_answer auth_key = pow(g_a, b, dh_prime) auth_key_str = long_to_bytes(auth_key) auth_key_sha = SHA1(auth_key_str) auth_key_aux_hash = auth_key_sha[:8] new_nonce_hash1 = SHA1(new_nonce + b'\x01' + auth_key_aux_hash)[-16:] new_nonce_hash2 = SHA1(new_nonce + b'\x02' + auth_key_aux_hash)[-16:] new_nonce_hash3 = SHA1(new_nonce + b'\x03' + auth_key_aux_hash)[-16:] assert set_client_DH_params_answer.nonce == self.resPQ.nonce assert set_client_DH_params_answer.server_nonce == self.resPQ.server_nonce if set_client_DH_params_answer.number == tl.dh_gen_ok_c.number: print(set_client_DH_params_answer.new_nonce_hash1, new_nonce_hash1) assert set_client_DH_params_answer.new_nonce_hash1.to_bytes( ) == new_nonce_hash1 print("Diffie Hellman key exchange processed successfully") self.server_salt = strxor( new_nonce[0:8], self.resPQ.server_nonce.to_bytes()[0:8]) self.auth_key.set_key(auth_key_str) print("Auth key generated") return "Auth Ok" elif set_client_DH_params_answer.number == tl.dh_gen_retry_c.number: assert set_client_DH_params_answer.new_nonce_hash2.to_bytes( ) == new_nonce_hash2 print("Retry Auth") elif set_client_DH_params_answer.status == tl.dh_gen_fail_c.number: assert set_client_DH_params_answer.new_nonce_hash3.to_bytes( ) == new_nonce_hash3 print("Auth Failed") raise Exception("Auth Failed") else: raise Exception("Response Error") def generate_message_id(self): msg_id = int(time() * 2**32) if self.last_message_id > msg_id: msg_id = self.last_message_id + 1 while msg_id % 4 is not 0: msg_id += 1 return msg_id def send_plaintext_message( self, message_data): # package message, not chat message msg = MTProtoUnencryptedMessage.new(self.generate_message_id(), message_data) self.send_tcp_message(msg) def recv_plaintext_message(self): tcp_msg = self.recv_tcp_message() msg = MTProtoUnencryptedMessage.from_bytes(tcp_msg.payload) if msg.is_encrypted(): raise ValueError('did not get a plaintext message') return msg.message_data def send_encrypted_message(self, message_data): """ Ecrypted Message: auth_key_id:int64 | msg_key:int128 | encrypted_data:bytes Encrypted Message: encrypted_data salt:int64 | session_id:int64 | message_id:int64 | seq_no:int32 | message_data_length:int32 | message_data:bytes | padding 0..15:bytes """ if self.session_id is None: self.session_id = self.random.getrandbits(64).to_bytes(8, 'little') msg = MTProtoEncryptedMessage.new( int.from_bytes(self.server_salt, 'little'), int.from_bytes(self.session_id, 'little'), self.generate_message_id(), 1, message_data) msg = msg.encrypt(self.auth_key) self.send_tcp_message(msg) def recv_encrypted_message(self): tcp_msg = self.recv_tcp_message() msg = MTProtoEncryptedMessage.from_bytes(tcp_msg.payload) msg = msg.decrypt(self.auth_key) print('message_data:', to_hex(msg.encrypted_data.message_data)) """ at this point, message_data looks a lot like this: message_data: Msg container -> DCF8F173 Vector<%Message> num_items:int -> 02000000 %Message: message_id:long -> 01D40F39 3BBFA055 seq_no:int -> 01000000 bytes:int -> 1C000000 body:Object -> new_session_created -> 0809C29E first_msg_id:long -> 00C8A02B 3BBFA055 unique_id:long -> 1A1D5711 00A96EC3 server_salt:long -> 74EEA560 D1AB64E3 %Message: message_id -> 01541139 3BBFA055 seq_no:int -> 02000000 bytes:int -> 14000000 body:Object -> msg_acks -> 59B4D662 Vector<long> -> 15C4B51C count -> 01000000 long -> 00C8A02B 3BBFA055 """ def send_tcp_message(self, mproto_message): tcp_msg = MTProtoTCPMessage.new(self.number, mproto_message) tcp_msg_data = tcp_msg.to_bytes() print(to_hex(tcp_msg_data)) self.socket.write(tcp_msg_data) self.number += 1 def recv_tcp_message(self): tcp_msg = MTProtoTCPMessage.from_stream(self.socket) if not tcp_msg.crc_ok(): raise ValueError('mproto_message checksum for tcp does not match') return tcp_msg def __del__(self): # cleanup self._socket.close()
def __init__(self, platform, address, data): platform.toolchain.attr_translate["KEEP"] = ("KEEP", "TRUE") platform.toolchain.attr_translate["DONT_TOUCH"] = ("DONT_TOUCH", "TRUE") self.address = address self.data = data rng = SystemRandom() with open("rom.db", "w") as f: for bit in range(0, 32): lutsel = Signal(4) for lut in range(4): if lut == 0: lutname = 'A' elif lut == 1: lutname = 'B' elif lut == 2: lutname = 'C' else: lutname = 'D' romval = rng.getrandbits(64) # print("rom bit ", str(bit), lutname, ": ", binascii.hexlify(romval.to_bytes(8, byteorder='big'))) rom_name = "KEYROM" + str(bit) + lutname if bit % 2 == 0: platform.toolchain.attr_translate[rom_name] = ( "LOC", "SLICE_X36Y" + str(50 + bit // 2)) else: platform.toolchain.attr_translate[rom_name] = ( "LOC", "SLICE_X37Y" + str(50 + bit // 2)) platform.toolchain.attr_translate[rom_name + 'BEL'] = ("BEL", lutname + '6LUT') platform.toolchain.attr_translate[rom_name + 'LOCK'] = ( "LOCK_PINS", "I5:A6, I4:A5, I3:A4, I2:A3, I1:A2, I0:A1") self.specials += [ Instance( "LUT6", name=rom_name, # p_INIT=0x0000000000000000000000000000000000000000000000000000000000000000, p_INIT=romval, i_I0=self.address[0], i_I1=self.address[1], i_I2=self.address[2], i_I3=self.address[3], i_I4=self.address[4], i_I5=self.address[5], o_O=lutsel[lut], attr=("KEEP", "DONT_TOUCH", rom_name, rom_name + 'BEL', rom_name + 'LOCK')) # X36Y99 and counting down ] f.write("KEYROM " + str(bit) + ' ' + lutname + ' ' + platform.toolchain.attr_translate[rom_name][1] + ' ' + str( binascii.hexlify( romval.to_bytes(8, byteorder='big'))) + '\n') self.comb += [ If(self.address[6:] == 0, self.data[bit].eq(lutsel[2])).Elif( self.address[6:] == 1, self.data[bit].eq(lutsel[3])).Elif( self.address[6:] == 2, self.data[bit].eq(lutsel[0])).Else( self.data[bit].eq(lutsel[1])) ]
class Datacenter: DATA_VERSION = 4 DCs = [ "149.154.175.50", "149.154.167.51", "149.154.175.100", "149.154.167.91", "149.154.171.5", ] DCs_ipv6 = [ "2001:b28:f23d:f001::a", "2001:67c:4e8:f002::a", "2001:b28:f23d:f003::a", "2001:67c:4e8:f004::a", "2001:b28:f23f:f005::a", ] DCs_test = [ "149.154.175.10", "149.154.167.40", "149.154.175.117", ] DCs_test_ipv6 = [ "2001:b28:f23d:f001::e", "2001:67c:4e8:f002::e", "2001:b28:f23d:f003::e", ] def __init__(self, dc_id, ipaddr, port, rsa_key): self.random = SystemRandom() self.session_id = None self.resPQ = None self.p_q_inner_data = None self.server_DH_params = None self.server_DH_inner_data = None self.client_DH_inner_data = None tmp_aes_key = None tmp_aes_iv = None self.set_client_DH_params_answer = None self.ipaddr = ipaddr self.port = port self.datacenter_id = dc_id self.auth_server_salt_set = [] self._socket = socket() self._socket.connect((ipaddr, port)) self._socket.settimeout(5.0) self.socket = self._socket.makefile(mode='rwb', buffering=0) self.message_queue = [] self.last_msg_id = 0 self.timedelta = 0 self.number = 0 self.authorized = False self.auth_key = MTProtoAuthKey() self.server_salt = None self.server_time = None self.MAX_RETRY = 5 self.AUTH_MAX_RETRY = 5 self.rsa_key = rsa_key self.b = self.random.getrandbits(2048) # Handshake self.create_auth_key() # self.test_api() def test_api(self): getNearestDc = tl.help_getNearestDc() print(getNearestDc) self.send_encrypted_message(getNearestDc.to_bytes()) self.recv_encrypted_message() # nearestDc = tl.NearestDc(self.recv_plaintext_message(True)) # print(nearestDc) """ g = public (prime) base, known to Alice, Bob, and Eve. g = 5 p = public (prime) number, known to Alice, Bob, and Eve. p = 23 a = Alice's private key, known only to Alice. a = 6 b = Bob's private key known only to Bob. b = 15 """ def _req_pq(self): nonce = tl.int128_c(self.random.getrandbits(128)) request = tl.req_pq(nonce) # raise Exception() self.send_plaintext_message(request.to_bytes()) res_pq = tl.ResPQ.from_stream(BytesIO(self.recv_plaintext_message())) # print(res_pq, ...) raise Exception() assert nonce == res_pq.nonce return res_pq def _create_p_q_inner_data(self): pq = self.resPQ.pq.to_int('big') p, q = prime.primefactors(pq) if p > q: p, q = q, p assert p * q == pq and p < q p_string = tl.string_c.from_int(p, byteorder='big') q_string = tl.string_c.from_int(q, byteorder='big') new_nonce = tl.int256_c(self.random.getrandbits(256)) p_q_inner_data = tl.p_q_inner_data_c(pq=self.resPQ.pq, p=p_string, q=q_string, nonce=self.resPQ.nonce, server_nonce=self.resPQ.server_nonce, new_nonce=new_nonce) assert p_q_inner_data.nonce == self.resPQ.nonce return p_q_inner_data def _req_DH_params(self): key = RSA.importKey(self.rsa_key.strip()) public_key_fingerprint = self.resPQ.server_public_key_fingerprints[0] data = self.p_q_inner_data.to_boxed_bytes() sha_digest = SHA1(data) # get padding of random data to fill what is left after data and sha_digest random_bytes = os.urandom(255 - len(data) - len(sha_digest)) to_encrypt = sha_digest + data + random_bytes # encrypt cat of sha_digest, data, and padding encrypted_data = tl.string_c(key.encrypt(to_encrypt, 0)[0]) # rsa encrypt (key == RSA.key) # Presenting proof of work; Server authentication req_DH_params = tl.req_DH_params(nonce=self.p_q_inner_data.nonce, server_nonce=self.p_q_inner_data.server_nonce, p=self.p_q_inner_data.p, q=self.p_q_inner_data.q, public_key_fingerprint=public_key_fingerprint, encrypted_data=encrypted_data) self.send_plaintext_message(req_DH_params.to_bytes()) server_DH_params = tl.Server_DH_Params.from_stream(BytesIO(self.recv_plaintext_message())) assert server_DH_params.number == tl.server_DH_params_ok_c.number, "failed to get params" assert self.resPQ.nonce == server_DH_params.nonce assert self.resPQ.server_nonce == server_DH_params.server_nonce return server_DH_params def _create_tmp_aes_keys(self): tmp_aes_key = SHA1(self.p_q_inner_data.new_nonce.to_bytes() + self.server_DH_params.server_nonce.to_bytes()) tmp_aes_key += SHA1(self.server_DH_params.server_nonce.to_bytes() + self.p_q_inner_data.new_nonce.to_bytes())[:12] tmp_aes_iv = SHA1(self.server_DH_params.server_nonce.to_bytes() + self.p_q_inner_data.new_nonce.to_bytes())[12:20] tmp_aes_iv += SHA1(self.p_q_inner_data.new_nonce.to_bytes() + self.p_q_inner_data.new_nonce.to_bytes()) tmp_aes_iv += self.p_q_inner_data.new_nonce.to_bytes()[0:4] return tmp_aes_key, tmp_aes_iv def _decrypt_Server_DH_inner_data(self): answer_with_hash = crypt.ige_decrypt(self.server_DH_params.encrypted_answer, self.tmp_aes_key, self.tmp_aes_iv) answer = answer_with_hash[20:] # decrypted at this point server_DH_inner_data = tl.Server_DH_inner_data.from_stream(BytesIO(answer)) assert self.server_DH_params.nonce == server_DH_inner_data.nonce assert self.server_DH_params.server_nonce == server_DH_inner_data.server_nonce return server_DH_inner_data def _create_client_DH_inner_data(self): dh_prime = self.server_DH_inner_data.dh_prime.to_int(byteorder='big') g = self.server_DH_inner_data.g g_a = self.server_DH_inner_data.g_a.to_int(byteorder='big') server_time = self.server_DH_inner_data.server_time self.timedelta = server_time - time() # keep in mind delta is used somewhere later assert prime.isprime(dh_prime) retry_id = tl.long_c(0) b = self.b g_b = pow(g, b, dh_prime) g_b_str = tl.bytes_c.from_int(g_b, byteorder='big') client_DH_inner_data = tl.client_DH_inner_data_c( nonce=self.server_DH_inner_data.nonce, server_nonce=self.server_DH_inner_data.server_nonce, retry_id=retry_id, g_b=g_b_str) return client_DH_inner_data def create_auth_key(self): self.resPQ = self._req_pq() print(self.resPQ) self.p_q_inner_data = self._create_p_q_inner_data() print(self.p_q_inner_data) self.server_DH_params = self._req_DH_params() print(self.server_DH_params) self.tmp_aes_key, self.tmp_aes_iv = self._create_tmp_aes_keys() self.server_DH_inner_data = self._decrypt_Server_DH_inner_data() print(self.server_DH_inner_data) self.client_DH_inner_data = self._create_client_DH_inner_data() print(self.client_DH_inner_data) data = self.client_DH_inner_data.to_boxed_bytes() data_with_sha = SHA1(data) + data data_with_sha_padded = data_with_sha + os.urandom(-len(data_with_sha) % 16) encrypted_data = crypt.ige_encrypt(data_with_sha_padded, self.tmp_aes_key, self.tmp_aes_iv) g_a = self.server_DH_inner_data.g_a.to_int(byteorder='big') dh_prime = self.server_DH_inner_data.dh_prime.to_int(byteorder='big') b = self.b new_nonce = self.p_q_inner_data.new_nonce.to_bytes() for i in range(1, self.AUTH_MAX_RETRY): # retry when dh_gen_retry or dh_gen_fail set_client_DH_params = tl.set_client_DH_params( nonce=self.resPQ.nonce, server_nonce=self.resPQ.server_nonce, encrypted_data=tl.bytes_c(encrypted_data) ) self.send_plaintext_message(set_client_DH_params.to_bytes()) self.set_client_DH_params_answer = tl.Set_client_DH_params_answer.from_stream(BytesIO(self.recv_plaintext_message())) set_client_DH_params_answer = self.set_client_DH_params_answer # print set_client_DH_params_answer auth_key = pow(g_a, b, dh_prime) auth_key_str = long_to_bytes(auth_key) auth_key_sha = SHA1(auth_key_str) auth_key_aux_hash = auth_key_sha[:8] new_nonce_hash1 = SHA1(new_nonce+b'\x01'+auth_key_aux_hash)[-16:] new_nonce_hash2 = SHA1(new_nonce+b'\x02'+auth_key_aux_hash)[-16:] new_nonce_hash3 = SHA1(new_nonce+b'\x03'+auth_key_aux_hash)[-16:] assert set_client_DH_params_answer.nonce == self.resPQ.nonce assert set_client_DH_params_answer.server_nonce == self.resPQ.server_nonce if set_client_DH_params_answer.number == tl.dh_gen_ok_c.number: print(set_client_DH_params_answer.new_nonce_hash1, new_nonce_hash1) assert set_client_DH_params_answer.new_nonce_hash1.to_bytes() == new_nonce_hash1 print("Diffie Hellman key exchange processed successfully") self.server_salt = strxor(new_nonce[0:8], self.resPQ.server_nonce.to_bytes()[0:8]) self.auth_key.set_key(auth_key_str) print("Auth key generated") return "Auth Ok" elif set_client_DH_params_answer.number == tl.dh_gen_retry_c.number: assert set_client_DH_params_answer.new_nonce_hash2.to_bytes() == new_nonce_hash2 print("Retry Auth") elif set_client_DH_params_answer.status == tl.dh_gen_fail_c.number: assert set_client_DH_params_answer.new_nonce_hash3.to_bytes() == new_nonce_hash3 print("Auth Failed") raise Exception("Auth Failed") else: raise Exception("Response Error") def generate_message_id(self): msg_id = int(time() * 2**32) if self.last_msg_id > msg_id: msg_id = self.last_msg_id + 1 while msg_id % 4 is not 0: msg_id += 1 return msg_id def send_plaintext_message(self, message_data): # package message, not chat message msg = MTProtoUnencryptedMessage.new(self.generate_message_id(), message_data) self.send_tcp_message(msg) def recv_plaintext_message(self): tcp_msg = self.recv_tcp_message() msg = MTProtoUnencryptedMessage.from_bytes(tcp_msg.payload) if msg.is_encrypted(): raise ValueError('did not get a plaintext message') return msg.message_data def send_encrypted_message(self, message_data): """ Ecrypted Message: auth_key_id:int64 | msg_key:int128 | encrypted_data:bytes Encrypted Message: encrypted_data salt:int64 | session_id:int64 | message_id:int64 | seq_no:int32 | message_data_length:int32 | message_data:bytes | padding 0..15:bytes """ if self.session_id is None: self.session_id = self.random.getrandbits(64).to_bytes(8, 'little') msg = MTProtoEncryptedMessage.new( int.from_bytes(self.server_salt, 'little'), int.from_bytes(self.session_id, 'little'), self.generate_message_id(), 1, message_data) msg = msg.encrypt(self.auth_key) self.send_tcp_message(msg) def recv_encrypted_message(self): tcp_msg = self.recv_tcp_message() msg = MTProtoEncryptedMessage.from_bytes(tcp_msg.payload) msg = msg.decrypt(self.auth_key) print('message_data:', to_hex(msg.encrypted_data.message_data)) """ at this point, message_data looks a lot like this: message_data: Msg container -> DCF8F173 Vector<%Message> num_items:int -> 02000000 %Message: message_id:long -> 01D40F39 3BBFA055 seq_no:int -> 01000000 bytes:int -> 1C000000 body:Object -> new_session_created -> 0809C29E first_msg_id:long -> 00C8A02B 3BBFA055 unique_id:long -> 1A1D5711 00A96EC3 server_salt:long -> 74EEA560 D1AB64E3 %Message: message_id -> 01541139 3BBFA055 seq_no:int -> 02000000 bytes:int -> 14000000 body:Object -> msg_acks -> 59B4D662 Vector<long> -> 15C4B51C count -> 01000000 long -> 00C8A02B 3BBFA055 """ def send_tcp_message(self, mproto_message): tcp_msg = MTProtoTCPMessage.new(self.number, mproto_message) tcp_msg_data = tcp_msg.to_bytes() print(to_hex(tcp_msg_data)) self.socket.write(tcp_msg_data) self.number += 1 def recv_tcp_message(self): tcp_msg = MTProtoTCPMessage.from_stream(self.socket) if not tcp_msg.crc_ok(): raise ValueError('mproto_message checksum for tcp does not match') return tcp_msg def __del__(self): # cleanup self._socket.close()
class Kopy(object): """ Implementation of the kopy.io API """ url = "https://kopy.io/documents/" verifyCert = False # kopy uses an invalid cert :'( keyLength = 256 / 8 ivLength = 16 blockSize = 16 saltLength = 8 passwordRandBytes = 100 # this must be > the length of an md5 hash (32 bytes) saltPadding = "Salted__" # this is half a block, and the salt is half a block ciphertextFormat = saltPadding + "{salt}{ciphertext}" # this is then b64'd documentFormat = {"data":None, "security":None, "keep":None}.copy # note that documentFormat is a method # TODO put in some intelligent defaults, like a scheme, maybe a user-agent # to declare a paste was made with kopycat. Then again, maybe not. docNotFound = "Document not found." cryptoSchemes = ["default", "encrypted"] def __init__(self): self.randomness = SystemRandom() def _randomBytes(self, length): """ Return a specified number of bytes from the OSs random facility. """ if length <= 0: raise Exception("length must be a positive integer.") return "".join([chr(self.randomness.getrandbits(8)) for i in range(length)]) def _generateSalt(self): return self.generateRandomBytes(self.saltLength) def _parseCiphertext(self, ciphertext): output = b64decode(ciphertext) if not output.startswith(self.saltPadding): raise Exception("Bad salt padding.") if not len(output) % self.blockSize == 0: raise Exception("Message isn't sized correctly.") salt = output[len(self.saltPadding):self.blockSize] message = output[self.blockSize:] return salt, message def _formatCiphertext(self, salt, ciphertext): if len(salt) != self.saltLength: raise Exception("Bad salt.") if len(ciphertext) % self.blockSize != 0: raise Exception("Bad ciphertext.") return b64encode(self.ciphertextFormat.format(salt=salt, ciphertext=ciphertext)) def _newAES(self, key, iv): return AES.new(key, AES.MODE_CBC, iv) def _getAESArgs(self, passphrase, salt): """ Generate the key and IV from a passphrase using OpenSSL's derivation method. """ if len(salt) != 8: raise Exception("Bad salt.") return self.opensslKeyDerivation(passphrase, salt, self.keyLength, self.ivLength) def _composeDocument(self, document, encryption, keep): """ Create a dictionary to represent the document, for requests.post()'s "data" parameter. """ output = self.documentFormat() output["data"] = document output["keep"] = keep output["security"] = "encrypted" if encryption else "default" return output def _parseDocument(self, json): """ Parse a JSON string into a native Python datastructure. """ output = loads(json) return output def _postDocument(self, document, encryption=False, keep=600): """ Send a request to the API to create a new document, and keep it for a certain number of seconds. Returns a dictionary with a "key" element, containing the new document's identifier. """ return self._parseDocument(post(self.url, verify=self.verifyCert, data=self._composeDocument(document, encryption, keep)).content) def _getDocument(self, documentId): """ Retrieve a document from the API. Returns a dictionary with the document's metadata. If the document was found, the "data" element will contain the actual document; the "security" element will tell you if its encrypted (a value of "default" means plaintext, otherwise its value will be "encrypted"). If the document was not found, it will have a "message" element with the value "Document not found." """ document = get(self.url + documentId, verify=self.verifyCert) if not document.status_code in [200, 404]: raise Exception("Failed to retrieve document due to unkown error.") if not ("content-type" in document.headers and \ document.headers["content-type"] == "application/json"): raise Exception("Document has invalid content-type.") else: return self._parseDocument(document.text) def _pad(self, message): """ Add PKCS#7 padding; use byte value cooresponding to the number of characters to pad (ie, pad one byte with \x01). Pad to self.blockSize. """ pad = self.blockSize - (len(message) % self.blockSize) return message + "".join([chr(pad) for i in range(pad)]) def _unpad(self, message): """ Remove PKCS#7 padding; use byte value cooresponding to the number of characters to pad (ie, pad one byte with \x01). """ if len(message) % self.blockSize != 0: raise Exception("Message is not properly sized.") pad = ord(message[-1]) if pad > self.blockSize: raise Exception("Bad padding.") output = message[:-pad] padding = message[-pad:] for i in padding: if ord(i) != pad: raise Exception("Bad padding.") return output def encrypt(self, document, passphrase, salt=None): """ Encrypt a message with AES-256-CBC and OpenSSL-compatble passphrase. If no salt is given, a salt is generated; this is probably what you want. """ if not salt: salt = self._generateSalt() key, iv = self._getAESArgs(passphrase, salt) document = self._pad(document) aes = self._newAES(key, iv) return self._formatCiphertext(salt, aes.encrypt(document)) def decrypt(self, document, passphrase): """ Decrypt a message with AES-256-CBC and OpenSSL-compatible passphrase. """ salt, ciphertext = self._parseCiphertext(document) key, iv = self._getAESArgs(passphrase, salt) aes = self._newAES(key, iv) return self._unpad(aes.decrypt(ciphertext)) def generateRandomBytes(self, length=14): """ Generate random output of an arbitrary length, made up of hexadecimal digits. The default length is the same as kopy.io uses. The entropy should be at its upper bound, which is 8 * length bits. But I'm not a cryptographer. """ if length <= 0: raise Exception("length must be a positive integer.") output = "" while len(output) < length: output += md5(self._randomBytes(self.passwordRandBytes)).hexdigest() return output[:length] # Regarding md5; the reasoning here is that its best not to expose # naked output from our CSPRNG, but thats really the OSs job, so this # is probably just a waste of clock cycles. def opensslKeyDerivation(self, password, salt, key_len, iv_len): """ Derive the key and the IV from the given password and salt. Salt is the first 8 bytes of ciphertext. Stolen shamelessly from this Stack Overflow posting: https://stackoverflow.com/questions/13907841/implement-openssl-aes-encryption-in-python """ dtot = md5(password + salt).digest() d = [ dtot ] while len(dtot)<(iv_len+key_len): d.append( md5(d[-1] + password + salt).digest() ) dtot += d[-1] return dtot[:key_len], dtot[key_len:key_len+iv_len] def createDocument(self, document, passphrase=None, keep=600): """ Puts a document on kopy.io, and returns its identifier. If a passphrase is given, the document will be encrypted. The document will expire after "keep" seconds. """ if passphrase != None: document = self.encrypt(document, passphrase) identifier = self._postDocument(document, encryption = (passphrase != None), keep=keep) if not "key" in identifier: raise Exception("An unknown error occured.") return identifier["key"] def retrieveDocument(self, documentId, passphrase=None): """ Gets a document from kopy.io, decrypts it if its encrypted, and returns it as a dictionary. The actual document will be in the "data" element. """ document = self._getDocument(documentId) # 404s if "message" in document and document["message"] == self.docNotFound: if "data" in document: raise Exception("kopy.io said document was not found; however," + \ " document contained value of '{}'.".format(document["data"])) else: raise Exception("Document was not found.") # Malformed documents if not "data" in document: raise Exception("Document contained no data.") # Handle encryption if "security" in document: if not document["security"] in self.cryptoSchemes: raise Exception("Document uses unknown encryption.") elif document["security"] == "encrypted": if passphrase == None: raise Exception("Document is encrypted, but no passphrase" + \ " was given.") else: # Encryption document["data"] = self.decrypt(document["data"], passphrase) elif document["security"] == "default": # Plain text pass return document
# filtering exports __all__ = ['AuC'] import os import time as timemod from binascii import hexlify, unhexlify from struct import pack, unpack from time import sleep try: from os import urandom as genrand except ImportError: # non-posix platform, use SystemRandom from random import SystemRandom _rand = SystemRandom() genrand = lambda n: uint_to_bytes(_rand.getrandbits(8 * n), 8 * n) try: from CryptoMobile.Milenage import Milenage, xor_buf, conv_C2, conv_C3, conv_A2 # other available conversion functions are: # conv_C4, conv_C5, conv_A2, conv_A3, conv_A4, conv_A7 from pycomp128 import comp128v1, comp128v2, comp128v3 except ImportError as err: print('CryptoMobile library is required for Milenage and Comp-128') raise (err) from .utils import * class AuC: """3GPP Authentication Centre
def generate(self): ''' @summary Generate configuration file with different random seeds ''' i=0 while True: try: os.remove(self.baseFile[:-4]+'_'+str(i)+'.xml') i+=1 except: break for dirname, dirnames, filenames in os.walk('.'): if dirname[-2:] == 'LO' or dirname[-2:] == 'UP': shutil.rmtree(dirname) f = Opener(self.baseFile) rootNode = f.getRootNode() GeneratorSeeds = rootNode.toElement().firstChildElement("Input").firstChildElement("PopulationManager").firstChildElement("Generator").firstChildElement("RandomizerInfo") SimulatorSeeds = rootNode.toElement().firstChildElement("Simulation").firstChildElement("RandomizerInfo") paramNode = rootNode.toElement().firstChildElement("System").firstChildElement("Parameters") EntryNodes = paramNode.elementsByTagName("Entry") threadsGenerator = self.spinBoxGenThread.value() threadsSimulator = self.spinBoxSimThread.value() elt = paramNode.firstChildElement("Entry") while elt.attribute("label") != "threads.simulator": elt = elt.nextSiblingElement("Entry") elt = elt.firstChild().toElement() elt.toElement().setAttribute("value", str(threadsSimulator)) elt = paramNode.firstChildElement("Entry") while elt.attribute("label") != "threads.generator": elt = elt.nextSiblingElement("Entry") elt = elt.firstChild().toElement() elt.toElement().setAttribute("value", str(threadsGenerator)) if self.checkBoxGen.isChecked(): if threadsGenerator < GeneratorSeeds.childNodes().count(): compteur = GeneratorSeeds.childNodes().count()-threadsGenerator while compteur !=0 : GeneratorSeeds.removeChild(GeneratorSeeds.lastChild()) compteur = compteur -1 else: compteur = threadsGenerator-GeneratorSeeds.childNodes().count() while compteur != 0 : GeneratorSeeds.appendChild(GeneratorSeeds.ownerDocument().createElement("Randomizer")) compteur = compteur -1 if self.checkBoxSim.isChecked(): if threadsSimulator < SimulatorSeeds.childNodes().count(): compteur = SimulatorSeeds.childNodes().count()-threadsSimulator while compteur !=0 : SimulatorSeeds.removeChild(SimulatorSeeds.lastChild()) compteur = compteur -1 else: compteur = threadsSimulator-SimulatorSeeds.childNodes().count() while compteur != 0 : SimulatorSeeds.appendChild(SimulatorSeeds.ownerDocument().createElement("Randomizer")) compteur = compteur -1 #Generator pseudo-random numbers for seeds fileNumber = 0 tmpTextStream = QtCore.QTextStream() randomGenerator = SystemRandom() if self.comboBoxBits.currentIndex() == 0: bitLength = 64 maxLong = 18446744073709551615 else: bitLength = 32 maxLong = 4294967295 while fileNumber != self.spinBoxNumFile.value(): if self.checkBoxGen.isChecked(): for i in range(0,GeneratorSeeds.childNodes().count()): currentRand = GeneratorSeeds.childNodes().item(i) currentRand.toElement().setAttribute("state","") try : randomLong = randomGenerator.getrandbits(bitLength) except NotImplementedError: randomLong = randint(1,maxLong) currentRand.toElement().setAttribute("seed",randomLong) if self.checkBoxSim.isChecked(): for i in range(0,SimulatorSeeds.childNodes().count()): currentRand = SimulatorSeeds.childNodes().item(i) currentRand.toElement().setAttribute("state","") try : randomLong = randomGenerator.getrandbits(bitLength) except NotImplementedError: randomLong = randint(1,maxLong) currentRand.toElement().setAttribute("seed",randomLong) fileP = QtCore.QFile(str(self.baseFile).rsplit(".")[0]+("_")+str(fileNumber)+".xml") fileP.open(QtCore.QIODevice.ReadWrite|QtCore.QIODevice.Truncate) tmpTextStream.setDevice(fileP) rootNode.save(tmpTextStream,5) fileP.close() fileNumber += 1 self.counter += 1 self.progressB.setValue(self.counter) if self.checkBoxSens.isChecked() or self.checkBoxUni.isChecked(): path = str(self.baseFile[:-4])+"_" util.script_sens.main(path, self.spinBoxNumFile.value(),self.progressB2,self.progressB2.value(),self.checkBoxUni.isChecked()) self.accept()
def generate_secret_key(): cryptogen = SystemRandom() return str(cryptogen.getrandbits(256))
def generate_auth_token(): rand = SystemRandom() bits = rand.getrandbits(256) secret = "{:064x}".format(bits) return secret