def unpack_factors(factor_string): generator = prime_generator() output = [] for bit in factor_string: prime = next(generator) if bit == '1': output.append(prime) return output
def generate_primes(count): generator = prime_generator() prime = next(generator) yield prime _prime = next(generator) for number in range(count - 1): while _prime < (prime ** 2): _prime = next(generator) prime = _prime yield prime
def pack_factors(factors): bit_string = b'' generator = prime_generator() factors = list(factors) while factors: prime = next(generator) if prime in factors: bit_string += '1' del factors[0] else: bit_string += '0' return bit_string
def prime_hash(message_bytes, rounds=1): # p1m1 + p2m2 + p3m3 + p4m4 output = 1 generator = prime_generator() prime = reversed([next(generator) for count in range(len(message_bytes) * 2)][::2]) for round in range(rounds): for index, hash_input in enumerate(bytearray(message_bytes)): output += (next(prime) * hash_input * (index + 1)) print output #output += output return output
def pack_exponents(exponents): bit_string = b'' generator = prime_generator() for prime in sorted(exponents.keys()): exponent = exponents.pop(prime) if exponent < 8: bit_string += '0' + format(exponent, 'b').zfill(3) else: segments = exponent / 8 bit_string += ('1' + '111') * segments remainder = exponent % 8 if remainder: bit_string += ('0' + format(remainder, 'b').zfill(3)) return bit_string
from os import urandom from crypto.utilities import prime_generator, gcd, bytes_to_words, bytes_to_integer, choice generator = prime_generator() PRIMES = [next(generator) for count in range(256)] INVERT_PRIMES = dict() for index, prime in enumerate(PRIMES): INVERT_PRIMES[prime] = index del generator def random_word(wordsize=1): return bytes_to_integer(bytearray(urandom(wordsize))) def encrypt(data, key, primes=PRIMES): ciphertext = [] for index, word in enumerate(bytearray(data)): randomized1 = primes[word] * primes[random_word()] randomized2 = primes[word] * primes[random_word()] assert gcd(randomized1, randomized2) == primes[word] # random_word will output word for both values every so often _randomized1 = randomized1 randomized1 = choice(key[index], randomized1, randomized2) randomized2 = choice(key[index], randomized2, _randomized1) ciphertext.append((randomized1, randomized2)) return ciphertext def decrypt(ciphertext, key): plaintext = bytearray() for index, _ciphertext in enumerate(ciphertext): randomized1, randomized2 = _ciphertext _randomized1 = randomized1
# choose elements of the public key according the message bits # multiply all of the selected elements together into a single product to produce the ciphertext # for example: # message_bits = [ 0, 1, 1, 0, 1] # public_primes = [p1, p2, p3, p4, p5] # ciphertext = p2 * p3 * p5 # to decrypt: # decrypt the sum to obtain the product of primes # enumerate the secret primes of the private key and # - if ciphertext % prime == 0: # - set the plaintext bit at the corresponding index to 1 # otherwise, set the plaintext bit at the corresponding index to 0 from crypto.utilities import big_prime, random_integer, modular_inverse, shuffle, random_bytes, prime_generator generator = prime_generator() PRIMES = [] for count in range(80): PRIMES.append(next(generator)) del generator del count def generate_private_key(prime_count=80, key_size=16, modulus_size=33): primes = PRIMES[:] shuffle(primes, bytearray(random_bytes(len(primes)))) key = random_integer(key_size) modulus = big_prime(modulus_size) return primes[:prime_count], key, modulus
def generate_primes_until(n): for prime in prime_generator(): if prime < n: yield prime else: raise StopIteration()