-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquadrature_successive.py
57 lines (45 loc) · 1.59 KB
/
quadrature_successive.py
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
# calcola x^y mod p
# stampa ogni passaggio
# l'algoritmo esegue O(logy) moltiplicazioni, complessivamente è O(n^3)
def quadrature_successive(x: int, y: int, p: int):
if p <= 0:
print(f'ERRORE: non posso eseguire l\'algoritmo se p <= 0')
return -1
if y < 0:
print(f'ERRORE: non posso eseguire l\'algoritmo se y < 0, mica mi hai preso per EE?! Lol.')
return -1
if y == 0:
print(f'{x}**0 mod {p} = 1')
return 1
if x >= p:
print(f'riduco {x} in {x % p} facendo {x} mod {p}')
x = x % p
biny = bin(y)[::-1][:-2]
print(f'{x}**1 mod {p} = {x}')
xpower = [x]
maxexp = len(biny) # ceil(log(y, 2)) ma meno pesante
for i in range(1, maxexp):
new = pow(xpower[-1], 2, p)
print(f'{x}**{2**(i)} mod {p} = ({x}**{2**(i-1)})**2 mod {p} = {xpower[-1]}**2 mod {p} = {new}')
xpower.append(new)
result = 1
str = f'{x}**{y} mod {p} = '
for i, digit in enumerate(biny):
if(digit == '1'):
result *= xpower[i]
str += f'({x}**{2**i} mod {p})'
print('------------------------------------------------')
fin = result % p
str += f' mod {p} = {fin}'
print('\n' + str)
return fin
x = 3
y = 55
p = 881
def main():
print(f'calcolo {x}**{y} mod {p}...')
output = quadrature_successive(x,y,p)
if(output != -1): print(f'\n{x}**{y} mod {p} = {output}.')
if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()