-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathscheme.py
More file actions
134 lines (111 loc) · 3.59 KB
/
Copy pathscheme.py
File metadata and controls
134 lines (111 loc) · 3.59 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
123
124
125
126
127
128
129
130
131
132
133
134
"""
BLS signature scheme.
Example:
>>> m = [3] * 2 # messages
>>> t, n = 2, 3 # number of authorities
>>> params = setup() # generate the public parameters.
>>> (sk, vk) = ttp_keygen(params, t, n) # generate key
>>> aggr_vk = aggregate_vk(params, vk) # aggregate verification keys
>>> sigs = [sign(params, ski, m) for ski in sk] # sign
>>> sigma = aggregate_sigma(params, sigs) # aggregate credentials
>>> assert verify(params, aggr_vk, sigma, m) # verify signature
"""
from bplib.bp import BpGroup, G2Elem
from bls.utils import *
def setup():
"""
Generate the public parameters.
Returns:
- params: the publc parameters
"""
G = BpGroup()
(g1, g2) = G.gen1(), G.gen2()
(e, o) = G.pair, G.order()
return (G, o, g1, g2, e)
def ttp_keygen(params, t, n):
"""
Generate keys for threshold signature (executed by a TTP).
Parameters:
- `params`: public parameters generated by `setup`
- `t` (integer): the threshold parameter
- `n` (integer): the total number of authorities
Returns:
- `sk` [Bn]: array containing the secret key of each authority
- `vk` [G2Elem]: array containing the verification key of each authority
"""
assert n >= t and t > 0
(G, o, g1, g2, e) = params
# generate polynomials
v = [o.random() for _ in range(0,t)]
# generate shares
sk = [poly_eval(v,i) % o for i in range(1,n+1)]
# set keys
vk = [xi*g2 for xi in sk]
return (sk, vk)
def aggregate_vk(params, vks, threshold=True):
"""
Aggregate the verification keys.
Parameters:
- `params`: public parameters generated by `setup`
- `vks` [G2Elem]: array containing the verification key of each authority
- `threshold` (bool): optional, whether to use threshold cryptography or not
Returns:
- `aggr_vk` (G2Elem): aggregated verification key
"""
(G, o, g1, g2, e) = params
# evaluate all lagrange basis polynomial li(0)
filter = [vk for vk in vks if vk is not None]
indexes = [i+1 for i, vk in enumerate(vks) if vk is not None]
l = lagrange_basis(indexes, o) if threshold else [1 for _ in vks]
# aggregate keys
aggr_vk = ec_sum([l[i]*filter[i] for i in range(len(filter))])
return aggr_vk
def sign(params, sk, m):
"""
Sign messages.
Parameters:
- `params`: public parameters generated by `setup`
- `sk` (Bn): the secret key of the authority
- `m` [Bn]: array containing the messages
Returns:
- `sigma_tilde` (G1Elem, G1Elem): blinded credential
"""
assert len(m) > 0
(G, o, g1, g2, e) = params
digest = hash(m)
h = G.hashG1(digest)
sigma = sk*h
return sigma
def aggregate_sigma(params, sigs, threshold=True):
"""
Aggregate partial signatures.
Parameters:
- `params`: public parameters generated by `setup`
- `sigs` [G1Elem]: array of partial credentials
- `threshold` (bool): optional, whether to use threshold cryptography or not
Returns:
- `aggr_sigma` (G1Elem): aggregated credential
"""
(G, o, g1, g2, e) = params
# evaluate all lagrange basis polynomial li(0)
filter = [sig for sig in sigs if sig is not None]
indexes = [i+1 for i, sig in enumerate(sigs) if sig is not None]
l = lagrange_basis(indexes, o) if threshold else [1 for _ in sigs]
# aggregate sigature
aggr_s = ec_sum([l[i]*filter[i] for i in range(len(filter))])
return aggr_s
def verify(params, aggr_vk, sigma, m):
"""
Verify signature.
Parameters:
- `params`: public parameters generated by `setup`
- `aggr_vk` (G2Elem): aggregated verification key
- `sigma` (G1Elem): signature
- `m` [Bn]: array containing the messages
Returns:
- `ret` (bool): whether the credential verifies
"""
(G, o, g1, g2, e) = params
digest = hash(m)
h = G.hashG1(digest)
return not h.isinf() and e(sigma, g2) == e(h, aggr_vk)