Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pwang00
GitHub Repository: pwang00/Cryptographic-Attacks
Path: blob/master/Public Key/Factoring/utils.py
336 views
1
# Sage does not implement xgcd or modular multiplicative inverses for polynomials over composite rings, so
2
# We just roll our own implementation here (which is really adapted pseudocode from Wikipedia)
3
import random
4
from sage.all import *
5
6
def polynomial_egcd(f, g):
7
"""
8
Calculates the polynomial inverse of f with respect to g.
9
:param f: a univariate polynomial.
10
:param g: a univariate polynomial.
11
:return: a polynomial h such that f*h = 1 (mod g)
12
"""
13
old_r, r = f, g
14
old_s, s = 1, 0
15
old_t, t = 0, 1
16
17
while r != 0:
18
try:
19
q = old_r // r
20
old_r, r = r, old_r - q * r
21
old_s, s = s, old_s - q * s
22
old_t, t = t, old_t - q * t
23
except:
24
raise ValueError("No inverse for r in Q.", r)
25
26
return old_r, old_s, old_t
27
28
def polynomial_inv_mod(f, g):
29
"""
30
Calculates the polynomial inverse of f with respect to g.
31
:param f: a univariate polynomial.
32
:param g: a univariate polynomial.
33
:return: a polynomial h such that f*h = 1 (mod g)
34
"""
35
g, s, _ = polynomial_egcd(f, g)
36
37
if g.degree() > 1:
38
raise ValueError("No polynomial inverse exists.")
39
40
return s * g.lc()**-1
41
42
def generate_cm_prime(D, n=512):
43
"""
44
Generates an approximately 2n-bit prime p such that 4p - 1 = D * s^2
45
:param D: a squarefree integer.
46
:param n: bit-length of s.
47
:return: prime p
48
"""
49
assert D.is_squarefree(), "D must be squarefree."
50
51
while True:
52
s = randint(2**n, 2**(n + 1) - 1)
53
t = D * s**2 + 1
54
p = t // 4
55
56
if is_prime(p) and t % 4 == 0:
57
return p
58