-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprime.py
More file actions
executable file
·122 lines (105 loc) · 3.09 KB
/
Copy pathprime.py
File metadata and controls
executable file
·122 lines (105 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/python3
from ctypes import *
import random
import logging
import log
logger = logging.getLogger('test.prime')
__all__ = ['isPrime', 'getRandPrime', 'inv']
libgmp = CDLL('libgmp.so.10')
class _mpz_t(Structure):
_fields_ = [('_mp_alloc', c_int), ('_mp_size', c_int), ('_mp_d', POINTER(c_ulong))]
def _mpz_init_set_str(p, s, base):
libgmp.__gmpz_init_set_str(pointer(p), s, base)
def _mpz_probab_prime_p(p, reps):
return libgmp.__gmpz_probab_prime_p(pointer(p), reps)
def isPrime(n):
"""Test if n is a prime."""
if type(n) != int:
raise ValueError('type error, n should be int type')
v = _mpz_t()
_mpz_init_set_str(v, bytes(str(n), encoding = 'ascii'), 10)
if _mpz_probab_prime_p(v, 50) == 0:
return False
else:
return True
def getRandPrime(bits = 1024):
"""Get a random prime."""
r = random.SystemRandom()
v = r.getrandbits(bits)
while not isPrime(v):
v = r.getrandbits(bits)
return v
def inv(v, p):
v = v % p
if v < 0:
v = v + p
if v == 0:
raise ValueError('v should not be zero in inv')
elif v == 1:
return 1
pp, vv = p, v
a, b = divmod(pp, vv)
l1=[1,0]
l2 = [0, 1]
l3 = list(map(lambda x: x[0] - a * x[1], zip(l1, l2)))
while b != 1:
pp, vv = vv, b
a, b = divmod(pp, vv)
l1 = l2
l2 = l3
l3 = list(map(lambda x: x[0] - a * x[1], zip(l1, l2)))
ret = l3[1]
ret = ret % p
if ret < 0:
ret = ret + p
return ret
def expmod(x, n, p):
b = n
t = x % p
ret = 1
while b != 0:
if b & 0x1 != 0:
ret *= t
ret %= p
t = t * t % p
b >>= 1
return ret
def isQR(a, p):
"""is a a quadratic residule mod p, p must be a prime
if p is prime, and (a, p) = 1, then
a is a a quadratic residule of p is eaual to
a ** ((p-1)/2) = 1 mod p
a is not a a quadratic residule of p is eaual to
a ** ((p-1)/2) = -1 mod p
"""
if not isPrime(p):
raise ValueError('p must be prime in sqrtmod in module {0}'.format(__name__))
return expmod(a, (p - 1)>>1, p) == 1
def sqrtmod(a, p):
"""Get x where x^2 = a mod p, p must be a prime
Cipolla's algorithm, refered to Wikipedia
"""
if not isPrime(p):
raise ValueError('p must be prime in sqrtmod in module {0}'.format(__name__))
if isQR(a, p) == False:
return None
r = random.SystemRandom()
while True:
b = r.randint(1, p-1)
if b * b % p == a % p:
return b
if isQR((b * b - a) % p, p) == False:
break
#define y, y**2 = 5, get solution in Fp(y) filed
t = [b, 1]
y2 = (b * b - a) % p
q = (p + 1) >> 1
ret = [1, 0]
while q != 0:
if q & 0x01 != 0:
ret = [(ret[0] * t[0] + y2 * ret[1] * t[1]) % p, (ret[0] * t[1] + ret[1] * t[0]) % p]
t = [(t[0] * t[0] + y2 * t[1] * t[1]) % p, 2 * t[0] * t[1] % p]
q >>= 1
if ret[1]:
logger.error('sqrt({0}, {1}), b = {2}, ret=({3}, {4})'.format(a, p, b, ret[0], ret[1]))
return ret[0]