-
Notifications
You must be signed in to change notification settings - Fork 1
/
verifying_algorithm.py
164 lines (114 loc) · 3.81 KB
/
verifying_algorithm.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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import logging
import hashlib
import functools
import ecdsa
from ecdsa.ecdsa import curve_secp256k1
from ecdsa.curves import SECP256k1
from ecdsa import numbertheory
from functools import reduce
def verify_ring_signature(message, y, c_0, s, Y, G=SECP256k1.generator):
"""
Verifies if a valid signature was made by a key inside a set of keys.
PARAMS
------
message: (str) message whos' signature is being verified.
y: (list) set of public keys with which the message was signed.
Signature:
c_0: (int) initial value to reconstruct the ring.
s: (list) vector of secrets used to create ring.
Y = (int) Link of unique signer.
G: (ecdsa.ellipticcurve.Point) Base point for the elliptic curve.
RETURNS
-------
Boolean value indicating if signature is valid.
"""
n = len(y)
c = [c_0] + [0] * (n - 1)
H = H2(y)
for i in range(n):
z_1 = (G * s[i]) + (y[i] * c[i])
z_2 = (H * s[i]) + (Y * c[i])
if i < n - 1:
c[i + 1] = H1([y, Y, message, z_1, z_2])
else:
return c_0 == H1([y, Y, message, z_1, z_2])
return False
def map_to_curve(x, P=curve_secp256k1.p()):
"""
Maps an integer to an elliptic curve.
PARAMS
------
x: (int) number to be mapped into E.
P: (ecdsa.curves.curve_secp256k1.p) Modulo for elliptic curve.
RETURNS
-------
(ecdsa.ellipticcurve.Point) Point in Curve
"""
x = x - 1
found = False
while not found:
x = x + 1
alpha =(((pow(x, 3, P) + (curve_secp256k1.a() * x))) + curve_secp256k1.b()) % P
try:
beta = numbertheory.square_root_mod_prime(alpha, P)
if [beta % 2 == 0] != [x % 2 != 0]:
y = beta
else:
y = P - beta
found = True
except Exception as e:
pass
return ecdsa.ellipticcurve.Point(curve_secp256k1, x, y)
def H1(msg):
"""
Return an integer representation of the hash of a message. The
message can be a list of messages that are concatenated with the
concat() function.
PARAMS
------
msg: (str or list) message(s) to be hashed.
RETURNS
-------
Integer representation of hexadecimal digest from hash function.
"""
return int(hashlib.sha256(concat(msg).encode()).hexdigest(), 16)
def H2(msg):
"""
Hashes a message into an elliptic curve point.
PARAMS
------
msg: (str or list) message(s) to be hashed.
RETURNS
-------
ecdsa.ellipticcurve.Point to curve.
"""
return map_to_curve(H1(msg))
def concat(params):
"""
Concatenates a list of parameters into a bytes. If one
of the parameters is a list, calls itself recursively.
PARAMS
------
params: (list) list of elements, must be of type:
- int
- list
- str
- ecdsa.ellipticcurve.Point
RETURNS
-------
concatenated bytes of all values.
"""
n = len(params)
bytes_value = [0] * n
for i in range(n):
if type(params[i]) is int:
bytes_value[i] = str(params[i])
if type(params[i]) is list:
bytes_value[i] = concat(params[i])
if type(params[i]) is ecdsa.ellipticcurve.Point:
bytes_value[i] = str(params[i].x()) + str(params[i].y())
if type(params[i]) is str:
bytes_value[i] = params[i]
if bytes_value[i] == 0:
bytes_value[i] = str(params[i].x()) + str(params[i].y())
return functools.reduce(lambda x, y: x + y, bytes_value)