Understanding Blum Blum Shub algorithm. (Python implementation) - python

Please help me to understand BBS algorithm. I did this implementation:
class EmptySequenseError(Exception):
pass
class BlumBlumShub(object):
def __init__(self, length):
self.length = length
self.primes = e(1000) # Primes obtained by my own Sieve of Eratosthenes implementation.
def get_primes(self):
out_primes = []
while len(out_primes) < 2:
curr_prime = self.primes.pop()
if curr_prime % 4 == 3:
out_primes.append(curr_prime)
return out_primes
def set_random_sequence(self):
p, q = self.get_primes()
m = p * q
self.random_sequence = [((x+1)**2)%m for x in range(self.length)]
def get_random_sequence(self):
if self.random_sequence:
return self.random_sequence
raise EmptySequenseError("Set random sequence before get it!")
And I have several questions. At first I do not want to use random library, it is too naive. My sequence is increasing, it is not absolutely random. How to prevent increasing in returned sequence? And I do not understand this part of the algorithm description:
At each step of the algorithm, some output is derived from xn+1; the output is commonly either the bit parity of xn+1 or one or more of the least significant bits of xn+1.
Please explain to me what does it mean?
Edit summary:
The algorithm is corrected.
Quote substituted to en.wikipedia quote.

for x in range(self.length):
self.random_sequence.append((x ** 2) % m)
Just generates [(x ** 2) % m for x in range(self.length)], which is roughly xn+1 = n2 mod M.
The algorithm is supposed to be: xn+1 = xn2 mod M
Do you see where your version is different?
As for the quote - you don't say where it's from, but Wikipedia has:
At each step of the algorithm, some output is derived from xn+1; the output is commonly either the bit parity of xn+1 or one or more of the least significant bits of xn+1.
It means that xn+1 is the seed for the next iteration, but not the pseudo-random number returned. Instead, the return value is derived from xn+1 by counting its bit parity (this yields either 0 or 1 each iteration), or by taking only some number of top bits.

Blum Blum Shub is described in Chapter Five of the Handbook of Applied Cryptography, Section 5.5.2. There is a lot of helpful stuff about random number generation in that chapter.

I would rather formalize my understanding as an answer.
class BlumBlumShub(object):
def __init__(self, length):
self.length = length
self.primes = e(1000)
def gen_primes(self):
out_primes = []
while len(out_primes) < 2:
curr_prime = self.primes[random.randrange(len(self.primes))]
if curr_prime % 4 == 3:
out_primes.append(curr_prime)
return out_primes
def random_generator(self):
x = random.randrange(1000000)
while self.length:
x += 1
p, q = self.gen_primes()
m = p * q
z = (x**2) % m
self.length -= 1
yield str(bin(z).count('1') % 2)
def get_random_bits(self):
return ''.join(self.random_generator())
BBS is pseudorandom bit generator, it must return random bits, not integers.
Return value is just parity bit of result xn+12 % m operation.
If I wrongly understood something, please explain my mistakes.

Related

Query regarding Bit Counting (Python)

I tried to solve this Kata problem
Write a function that takes an integer as input, and returns the number of bits that are equal to one in the binary representation of that number. You can guarantee that input is non-negative.
Example: The binary representation of 1234 is 10011010010, so the function should return 5 in this case.
But the problem is my code gives the correct answers right for the first time around but when
it is run for 2nd time onward it gives wrong answers only. I think it has to do sth with how my code is recursive. Please help me figure it out.
for example when i run count_bits(24) it gives the output 2 which is correct but when i run the same function again it would give 4 and then 6 and so on . I dont know what's wrong with this
My code.
dec_num = []
def count_bits(n):
def DecimalToBinary(n):
if n >= 1:
DecimalToBinary(n // 2)
dec_num.append( n % 2)
return dec_num
dec = DecimalToBinary(n)
return dec.count(1)
There is no need to create a list of digits if all you need is their sum. When possible, avoid creating mutable state in a recursive solution:
def count_bits(n):
if n > 0:
return n % 2 + count_bits(n // 2)
else:
return 0
That's a pretty natural translation of the obvious algorithm:
The sum of the bits in a number is the last bit plus the sum of the bits in the rest of the number.
Sometimes it's convenient to accumulate a result, which is best done by adding an accumulator argument. In some languages, that can limit stack usage, although not in Python which doesn't condense tail calls. All the same, some might find this more readable:
def count_bits(n, accum = 0):
if n > 0:
return count_bits(n // 2, accum + n % 2)
else:
return accum
In Python, a generator is a more natural control structure:
def each_bit(n):
while n > 0:
yield n % 2
n //= 2
def count_bits(n):
return sum(each_bit(n))
Of course, there are lots more ways to solve this problem.
That is because dec_num is outside the method, so it's reused at every call, put it inside
def count_bits(n):
dec_num = []
def DecimalToBinary(n):
if n >= 1:
DecimalToBinary(n // 2)
dec_num.append(n % 2)
return dec_num
dec = DecimalToBinary(n)
return dec.count(1)

Efficient finding primitive roots modulo n using Python?

I'm using the following code for finding primitive roots modulo n in Python:
Code:
def gcd(a,b):
while b != 0:
a, b = b, a % b
return a
def primRoots(modulo):
roots = []
required_set = set(num for num in range (1, modulo) if gcd(num, modulo) == 1)
for g in range(1, modulo):
actual_set = set(pow(g, powers) % modulo for powers in range (1, modulo))
if required_set == actual_set:
roots.append(g)
return roots
if __name__ == "__main__":
p = 17
primitive_roots = primRoots(p)
print(primitive_roots)
Output:
[3, 5, 6, 7, 10, 11, 12, 14]
Code fragment extracted from: Diffie-Hellman (Github)
Can the primRoots method be simplified or optimized in terms of memory usage and performance/efficiency?
One quick change that you can make here (not efficiently optimum yet) is using list and set comprehensions:
def primRoots(modulo):
coprime_set = {num for num in range(1, modulo) if gcd(num, modulo) == 1}
return [g for g in range(1, modulo) if coprime_set == {pow(g, powers, modulo)
for powers in range(1, modulo)}]
Now, one powerful and interesting algorithmic change that you can make here is to optimize your gcd function using memoization. Or even better you can simply use built-in gcd function form math module in Python-3.5+ or fractions module in former versions:
from functools import wraps
def cache_gcd(f):
cache = {}
#wraps(f)
def wrapped(a, b):
key = (a, b)
try:
result = cache[key]
except KeyError:
result = cache[key] = f(a, b)
return result
return wrapped
#cache_gcd
def gcd(a,b):
while b != 0:
a, b = b, a % b
return a
# or just do the following (recommended)
# from math import gcd
Then:
def primRoots(modulo):
coprime_set = {num for num in range(1, modulo) if gcd(num, modulo) == 1}
return [g for g in range(1, modulo) if coprime_set == {pow(g, powers, modulo)
for powers in range(1, modulo)}]
As mentioned in comments, as a more pythoinc optimizer way you can use fractions.gcd (or for Python-3.5+ math.gcd).
Based on the comment of Pete and answer of Kasramvd, I can suggest this:
from math import gcd as bltin_gcd
def primRoots(modulo):
required_set = {num for num in range(1, modulo) if bltin_gcd(num, modulo) }
return [g for g in range(1, modulo) if required_set == {pow(g, powers, modulo)
for powers in range(1, modulo)}]
print(primRoots(17))
Output:
[3, 5, 6, 7, 10, 11, 12, 14]
Changes:
It now uses pow method's 3-rd argument for the modulo.
Switched to gcd built-in function that's defined in math (for Python 3.5) for a speed boost.
Additional info about built-in gcd is here: Co-primes checking
In the special case that p is prime, the following is a good bit faster:
import sys
# translated to Python from http://www.bluetulip.org/2014/programs/primitive.js
# (some rights may remain with the author of the above javascript code)
def isNotPrime(possible):
# We only test this here to protect people who copy and paste
# the code without reading the first sentence of the answer.
# In an application where you know the numbers are prime you
# will remove this function (and the call). If you need to
# test for primality, look for a more efficient algorithm, see
# for example Joseph F's answer on this page.
i = 2
while i*i <= possible:
if (possible % i) == 0:
return True
i = i + 1
return False
def primRoots(theNum):
if isNotPrime(theNum):
raise ValueError("Sorry, the number must be prime.")
o = 1
roots = []
r = 2
while r < theNum:
k = pow(r, o, theNum)
while (k > 1):
o = o + 1
k = (k * r) % theNum
if o == (theNum - 1):
roots.append(r)
o = 1
r = r + 1
return roots
print(primRoots(int(sys.argv[1])))
You can greatly improve your isNotPrime function by using a more efficient algorithm. You could double the speed by doing a special test for even numbers and then only testing odd numbers up to the square root, but this is still very inefficient compared to an algorithm such as the Miller Rabin test. This version in the Rosetta Code site will always give the correct answer for any number with fewer than 25 digits or so. For large primes, this will run in a tiny fraction of the time it takes to use trial division.
Also, you should avoid using the floating point exponentiation operator ** when you are dealing with integers as in this case (even though the Rosetta code that I just linked to does the same thing!). Things might work fine in a particular case, but it can be a subtle source of error when Python has to convert from floating point to integers, or when an integer is too large to represent exactly in floating point. There are efficient integer square root algorithms that you can use instead. Here's a simple one:
def int_sqrt(n):
if n == 0:
return 0
x = n
y = (x + n//x)//2
while (y<x):
x=y
y = (x + n//x)//2
return x
Those codes are all in-efficient, in many ways, first of all you do not need to iterate for all co-prime reminders of n, you need to check only for powers that are dividers of Euler's function from n. In the case n is prime Euler's function is n-1. If n i prime, you need to factorize n-1 and make check with only those dividers, not all. There is a simple mathematics behind this.
Second. You need better function for powering a number imagine the power is too big, I think in python you have the function pow(g, powers, modulo) which at each steps makes division and getting the remainder only ( _ % modulo ).
If you are going to implement the Diffie-Hellman algorithm it is better to use safe primes. They are such primes that p is a prime and 2p+1 is also prime, so that 2p+1 is called safe prime. If you get n = 2*p+1, then the dividers for that n-1 (n is prime, Euler's function from n is n-1) are 1, 2, p and 2p, you need to check only if the number g at power 2 and g at power p if one of them gives 1, then that g is not primitive root, and you can throw that g away and select another g, the next one g+1, If g^2 and g^p are non equal to 1 by modulo n, then that g is a primitive root, that check guarantees, that all powers except 2p would give numbers different from 1 by modulo n.
The example code uses Sophie Germain prime p and the corresponding safe prime 2p+1, and calculates primitive roots of that safe prime 2p+1.
You can easily re-work the code for any prime number or any other number, by adding a function to calculate Euler's function and to find all divisors of that value. But this is only a demo not a complete code. And there might be better ways.
class SGPrime :
'''
This object expects a Sophie Germain prime p, it does not check that it accept that as input.
Euler function from any prime is n-1, and the order (see method get_order) of any co-prime
remainder of n could be only a divider of Euler function value.
'''
def __init__(self, pSophieGermain ):
self.n = 2*pSophieGermain+1
#TODO! check if pSophieGermain is prime
#TODO! check if n is also prime.
#They both have to be primes, elsewhere the code does not work!
# Euler's function is n-1, #TODO for any n, calculate Euler's function from n
self.elrfunc = self.n-1
# All divisors of Euler's function value, #TODO for any n, get all divisors of the Euler's function value.
self.elrfunc_divisors = [1, 2, pSophieGermain, self.elrfunc]
def get_order(self, r):
'''
Calculate the order of a number, the minimal power at which r would be congruent with 1 by modulo p.
'''
r = r % self.n
for d in self.elrfunc_divisors:
if ( pow( r, d, self.n) == 1 ):
return d
return 0 # no such order, not possible if n is prime, - see small Fermat's theorem
def is_primitive_root(self, r):
'''
Check if r is a primitive root by modulo p. Such always exists if p is prime.
'''
return ( self.get_order(r) == self.elrfunc )
def find_all_primitive_roots(self, max_num_of_roots = None):
'''
Find all primitive roots, only for demo if n is large the list is large for DH or any other such algorithm
better to stop at first primitive roots.
'''
primitive_roots = []
for g in range(1, self.n):
if ( self.is_primitive_root(g) ):
primitive_roots.append(g)
if (( max_num_of_roots != None ) and (len(primitive_roots) >= max_num_of_roots)):
break
return primitive_roots
#demo, Sophie Germain's prime
p = 20963
sggen = SGPrime(p)
print (f"Safe prime : {sggen.n}, and primitive roots of {sggen.n} are : " )
print(sggen.find_all_primitive_roots())
Regards

Generating a random, non-prime number in python

How would I generate a non-prime random number in a range in Python?
I am confused as to how I can create an algorithm that would produce a non-prime number in a certain range. Do I define a function or create a conditional statement? I would like each number in the range to have the same probability. For example, in 1 - 100, each non-prime would not have a 1% chance but instead has a ~1.35% chance.
Now, you didn't say anything about efficiency, and this could surely be optimized, but this should solve the problem. This should be an efficient algorithm for testing primality:
import random
def isPrime(n):
if n % 2 == 0 and n > 2:
return False
return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))
def randomNonPrime(rangeMin, rangeMax):
nonPrimes = filter(lambda n: not isPrime(n), xrange(rangeMin, rangeMax+1))
if not nonPrimes:
return None
return random.choice(nonPrimes)
minMax = (1000, 10000)
print randomNonPrime(*minMax)
After returning a list of all non-primes in range, a random value is selected from the list of non-primes, making the selection of any non-prime in range just as likely as any other non-prime in the range.
Edit
Although you didn't ask about efficiency, I was bored, so I figured out a method of doing this that makes a range of (1000, 10000000) take a little over 6 seconds on my machine instead of over a minute and a half:
import numpy
import sympy
def randomNonPrime(rangeMin, rangeMax):
primesInRange = numpy.fromiter(
sympy.sieve.primerange(rangeMin, rangeMax),
dtype=numpy.uint32,
count=-1
)
numbersInRange = numpy.arange(rangeMin, rangeMax+1, dtype=numpy.uint32)
nonPrimes = numbersInRange[numpy.invert(numpy.in1d(numbersInRange, primesInRange))]
if not nonPrimes.size:
return None
return numpy.random.choice(nonPrimes)
minMax = (1000, 10000000)
print randomNonPrime(*minMax)
This uses the SymPy symbolic mathematics library to optimize the generation of prime numbers in a range, and then uses NumPy to filter our output and select a random non-prime.
The algorithm and ideas to choose is very dependent on your exact use-case, as mentioned by #smarx.
Assumptions:
Each non-prime within the range has the same probability of beeing chosen / uniformity
It is sufficient that the sampled number is not a prime with a very high probability (algorithmic false positives are less likely than CPU-bugs & co.)
The sampling-range could be big (sieve-like approaches are slow)
High performance of a single sample is desired (no caching; no sampling without replacement)
Method:
Sample random-number in range
Check if this number is prime with a very fast probabilistic primality test
Stop when observing first non-prime number
If no number is found, stop algorithm after max_trials
max_trials-value is set by an approximation to the Coupon-Collectors-Problem (wiki): expected number of samples to observe each candidate once
Characteristics of method
Fast for single samples (10000 samples per second on single CPU; given range as in example)
Easy to prove uniformity
Good asymptotic behaviour regarding range-size and range-position (number sizes)
Code
import random
import math
""" Miller-Rabin primality test
source: https://jeremykun.com/2013/06/16/miller-rabin-primality-test/
"""
def decompose(n):
exponentOfTwo = 0
while n % 2 == 0:
n = n//2 # modified for python 3!
exponentOfTwo += 1
return exponentOfTwo, n
def isWitness(possibleWitness, p, exponent, remainder):
possibleWitness = pow(possibleWitness, remainder, p)
if possibleWitness == 1 or possibleWitness == p - 1:
return False
for _ in range(exponent):
possibleWitness = pow(possibleWitness, 2, p)
if possibleWitness == p - 1:
return False
return True
def probablyPrime(p, accuracy=100):
if p == 2 or p == 3: return True
if p < 2: return False
exponent, remainder = decompose(p - 1)
for _ in range(accuracy):
possibleWitness = random.randint(2, p - 2)
if isWitness(possibleWitness, p, exponent, remainder):
return False
return True
""" Coupon-Collector Problem (approximation)
How many random-samplings with replacement are expected to observe each element at least once
"""
def couponcollector(n):
return int(n*math.log(n))
""" Non-prime random-sampling
"""
def get_random_nonprime(min, max):
max_trials = couponcollector(max-min)
for i in range(max_trials):
candidate = random.randint(min, max)
if not probablyPrime(candidate):
return candidate
return -1
# TEST
print(get_random_nonprime(1000, 10000000))

Prime number generation using Fibonacci possible?

I'm generating prime numbers from Fibonacci as follows (using Python, with mpmath and sympy for arbitrary precision):
from mpmath import *
def GCD(a,b):
while a:
a, b = fmod(b, a), a
return b
def generate(x):
mp.dps = round(x, int(log10(x))*-1)
if x == GCD(x, fibonacci(x-1)):
return True
if x == GCD(x, fibonacci(x+1)):
return True
return False
for x in range(1000, 2000)
if generate(x)
print(x)
It's a rather small algorithm but seemingly generates all primes (except for 5 somehow, but that's another question). I say seemingly because a very little percentage (0.5% under 1000 and 0.16% under 10K, getting less and less) isn't prime. For instance under 1000: 323, 377 and 442 are also generated. These numbers are not prime.
Is there something off in my script? I try to account for precision by relating the .dps setting to the number being calculated. Can it really be that Fibonacci and prime numbers are seemingly so related, but then when it's get detailed they aren't? :)
For this type of problem, you may want to look at the gmpy2 library. gmpy2 provides access to the GMP multiple-precision library which includes gcd() and fib() functions which calculate the greatest common divisor and the n-th fibonacci numbers quickly, and only using integer arithmetic.
Here is your program re-written to use gmpy2.
import gmpy2
def generate(x):
if x == gmpy2.gcd(x, gmpy2.fib(x-1)):
return True
if x == gmpy2.gcd(x, gmpy2.fib(x+1)):
return True
return False
for x in range(7, 2000):
if generate(x):
print(x)
You shouldn't be using any floating-point operations. You can calculate the GCD just using the builtin % (modulo) operator.
Update
As others have commented, you are checking for Fibonacci pseudoprimes. The actual test is slightly different than your code. Let's call the number being tested n. If n is divisible by 5, then the test passes if n evenly divides fib(n). If n divided by 5 leaves a remainder of either 1 or 4, then the test passes if n evenly divides fib(n-1). If n divided by 5 leaves a remainder of either 2 or 3, then the test passes if n evenly divides fib(n+1). Your code doesn't properly distinguish between the three cases.
If n evenly divides another number, say x, it leaves a remainder of 0. This is equivalent to x % n being 0. Calculating all the digits of the n-th Fibonacci number is not required. The test just cares about the remainder. Instead of calculating the Fibonacci number to full precision, you can calculate the remainder at each step. The following code calculates just the remainder of the Fibonacci numbers. It is based on the code given by #pts in Python mpmath not arbitrary precision?
def gcd(a,b):
while b:
a, b = b, a % b
return a
def fib_mod(n, m):
if n < 0:
raise ValueError
def fib_rec(n):
if n == 0:
return 0, 1
else:
a, b = fib_rec(n >> 1)
c = a * ((b << 1) - a)
d = b * b + a * a
if n & 1:
return d % m, (c + d) % m
else:
return c % m, d % m
return fib_rec(n)[0]
def is_fib_prp(n):
if n % 5 == 0:
return not fib_mod(n, n)
elif n % 5 == 1 or n % 5 == 4:
return not fib_mod(n-1, n)
else:
return not fib_mod(n+1, n)
It's written in pure Python and is very quick.
The sequence of numbers commonly known as the Fibonacci numbers is just a special case of a general Lucas sequence L(n) = p*L(n-1) - q*L(n-2). The usual Fibonacci numbers are generated by (p,q) = (1,-1). gmpy2.is_fibonacci_prp() accepts arbitrary values for p,q. gmpy2.is_fibonacci(1,-1,n) should match the results of the is_fib_pr(n) given above.
Disclaimer: I maintain gmpy2.
This isn't really a Python problem; it's a math/algorithm problem. You may want to ask it on the Math StackExchange instead.
Also, there is no need for any non-integer arithmetic whatsoever: you're computing floor(log10(x)) which can be done easily with purely integer math. Using arbitrary-precision math will greatly slow this algorithm down and may introduce some odd numerical errors too.
Here's a simple floor_log10(x) implementation:
from __future__ import division # if using Python 2.x
def floor_log10(x):
res = 0
if x < 1:
raise ValueError
while x >= 1:
x //= 10
res += 1
return res

Python Syntax Problem

I'm just getting back into Project Euler and have lost my account and solutions, so I'm back on problem 7. However, my code doesn't work. It seems fairly elementary to me, can someone help me debug my (short) script?
Should find the 10001st Prime.
#!/usr/bin/env python
#encoding: utf-8
"""
P7.py
Created by Andrew Levenson on 2010-06-29.
Copyright (c) 2010 __ME__. All rights reserved.
"""
import sys
import os
from math import sqrt
def isPrime(num):
flag = True
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
flag = False
if flag == True:
return True
else:
return False
def main():
i, n = 1, 3
p = False
end = 6
while end - i >= 0:
p = isPrime(n)
if p == True:
i = i + 1
print n
n = n + 1
if __name__ == '__main__':
main()
Edit*: Sorry, the issue is it says every number is prime. :/
The syntax is fine (in Python 2). The semantics has some avoidable complications, and this off-by-one bug:
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
flag = False
range(2, Y) goes from 2 included to Y excluded -- so you're often not checking the last possible divisor and thereby deeming "primes" many numbers that aren't. As the simplest fix, try a 1 + int(... in that range. After which, removing those avoidable complications is advisable: for example,
if somebool: return True
else: return False
is never warranted, as the simpler return somebool does the same job.
A simplified version of your entire code (with just indispensable optimizations, but otherwise exactly the same algorithm) might be, for example:
from math import sqrt
def isPrime(num):
for x in range(3, int(1 + sqrt(num)), 2):
if num % x == 0: return False
return True
def main():
i, n = 0, 3
end = 6
while i < end:
if isPrime(n):
i += 1
print n
n += 2
if __name__ == '__main__':
main()
"Return as soon as you know the answer" was already explained, I've added one more crucial optimization (+= 2, instead of 1, for n, as we "know" even numbers > 3 are not primes, and a tweak of the range for the same reason).
It's possible to get cuter, e.g.:
def isPrime(num):
return all(num % x for x n range(3, int(1 + sqrt(num)), 2))
though this may not look "simpler" if you're unfamiliar with the all built-in, it really is, because it saves you having to do (and readers of the code having to follow) low level logic, in favor of an appropriate level of abstraction to express the function's key idea, that is, "num is prime iff all possible odd divisors have a [[non-0]] remainder when the division is tried" (i.e., express the concept directly in precise, executable form). The algorithm within is actually still identical.
Going further...:
import itertools as it
def odd():
for n in it.count(1):
yield n + n + 1
def main():
end = 5
for i, n in enumerate(it.ifilter(isPrime, odd())):
print n
if i >= end: break
Again, this is just the same algorithm as before, just expressed at a more appropriate level of abstraction: the generation of the sequence of odd numbers (from 3 included upwards) placed into its own odd generator, and some use of the enumerate built-in and itertools functionality to avoid inappropriate (and unneeded) low-level expression / reasoning.
I repeat: no fundamental optimization applied yet -- just suitable abstraction. Optimization of unbounded successive primes generation in Python (e.g. via an open-ended Eratosthenes Sieve approach) has been discussed in depth elsewhere, e.g. here (be sure to check the comments too!). Here I was focusing on showing how (with built-ins such as enumerate, all, and any, the crucial itertools, plus generators and generator expressions) many "looping" problems can be expressed in modern Python at more appropriate levels of abstraction than the "C-inspired" ones that may appear most natural to most programmers reared on C programming and the like. (Perhaps surprisingly to scholars used to C++'s "abstraction penalty" first identified by Stepanov, Python usually tends to have an "abstraction premium" instead, especially if itertools, well known for its blazing speed, is used extensively and appropriately... but, that's really a different subject;-).
Isn't this better?
def isPrime(num):
for x in range(2,int(sqrt(num))):
if( num % x == 0 ):
return False
return True
And this:
def main():
i, n = 1, 3
while i <= 6:
if isPrime(n):
i = i + 1
print n
n = n + 1
Also, I'm not seeing a 10001 anywhere in there...

Categories

Resources