def find_generator_and_safe_prime(bits, gen_max_bits = False): stdout.write('Trying to find prime p ') while(1): stdout.write('.') q = number.getPrime(bits-1) # zeby pomnozona przez 2 byla na pewno mniejsza od p, (+1 pomijam, zakladam ze nie przekroczy) p = (q << 1) + 1 if number.isPrime(p): print '\n' + str(number.size(p)) + ' bits prime p found' p_sub_1 = p - 1 stdout.write('Trying to find generator g ') while(1): if gen_max_bits: # generator moze miec dowolna liczbe bitow g = number.getRandomNBitInteger(bits) if g >= p: continue else: g = number.getRandomRange(2, p) if pow(g, 2, p) == 1 or pow(g, q, p) == 1: stdout.write('.') continue print '\n' + str(number.size(g)) + ' bits generator g found' return p, g
def randrange(self, *args): """randrange([start,] stop[, step]): Return a randomly-selected element from range(start, stop, step).""" if len(args) == 3: (start, stop, step) = args elif len(args) == 2: (start, stop) = args step = 1 elif len(args) == 1: (stop, ) = args start = 0 step = 1 else: raise TypeError("randrange expected at most 3 arguments, got %d" % (len(args), )) if (not isinstance(start, (int, long)) or not isinstance(stop, (int, long)) or not isinstance(step, (int, long))): raise TypeError("randrange requires integer arguments") if step == 0: raise ValueError("randrange step argument must not be zero") num_choices = ceil_div(stop - start, step) if num_choices < 0: num_choices = 0 if num_choices < 1: raise ValueError("empty range for randrange(%r, %r, %r)" % (start, stop, step)) # Pick a random number in the range of possible numbers r = num_choices while r >= num_choices: r = self.getrandbits(size(num_choices)) return start + (step * r)
def _check_public_key(self, dsaObj): k = a2b_hex(self.k) m_hash = a2b_hex(self.m_hash) # Check capabilities self.assertEqual(0, dsaObj.has_private()) self.assertEqual(1, dsaObj.can_sign()) self.assertEqual(0, dsaObj.can_encrypt()) self.assertEqual(0, dsaObj.can_blind()) # Check dsaObj.[ygpq] -> dsaObj.key.[ygpq] mapping self.assertEqual(dsaObj.y, dsaObj.key.y) self.assertEqual(dsaObj.g, dsaObj.key.g) self.assertEqual(dsaObj.p, dsaObj.key.p) self.assertEqual(dsaObj.q, dsaObj.key.q) # Check that private parameters are all missing self.assertEqual(0, hasattr(dsaObj, 'x')) self.assertEqual(0, hasattr(dsaObj.key, 'x')) # Sanity check key data self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1 # Public-only key objects should raise an error when .sign() is called self.assertRaises(TypeError, dsaObj.sign, m_hash, k) # Check __eq__ and __ne__ self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),True) # assert_ self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf
def genKey(name, filename): #print("Reading public key: %s" % filename) with open(filename, 'rU') as fh: pubkey_data = fh.read() pubkey = RSA.importKey(pubkey_data) # Only support 2048 or 4096 bit keys size = number.size(pubkey.n) if size < 2000: print("Error: Key size is: %d" % pubkey.size()) sys.exit(1) key = {} key["name"] = name key["size"] = "%s" % size key["bits"] = "0x%x" % size # Here be dragons, this really doesn't handle a u64. key["exponent"] = "0x0 0x%x" % pubkey.e b2_32 = 2**32L n0_invp = (number.inverse(pubkey.n, b2_32) - b2_32) * -1 key["n0inverse"] = "0x%x" % n0_invp modulus = pubkey.n key["modulus"] = " ".join(genWords(size, modulus)) r = 2**size r_squared = (r * r) % modulus key["rsquared"] = " ".join(genWords(size, r_squared)) return key
def randrange(self, *args): if len(args) == 3: start, stop, step = args elif len(args) == 2: start, stop = args step = 1 elif len(args) == 1: stop, = args start = 0 step = 1 else: raise TypeError('randrange expected at most 3 arguments, got %d' % (len(args),)) if not isinstance(start, (int, long)) or not isinstance(stop, (int, long)) or not isinstance(step, (int, long)): raise TypeError('randrange requires integer arguments') if step == 0: raise ValueError('randrange step argument must not be zero') num_choices = ceil_div(stop - start, step) if num_choices < 0: num_choices = 0 if num_choices < 1: raise ValueError('empty range for randrange(%r, %r, %r)' % (start, stop, step)) r = num_choices while r >= num_choices: r = self.getrandbits(size(num_choices)) return start + step * r
def generate_c(bits, randfunc, progress_func=None): # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p * q) < bits: p = pubkey.getPrime(bits / 2, randfunc) q = pubkey.getPrime(bits / 2, randfunc) # p shall be smaller than q (for calc of u) if p > q: (p, q) = (q, p) if progress_func: progress_func('u\n') u = pubkey.inverse(p, q) n = p * q e = 65537L if progress_func: progress_func('d\n') d = pubkey.inverse(e, (p - 1) * (q - 1)) key = _fastmath.rsa_construct(n, e, d, p, q, u) obj = RSAobj_c(key) ## print p ## print q ## print number.size(p), number.size(q), number.size(q*p), ## print obj.size(), bits assert bits <= 1 + obj.size(), "Generated key is too small" return obj
def _check_public_key(self, dsaObj): k = a2b_hex(self.k) m_hash = a2b_hex(self.m_hash) # Check capabilities self.assertEqual(0, dsaObj.has_private()) self.assertEqual(1, dsaObj.can_sign()) self.assertEqual(0, dsaObj.can_encrypt()) self.assertEqual(0, dsaObj.can_blind()) # Check dsaObj.[ygpq] -> dsaObj.key.[ygpq] mapping self.assertEqual(dsaObj.y, dsaObj.key.y) self.assertEqual(dsaObj.g, dsaObj.key.g) self.assertEqual(dsaObj.p, dsaObj.key.p) self.assertEqual(dsaObj.q, dsaObj.key.q) # Check that private parameters are all missing self.assertEqual(0, hasattr(dsaObj, 'x')) self.assertEqual(0, hasattr(dsaObj.key, 'x')) # Sanity check key data self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1 # Public-only key objects should raise an error when .sign() is called self.assertRaises(TypeError, dsaObj.sign, m_hash, k) # Check __eq__ and __ne__ self.assert_(dsaObj.publickey() == dsaObj.publickey()) self.assert_(not (dsaObj.publickey() != dsaObj.publickey()))
def testing_full(i): print('running full test %d times' % i) bits = 128 for i in range(100): p = gmpy2.next_prime(2**(bits / 2)) q = gmpy2.next_prime(p) n = p * q n2 = n * n mbits = size(n) b = mbits // 2 k = getRandomRange(0, n) g = (1 + k * n) % n2 sk1 = LCM(p - 1, q - 1) sk2 = inverse(L(pow(g, sk1, n2), n), n) pt = getRandomInteger(bits - 1) ct = encrypt(pt, g, n, n2) assert decrypt(encrypt(pt, g, n, n2), sk1, sk2, n, n2) == pt print(pt) print(bin(pt)[2:]) low = recover_low_bits(LocalOracle(sk1, sk2, n, n2, b), n, n2, g, ct) print(low) high = recover_high_bits(int(low, 2), LocalOracle(sk1, sk2, n, n2, b), n, n2, g, ct) print(high) result = int(high + low, 2) print(result) assert result == pt
def rsa_long_encrypt(self, plaintext_str): """Encrypt the string :param plaintext_str: Strings that need to be encrypted, type str :return: Encrypted string, type str """ _msg = plaintext_str.encode('utf-8') length = len(_msg) # 1024/8 - 11=117, 1024 bits key # 2048/8 - 11=245, 2048 bits key mod_bits = size(rsa.importKey(self.public_key).n) default_length = ceil_div(mod_bits, 8) - 11 # Public key encryption public_obj = PKCS1_v1_5.new(rsa.importKey(self.public_key)) # Fragment encryption is not required if length < default_length: return base64.b64encode("".join(public_obj.encrypt(_msg))) # Fragment encryption offset = 0 res = [] while length - offset > 0: if length - offset > default_length: res.append( public_obj.encrypt(_msg[offset:offset + default_length])) else: res.append(public_obj.encrypt(_msg[offset:])) offset += default_length return base64.b64encode("".join(res))
def generate(bits, randfunc=None, progress_func=None): obj = Paillierobj() # Generate the prime factors of n if progress_func: progress_func("p,q\n") p = q = 1L assert bits % 2 == 0, "Not an even number of bits" while number.size(p * q) < bits: p = number.getPrime(bits >> 1, randfunc) q = number.getPrime(bits >> 1, randfunc) obj.p = p obj.q = q obj.n = p * q obj.n_sq = obj.n * obj.n if progress_func: progress_func("l\n") obj.l = number.LCM(obj.p - 1, obj.q - 1) if progress_func: progress_func("g\n") obj.g = obj._getRandomMult() * obj.n + 1 # TODO: check gExp = L(pow(obj.g, obj.l, obj.n_sq), obj.n) while not number.GCD(gExp, obj.n) == 1: obj.g = obj._getRandomMult() * obj.n + 1 # TODO: check gExp = L(pow(obj.g, obj.l, obj.n_sq), obj.n) obj.m = number.inverse(gExp, obj.n) assert bits <= 1 + obj.size(), "Generated key is too small" return obj
def _check_public_key(self, dsaObj): k = bytes_to_long(a2b_hex(self.k)) m_hash = bytes_to_long(a2b_hex(self.m_hash)) # Check capabilities self.assertEqual(0, dsaObj.has_private()) self.assertEqual(1, dsaObj.can_sign()) self.assertEqual(0, dsaObj.can_encrypt()) # Check that private parameters are all missing self.assertEqual(0, hasattr(dsaObj, 'x')) # Sanity check key data self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1 # Public-only key objects should raise an error when .sign() is called self.assertRaises(TypeError, dsaObj._sign, m_hash, k) # Check __eq__ and __ne__ self.assertEqual(dsaObj.publickey() == dsaObj.publickey(), True) # assert_ self.assertEqual(dsaObj.publickey() != dsaObj.publickey(), False) # failIf
def rsa_long_decrypt(self, encrypted_str): """Decrypt an encrypted string :param encrypted_str: Encrypted string, type str :return: Decrypted string, type str """ _msg = base64.b64decode(encrypted_str) length = len(_msg) # 1024/8=128, 1024 bits key # 2048/8=256, 2048 bits key mod_bits = size(rsa.importKey(self.private_key).n) default_length = ceil_div(mod_bits, 8) # Private key to decrypt private_obj = PKCS1_v1_5.new(rsa.importKey(self.private_key)) # Fragment decryption is not required if length < default_length: return "".join(private_obj.decrypt(_msg, 'xyz')) # Fragment decryption offset = 0 res = [] while length - offset > 0: if length - offset > default_length: res.append( private_obj.decrypt(_msg[offset:offset + default_length], 'xyz')) else: res.append(private_obj.decrypt(_msg[offset:], 'xyz')) offset += default_length return "".join(res)
def randrange(self, *args): """randrange([start,] stop[, step]): Return a randomly-selected element from range(start, stop, step).""" if len(args) == 3: (start, stop, step) = args elif len(args) == 2: (start, stop) = args step = 1 elif len(args) == 1: (stop,) = args start = 0 step = 1 else: raise TypeError("randrange expected at most 3 arguments, got %d" % (len(args),)) if not isinstance(start, (int, long)) or not isinstance(stop, (int, long)) or not isinstance(step, (int, long)): raise TypeError("randrange requires integer arguments") if step == 0: raise ValueError("randrange step argument must not be zero") num_choices = ceil_div(stop - start, step) if num_choices < 0: num_choices = 0 if num_choices < 1: raise ValueError("empty range for randrange(%r, %r, %r)" % (start, stop, step)) # Pick a random number in the range of possible numbers r = num_choices while r >= num_choices: r = self.getrandbits(size(num_choices)) return start + (step * r)
def generate_c(bits, randfunc, progress_func = None): # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p*q) < bits: p = pubkey.getPrime(bits/2, randfunc) q = pubkey.getPrime(bits/2, randfunc) # p shall be smaller than q (for calc of u) if p > q: (p, q)=(q, p) if progress_func: progress_func('u\n') u=pubkey.inverse(p, q) n=p*q e = 65537L if progress_func: progress_func('d\n') d=pubkey.inverse(e, (p-1)*(q-1)) key = _fastmath.rsa_construct(n,e,d,p,q,u) obj = RSAobj_c(key) ## print p ## print q ## print number.size(p), number.size(q), number.size(q*p), ## print obj.size(), bits assert bits <= 1+obj.size(), "Generated key is too small" return obj
def find_generator_and_prime(bits, n, gen_max_bits = False): # p - 1 = q1 * q2 * q3 * ... * qn p_sub_1 = 0 # p - 1 p = 0 stdout.write('Trying to find prime p ') while(not number.isPrime(p)): # sprawdzamy czy liczba p jest pierwsza, inaczej nie ma sensu szukac generatora stdout.write('.') qs = [2] # lista q, inicjowana q1 = 2, bez 2 p+1 bylaby zawsze liczba parzysta czyli nie pierwsza p_sub_1 = qs[0] # p - 1 = q1 for i in range(0, n): q = number.getPrime(bits/n) tmp_p_sub_1 = p_sub_1 * q tmp_p = tmp_p_sub_1 + 1 if number.size(tmp_p) <= bits: # sprawdzamy czy liczba p ma tyle bitow ile chcemy p_sub_1 = tmp_p_sub_1 p = tmp_p qs.append(q) else: break if(number.size(p_sub_1) != bits): # dopelniamy do oczekiwanej liczby bitow mnozac kilkukrotnie przez 2 p_sub_1 <<= bits-number.size(p_sub_1) p = p_sub_1 + 1 stdout.write('\n' + str(number.size(p)) + ' bits prime p found\n') stdout.write("Trying to find generator g ") while(1): # kazda grupa cykliczna ma generator stdout.write('.') if gen_max_bits: g = number.getRandomNBitInteger(bits) # generator moze miec dowolna liczbe bitow if g >= p: continue else: g = number.getRandomRange(2, p) isGenerator = True for q in qs: if pow(g, p_sub_1/q, p) == 1: # nie jest generatorem jesli g ^ ((p-1) / q) mod p == 1 isGenerator = False break; if isGenerator: stdout.write('\n' + str(number.size(g)) + ' bits generator g found\n') return p, g
def update_rsa_key_info(self, rsa_key, mode): """Stores info about the RSA key. """ modBits = number.size(rsa_key._key.n) self.rsa_key_info[mode] = {"bits": modBits} k = number.ceil_div(modBits, 8) self.rsa_key_info[mode].update({"bytes": k}) hLen = rsa_key._hashObj.digest_size self.rsa_key_info[mode].update({"max_message_length": k - (2 * hLen) - 2})
def update_rsa_key_info(self, rsa_key, mode): """Stores info about the RSA key. """ modBits = number.size(rsa_key._key.n) self.rsa_key_info[mode] = {'bits': modBits} k = number.ceil_div(modBits, 8) self.rsa_key_info[mode].update({'bytes': k}) hLen = rsa_key._hashObj.digest_size self.rsa_key_info[mode].update( {'max_message_length': k - (2 * hLen) - 2})
def generate_py(bits, randfunc, progress_func=None): """generate(bits:int, randfunc:callable, progress_func:callable) Generate an RSA key of length 'bits', using 'randfunc' to get random data and 'progress_func', if present, to display the progress of the key generation. """ obj=RSAobj() obj.e = 65537L # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p*q) < bits: # Note that q might be one bit longer than p if somebody specifies an odd # number of bits for the key. (Why would anyone do that? You don't get # more security.) # # Note also that we ensure that e is coprime to (p-1) and (q-1). # This is needed for encryption to work properly, according to the 1997 # paper by Robert D. Silverman of RSA Labs, "Fast generation of random, # strong RSA primes", available at # http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.17.2713&rep=rep1&type=pdf # Since e=65537 is prime, it is sufficient to check that e divides # neither (p-1) nor (q-1). p = 1L while (p - 1) % obj.e == 0: if progress_func: progress_func('p\n') p = pubkey.getPrime(bits/2, randfunc) q = 1L while (q - 1) % obj.e == 0: if progress_func: progress_func('q\n') q = pubkey.getPrime(bits - (bits/2), randfunc) # p shall be smaller than q (for calc of u) if p > q: (p, q)=(q, p) obj.p = p obj.q = q if progress_func: progress_func('u\n') obj.u = pubkey.inverse(obj.p, obj.q) obj.n = obj.p*obj.q if progress_func: progress_func('d\n') obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1)) assert bits <= 1+obj.size(), "Generated key is too small" return obj
def _check_private_key(self, dsaObj): # Check capabilities self.assertEqual(1, dsaObj.has_private()) self.assertEqual(1, dsaObj.can_sign()) self.assertEqual(0, dsaObj.can_encrypt()) # Sanity check key data self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1 self.assertEqual(dsaObj.y, pow(dsaObj.g, dsaObj.x, dsaObj.p)) # y == g**x mod p self.assertEqual(1, 0 < dsaObj.x < dsaObj.q) # 0 < x < q
def _needs_symmetric(self, plaintext): """ Determines whether the key is big enough for the plaintext, or whether we need to go symmetric. Stolen from pycrypto source. """ modBits = number.size(self.key.n) k = number.ceil_div(modBits, 8) # Convert from bits to bytes hLen = self.hashAlgo.digest_size mLen = len(plaintext) ps_len = k-mLen-2*hLen-2 return ps_len < 0
def encrypt(msg, e, n=None, p=None, q=None): '''Encrypts a string msg with values e and n in 6 steps Steps: 1) Breaks the sting into chunks that can be encrypted for given n. 2) Each chunk is translated into its ascii value as a hex string. 3) The last chunk is padded with null values if it is smaller than the other chunks. 4) Each chunk is encrypted and stored as a binary value. 5) Each chunk is given leading 0's so each has bits equal to the number of bits in n. 6) The chunks are joined together and converted to a number. Parameters: msg(str): ascii sting containing a message Returns: int: encrypted message as a number Raises: ValueError: if n is not given and p or q are not given ''' if n is None: if p is None or q is None: raise ValueError("p and q are needed if n is not given") n = p * q chunkSize = int(size(n) / 8) # Step 1: Break message up into chunks msgChunks = strToList(msg, chunkSize) # Steps 2 to 5: Read docstring for func in [(lambda chunk: ''.join(hex(ord(c))[2:] for c in chunk)), (lambda chunk: chunk + '0' * ((chunkSize * 2) - len(chunk))), (lambda chunk: bin(pow(int(chunk, 16), e, n))[2:]), (lambda chunk: chunk.zfill(size(n)))]: msgChunks = list(map(func, msgChunks)) # Step 6: Merge chunks into a single string and convert to integer return int(listToStr(msgChunks), 2)
def eval(self, x): """This method returns the evaluation of the function with input x :param x: this is the input as a Long """ aes = AES.new(self.key, AES.MODE_CFB, "\0"*AES.block_size) while True: nonce = 0 data = KeyedPRF.pad(SHA256.new(str(x+nonce).encode()).digest(), (number.size(self.range)+7)//8) num = self.mask & number.bytes_to_long(aes.encrypt(data)) if (num < self.range): return num nonce += 1
def get_bit(number, n_bit, dire): ''' dire: 1: left 0: right ''' if dire: sn = size(number) if sn % 8 != 0: sn += (8 - sn % 8) return number >> (sn-n_bit) else: return number & (pow(2, n_bit) - 1)
def bit_length(input_num): """ Return the bit length of input. EX: 7 (0b111) has length 3 EX: 8 (0b1000) has length 4 Inputs: ``int`` input_num Outputs: ``int`` """ # just use the pycryptodome function for this return number.size(int(input_num))
def recover_high_bits(low, oracle, n, n2, g, ct): print('cracking high bits') mbits = size(n) b = mbits // 2 result_bits = [] subtractor = n - low sub = encrypt(subtractor, g, n, n2) ct_sub = (ct * sub) % n2 for i in range(b): divisor = inverse(2**i, n) payload = pow(ct_sub, divisor, n2) lsb = oracle.get_lsb(payload) result_bits.append(str(lsb)) return "".join(result_bits[::-1])
def get_random_range(a, b, randfunc=None): """getRandomRange(a:int, b:int, randfunc:callable):long Return a random number n so that a <= n < b. If randfunc is omitted, then Random.new().read is used. This function is for internal use only and may be renamed or removed in the future. """ range_ = b - a - 1 bits = size(range_) value = get_random_integer(bits, randfunc) while value > range_: value = get_random_integer(bits, randfunc) return a + value
def eval(self, x): """This method returns the evaluation of the function with input x :param x: this is the input as a Long """ aes = AES.new(self.key, AES.MODE_CFB, "\0" * AES.block_size) while True: nonce = 0 data = KeyedPRF.pad( SHA256.new(str(x + nonce).encode()).digest(), (number.size(self.range) + 7) // 8) num = self.mask & number.bytes_to_long(aes.encrypt(data)) if (num < self.range): return num nonce += 1
def __init__(self, key, range): """Initialization method :param key: the key to use for the PRF. this key is the only source of randomness for the output of this function. should be a hashable object, preferably a byte array or string :param range: the output range as a long of the function. the output of the function will be in [0:range) """ self.key = key self.range = range # we need a mask because the number we'll generate will be of a # certain byte size but we want to restrict it to within a # certain bit size because we're trying to find numbers within # a certain range this will speed it up self.mask = (1 << number.size(self.range)) - 1
def generate_pq(modbits): # generate primes p ad q # stolen from pycrypt p = q = 1L while number.size(p * q) < modbits: if modbits > 512: # Note that q might be one bit longer than p if somebody specifies an odd # number of bits for the key. (Why would anyone do that? You don't get # more security.) p = pubkey.getStrongPrime(modbits >> 1, 0, 1e-12, None) q = pubkey.getStrongPrime(modbits - (modbits >> 1), 0, 1e-12, None) else: p = pubkey.getPrime(modbits >> 1, None) q = pubkey.getPrime(modbits - (modbits >> 1), None) return (p, q)
def generate_pq(modBits): ''' Generate p, q (public key) with modBits bits for SRA encryption generate primes p and q, from Sefasi and pycrypt ''' assert (modBits % 2 == 0) # must provide even number of bits p = q = 1L while number.size(p * q) < modBits: if modBits > 512: p = pubkey.getStrongPrime(modBits >> 1, 0, 1e-12, None) q = pubkey.getStrongPrime(modBits - (modBits >> 1), 0, 1e-12, None) else: p = pubkey.getPrime(modBits >> 1, None) q = pubkey.getPrime(modBits - (modBits >> 1), None) return (p, q)
def __init__(self, key, range): """Initialization method :param key: the key to use for the PRF. this key is the only source of randomness for the output of this function. should be a hashable object, preferably a byte array or string :param range: the output range as a long of the function. the output of the function will be in [0:range) """ self.key = key self.range = range # we need a mask because the number we'll generate will be of a # certain byte size but we want to restrict it to within a # certain bit size because we're trying to find numbers within # a certain range this will speed it up self.mask = (1 << number.size(self.range))-1
def generate_pq(modbits): # generate primes p ad q # stolen from pycrypt p = q = 1L while number.size(p*q) < modbits: if modbits > 512 : # Note that q might be one bit longer than p if somebody specifies an odd # number of bits for the key. (Why would anyone do that? You don't get # more security.) p = pubkey.getStrongPrime(modbits>>1, 0, 1e-12, None) q = pubkey.getStrongPrime(modbits - (modbits>>1), 0, 1e-12, None) else : p = pubkey.getPrime(modbits>>1, None) q = pubkey.getPrime(modbits - (modbits>>1), None) return (p, q)
def Sign(self, data): # Prepend precomputed ASN1 hash code for SHA1 data = b'\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14' + data pkcs = pkcs1_15.new(self.rsa_key) # See 8.2.1 in RFC3447 modBits = number.size(pkcs._key.n) k = pkcs1_15.ceil_div(modBits,8) # Convert from bits to bytes # Step 2a (OS2IP) em_int = pkcs1_15.bytes_to_long(PycryptodomeAuthSigner._pad_for_signing(data, k)) # Step 2b (RSASP1) m_int = pkcs._key._decrypt(em_int) # Step 2c (I2OSP) signature = pkcs1_15.long_to_bytes(m_int, k) return signature
def get_pkey(): print "DH key exchange system:" P = getPrime(m) print "P: ", hex(P) G = getRandomNBitInteger(m) a = getRandomNBitInteger(m / 4) Ya = pow(G, a, P) print "Please enter you secret key: " try: b = raw_input() b = int(b) assert size(b) == m / 4 except: m_exit(-1) Yb = pow(G, b, P) K = pow(Yb, a, P) return (Ya, K)
def get_pkey(): print "DH key exchange system:" P = getPrime(m) print "P: ", hex(P) G = getRandomNBitInteger(m) a = getRandomNBitInteger(m/4) Ya = pow(G, a, P) print "Please enter you secret key: " try: b = raw_input() b = int(b) assert size(b) == m/4 except: m_exit(-1) Yb = pow(G, b, P) K = pow(Yb, a, P) return (Ya, K)
def recover_low_bits(oracle, n, n2, g, ct): print('cracking low bits') mbits = size(n) bits_to_recover = mbits // 2 result_bits = [] initial_state = oracle.get_lsb(ct) for i in range(bits_to_recover): filling = [ '0' if known_bit == '1' else '1' for known_bit in result_bits ] add = int("".join(filling + ['1']), 2) << (bits_to_recover - i - 1) payload = (ct * encrypt(add, g, n, n2)) % n2 lsb = oracle.get_lsb(payload) if lsb != initial_state: result_bits.append('1') else: result_bits.append('0') result = "".join(result_bits) return result
def generate_py(bits, randfunc, progress_func=None, e=65537): """generate(bits:int, randfunc:callable, progress_func:callable, e:int) Generate an RSA key of length 'bits', public exponent 'e'(which must be odd), using 'randfunc' to get random data and 'progress_func', if present, to display the progress of the key generation. """ obj=RSAobj() obj.e = long(e) # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p*q) < bits: # Note that q might be one bit longer than p if somebody specifies an odd # number of bits for the key. (Why would anyone do that? You don't get # more security.) p = pubkey.getStrongPrime(bits>>1, obj.e, 1e-12, randfunc) q = pubkey.getStrongPrime(bits - (bits>>1), obj.e, 1e-12, randfunc) # It's OK for p to be larger than q, but let's be # kind to the function that will invert it for # th calculation of u. if p > q: (p, q)=(q, p) obj.p = p obj.q = q if progress_func: progress_func('u\n') obj.u = pubkey.inverse(obj.p, obj.q) obj.n = obj.p*obj.q if progress_func: progress_func('d\n') obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1)) assert bits <= 1+obj.size(), "Generated key is too small" return obj
def sign(self, message): from Crypto.Util.py3compat import _copy_bytes modBits = size(self._key.n) k = ceil_div(modBits, 8) mLen = len(message) # Step 1 if mLen > k - 11: raise ValueError("Plaintext is too long.") # Step 2a ps = b'\xff' * (k - mLen - 3) # Step 2b em = b'\x00\x01' + ps + b'\x00' + _copy_bytes(None, None, message) # Step 3a (OS2IP) em_int = bytes_to_long(em) # Step 3b (RSAEP) m_int = self._key._decrypt(em_int) # Step 3c (I2OSP) c = long_to_bytes(m_int, k) return c
def generate_py(bits, randfunc, progress_func=None): """generate(bits:int, randfunc:callable, progress_func:callable) Generate an RSA key of length 'bits', using 'randfunc' to get random data and 'progress_func', if present, to display the progress of the key generation. """ obj=RSAobj() # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p*q) < bits: # Note that q might be one bit longer than p if somebody specifies an odd # number of bits for the key. (Why would anyone do that? You don't get # more security.) p = pubkey.getPrime(bits/2, randfunc) q = pubkey.getPrime(bits - (bits/2), randfunc) # p shall be smaller than q (for calc of u) if p > q: (p, q)=(q, p) obj.p = p obj.q = q if progress_func: progress_func('u\n') obj.u = pubkey.inverse(obj.p, obj.q) obj.n = obj.p*obj.q obj.e = 65537L if progress_func: progress_func('d\n') obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1)) assert bits <= 1+obj.size(), "Generated key is too small" return obj
def generate_py(bits, randfunc, progress_func=None): """generate(bits:int, randfunc:callable, progress_func:callable) Generate an RSA key of length 'bits', using 'randfunc' to get random data and 'progress_func', if present, to display the progress of the key generation. """ obj = RSAobj() obj.e = 65537L # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p * q) < bits: # Note that q might be one bit longer than p if somebody specifies an odd # number of bits for the key. (Why would anyone do that? You don't get # more security.) p = pubkey.getStrongPrime(bits >> 1, obj.e, 1e-12, randfunc) q = pubkey.getStrongPrime(bits - (bits >> 1), obj.e, 1e-12, randfunc) # p shall be smaller than q (for calc of u) if p > q: (p, q) = (q, p) obj.p = p obj.q = q if progress_func: progress_func('u\n') obj.u = pubkey.inverse(obj.p, obj.q) obj.n = obj.p * obj.q if progress_func: progress_func('d\n') obj.d = pubkey.inverse(obj.e, (obj.p - 1) * (obj.q - 1)) assert bits <= 1 + obj.size(), "Generated key is too small" return obj
def generate_py(bits, randfunc, progress_func=None, e=65537): obj = RSAobj() obj.e = long(e) if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p * q) < bits: p = pubkey.getStrongPrime(bits >> 1, obj.e, 1e-12, randfunc) q = pubkey.getStrongPrime(bits - (bits >> 1), obj.e, 1e-12, randfunc) if p > q: p, q = q, p obj.p = p obj.q = q if progress_func: progress_func('u\n') obj.u = pubkey.inverse(obj.p, obj.q) obj.n = obj.p * obj.q if progress_func: progress_func('d\n') obj.d = pubkey.inverse(obj.e, (obj.p - 1) * (obj.q - 1)) return obj
def decrypt_with_rsa_chunyu(msg): ''' msg必须采用base64编码, 注意: base64编码的数据经过URLDecoder处理之后,可能不正确,其中的+会变成' ' ''' msg = base64ToString(msg) key = RSA.importKey(_private_rsa_key) cipher = PKCS1_v1_5_Cipher.new(key) modBits = number.size(key.n) k = ceil_div(modBits,8) # Convert from bits to bytes print "K: ", k msglen = len(msg) msg_encryted = "" start_idx = 0 ## 处理过长的加密 while msglen > 0: len1 = min([msglen, k]) cleartext = cipher.decrypt(msg[start_idx: (start_idx + len1)], "") msg_encryted = msg_encryted + cleartext start_idx = start_idx + len1 msglen = msglen - len1 return msg_encryted
def ecnrypt_symm_key(user, user_pub_key, symm_key): print(user_pub_key) key = RSA.import_key(user_pub_key) # encrypt symm key wirh public RSA key cipher = PKCS1_OAEP.new(key, SHA256) # Adapted from github kadaliao/rsa_util.py # to calculate the max message size the cipher can handle # it can be of variable length, but not longer than the RSA modulus (in bytes) # minus 2, minus twice the hash output size. modBits = number.size(cipher._key.n) k = number.ceil_div(modBits, 8) hLen = cipher._hashObj.digest_size length = k - 2 * hLen - 3 res = [] for i in range(0, len(symm_key), length): res.append(cipher.encrypt(symm_key[i:i + length])) ciph_symm_key = b''.join(res) symm_b64 = b64encode(ciph_symm_key).decode('utf-8') return symm_key_format % (user, symm_b64)
def decrypt_with_rsa_chunyu(msg): ''' msg必须采用base64编码, 注意: base64编码的数据经过URLDecoder处理之后,可能不正确,其中的+会变成' ' ''' msg = base64ToString(msg) key = RSA.importKey(_private_rsa_key) cipher = PKCS1_v1_5_Cipher.new(key) modBits = number.size(key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes print "K: ", k msglen = len(msg) msg_encryted = "" start_idx = 0 ## 处理过长的加密 while msglen > 0: len1 = min([msglen, k]) cleartext = cipher.decrypt(msg[start_idx:(start_idx + len1)], "") msg_encryted = msg_encryted + cleartext start_idx = start_idx + len1 msglen = msglen - len1 return msg_encryted
def generate(bits, randfunc, progress_func=None): """generate(bits:int, randfunc:callable, progress_func:callable) Generate an RSA key of length 'bits', using 'randfunc' to get random data and 'progress_func', if present, to display the progress of the key generation. """ obj=RSAobj() # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p*q) < bits: p = pubkey.getPrime(bits/2, randfunc) q = pubkey.getPrime(bits/2, randfunc) # p shall be smaller than q (for calc of u) if p > q: (p, q)=(q, p) obj.p = p obj.q = q if progress_func: progress_func('u\n') obj.u = pubkey.inverse(obj.p, obj.q) obj.n = obj.p*obj.q obj.e = 65537L if progress_func: progress_func('d\n') obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1)) assert bits <= 1+obj.size(), "Generated key is too small" return obj
def encrypt_with_rsa_chunyu(msg): ''' msg必须采用utf8编码 ''' msg = ensure_utf8(msg) key = RSA.importKey(_public_rsa_key) cipher = PKCS1_v1_5_Cipher.new(key) modBits = number.size(key.n) k = ceil_div(modBits,8) - 28 ## 11 # Convert from bits to bytes print "K: ", k msglen = len(msg) msg_encryted = "" start_idx = 0 ## 处理过长的加密 while msglen > 0: len1 = min([msglen, k]) encrypt = cipher.encrypt(msg[start_idx: (start_idx + len1)]) msg_encryted = msg_encryted + encrypt start_idx = start_idx + len1 msglen = msglen - len1 return stringToBase64(msg_encryted)
def generate(bits, randfunc, progress_func=None): """generate(bits:int, randfunc:callable, progress_func:callable) Generate an RSA key of length 'bits', using 'randfunc' to get random data and 'progress_func', if present, to display the progress of the key generation. """ obj = RSAobj() # Generate the prime factors of n if progress_func: progress_func('p,q\n') p = q = 1L while number.size(p * q) < bits: p = pubkey.getPrime(bits / 2, randfunc) q = pubkey.getPrime(bits / 2, randfunc) # p shall be smaller than q (for calc of u) if p > q: (p, q) = (q, p) obj.p = p obj.q = q if progress_func: progress_func('u\n') obj.u = pubkey.inverse(obj.p, obj.q) obj.n = obj.p * obj.q obj.e = 65537L if progress_func: progress_func('d\n') obj.d = pubkey.inverse(obj.e, (obj.p - 1) * (obj.q - 1)) assert bits <= 1 + obj.size(), "Generated key is too small" return obj
def size(self): return number.size(self.n) - 1 # TODO: check this
def size(self): """size() : int Return the maximum number of bits that can be handled by this key. """ return number.size(self.n) - 1
def test_size(self): self.assertEqual(number.size(2),2) self.assertEqual(number.size(3),2) self.assertEqual(number.size(0xa2),8) self.assertEqual(number.size(0xa2ba40),8*3) self.assertEqual(number.size(0xa2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5L), 1024)
def size(self): """Return the maximum number of bits that can be encrypted""" return size(self.n) - 1
def size(self): "Return the maximum number of bits that can be handled by this key." return number.size(self.p) - 1
def size(self): return number.size(self.p) - 1