Once you understand Shor’s period-finding then it is an easy piece of cake to also grasp how you can do factoring of for example a number with two large prime factors N=pq with p, q in P.
Today, we won’t go into the details how that is done, but look at a preliminary number theoretic relation, which enables us (in combination with Shor’s period finding) to do factoring. It’s a little difficult to understand the details, but the general picture is quite clear:
The probability is at least 1/2 that if a is a random member of Gpq for prime p and q, then the order r of a in Gpq satisfies both
r is evenand
ar/2≢−1(modpq)where a to the power of it’s order r is equal to 1(modpq). Let’s compress this already mathematical statement a little more. For a∈Gpq and p,q∈P it holds that:
Pr{ar/2≢−1(modpq)}⩾1/2with ar≡1(modpq), where I’ve omitted the r is even part, since the condition (2) can be subsumed in (1). Alright, let’s do some plotting:

The plot may be displayed rather small, so I’d suggest you click on it: What you’ll see is that all probabilities are larger or equal than 1/2 for some chosen prime pairs p and q. Apparently, the larger p and q the higher the probability that ar/2≢−1(modpq), which makes sense since there are then a lot more numbers not congruent to −1 in Gpq. Above the prime pairs (p,q) are in the range (3,3)…(19,19). When we extend the range then the probabilities get very close to 1:

This looks fantastic! Given this relation we can now factor a larger number with prime factors N=pq into it’s components, the details of which will follow in my next post.
01 #!/usr/bin/env python
02 ########################################################################
03
04 import itertools as it
05 import numpy as np
06 import random
07 import math
08 import gmpy2 as gmp
09
10 from matplotlib import pyplot as pp
11
12 ########################################################################
13
14 def POWERs(a, p, q):
15 fn = lambda k: a**k % (p*q)
16 return map(fn, range(p*q))
17 def ORDERs(a, p, q, rem=1):
18 f1 = lambda t: t[1] == rem
19 f2 = lambda t: t[0]
20 return map(f2, filter(f1, enumerate(POWERs(a, p, q))))
21 def ORDER(a, p, q):
22 return list(it.islice(ORDERs(a, p, q), 1, 2))[0] \
23 if a % p != 0 and a % q else None
24 def OSAMPLE(p, q, sz):
25 f1 = lambda _: random.randint(0, p*q - 1)
26 f2 = lambda a: (a, ORDER(a, p, q))
27 f3 = lambda t: t[1] is not None
28 return filter(f3, map(f2, map(f1, range(sz))))
29 def M1(p, q, sz):
30 fn = lambda t: t[1] % 2 == 0
31 return sum(map(fn, OSAMPLE(p, q, sz))) / sz
32 def M2(p, q, sz):
33 fn = lambda t: gmp.powmod(t[0], int(t[1]/2), p*q) != -1
34 return sum(map(fn, OSAMPLE(p, q, sz))) / sz
35
36 def PRIMEs(n):
37 sieve = [True] * n
38 for i in range(3,int(n**0.5)+1,2):
39 if sieve[i]: sieve[i*i::2*i]=[False]*int((n-i*i-1)/(2*i)+1)
40 return [i for i in range(3,n,2) if sieve[i]]
41
42 def PSAMPLE(sz):
43 return [(p1, p2) for p1 in PRIMEs(n=sz) for p2 in PRIMEs(n=sz)]
44
45 ps = PSAMPLE(sz=25)
46 m2 = list(map(lambda p: M2(p[0], p[1], sz=250), ps))
47
48 for i, p in enumerate(ps):
49 pass ## pp.text(i, m2[i], '(%s,%s)' % p)
50
51 pp.title('M2: Pr{a^{order(a)/2} != -1 (mod pq)} for random a in G{pq}')
52 pp.plot(m2, 'b*')
53 pp.grid()
54 pp.show()
55
56 ########################################################################
No comments:
Post a Comment