Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pwang00
GitHub Repository: pwang00/Cryptographic-Attacks
Path: blob/master/Public Key/RSA/blinding.sage
336 views
1
import random
2
3
def generate_private_params(e=65537, bits=1024):
4
while 1:
5
p = random_prime(2^bits, proof=False)
6
q = random_prime(2^bits, proof=False)
7
8
N = p * q
9
phi = (p - 1) * (q - 1)
10
11
if gcd(phi, e) != 1:
12
continue
13
14
d = inverse_mod(e, phi)
15
return N, d
16
17
18
def sign_message(m, N, d, deny=range(0, 10000)):
19
# deny is the range of messages that the signer refuses to sign.
20
if m in deny:
21
raise ValueError("Wait that's illegal")
22
s = pow(m, d, N)
23
return s
24
25
def test():
26
m = 10001
27
m2 = 10002
28
e = 65537
29
target_m = 2
30
31
N, d = generate_private_params()
32
33
s1 = sign_message(m, N, d)
34
s2 = sign_message(m2, N, d)
35
r = random.randint(0, N)
36
37
# Let's say the attacker wants to obtain a signature of m = 2. Obviously he can't do this directly since the sender won't allows a signature for 2.
38
# However, this does little to stop the attacker, who can pick an `r` in Z_n and request a signature $s$ for $r^e * m$.
39
# The signer doesn't know the attacker's intentions and assumes that because the message is not in a list of banned ones
40
# It is safe to sign. The attacker can then calculate the desired signature of $m$ by simply taking ((r^-1 mod N) * s) mod N.
41
42
s_r = inverse_mod(r, N) * sign_message(pow(r, e, N) * target_m, N, d)
43
sig_of_2 = sign_message(2, N, d, deny=[])
44
45
assert sig_of_2 == s_r
46
47
return s_r
48
49
if __name__ == "__main__":
50
test()
51
52