Commit 43c5ff3f864fddfde8a4ce4d130635c8110d8ccb

BUGFIX: fixed several niggling errors in KSW
KSW.py
(167 / 35)
  
2929
3030#############################################
3131# Cryptosystem #
32#############################################
32#############################################
3333
34class Cryptosystem:
35
36 params = None
37 pairing = None
38 # generates G
39 g_G = None
40 # generates G_p
41 g_G_p = None
42 # generates G_q
43 g_G_q = None
44 # generates G_r
34class PublicKey:
35 g_G_p = None
4536 g_G_r = None
46 # random element of G_r
47 R0 = None
48 # Rs[] = ((Ri,0), (Ri, 1)) * n, R e G_r
49 Rs = None
50 # Hs[] = ((Hi,0), (Hi, 1)) * n, H e G_p
37 Q = None
38 vector = None
39 def __init__(self, gen_p, gen_r, Q, vector):
40 self.g_G_p = gen_p
41 self.g_G_r = gen_r
42 self.Q = Q
43 self.vector = vector
44
45class MasterSecretKey:
46 p = None
47 q = None
48 r = None
49 g_G_q = None
5150 Hs = None
51 def __init__(self, p, q, r, g_G_q, Hs):
52 self.p = p
53 self.q = q
54 self.r = r
55 self.g_G_q = g_G_q
56 self.Hs = Hs
57
58
59class Cryptosystem:
5260
53 def __init__(self, i) -> "(PK, SK)":
61 def __init__(self, security) -> "(PK, SK)":
62 self.security = security
5463 # select p, q, r
5564 p = get_random_prime(200)
5665 q = get_random_prime(200)
5766 r = get_random_prime(200)
5867 # make n
59 n = p*q*r
68 self.n = p*q*r
6069 # build the params
61 self.params = Parameters(n=n)
70 params = Parameters(n=self.n)
6271 # build the pairing
6372 self.pairing = Pairing(params)
6473 # find the generators for the G_p, G_q, and G_r subgroups
65 self.g_G = Element.random(pairing, G1)**n
66 self.g_G_p = Element.random(pairing, G1)**(q*r)
67 self.g_G_r = Element.random(pairing, G1)**(p*q)
68 self.g_G_q = Element.random(pairing, G1)**(p*r)
74 g_G = Element.random(self.pairing, G1)**self.n
75 g_G_p = Element.random(self.pairing, G1)**(q*r)
76 g_G_r = Element.random(self.pairing, G1)**(p*q)
77 g_G_q = Element.random(self.pairing, G1)**(p*r)
6978 # choose R0
70 self.R0 = self.g_G_r ** get_random(r)
79 R0 = g_G_r ** Element.random(self.pairing, Zr)
7180 # choose the random R's
81 Rs = []
82 for i in range(security):
83 ri1 = g_G_r**Element.random(self.pairing, Zr)
84 ri2 = g_G_r**Element.random(self.pairing, Zr)
85 Rs.append((ri1, ri2))
7286 # choose the random H's
87 Hs = []
88 for i in range(security):
89 hi1 = g_G_p**get_random(p)
90 hi2 = g_G_p**get_random(p)
91 Hs.append((hi1, hi2))
7392 # calculate Q
74 pass
93 Q = g_G_q * R0
94 # build the vector
95 vector = []
96 for pos, h in enumerate(Hs):
97 Ri = Rs[pos]
98 vi = (Ri[0]*h[0], Ri[1]*h[0])
99 vector.append(vi)
100 # build the public and master secret keys
101 self.pk = PublicKey(g_G_p, g_G_r, Q, vector)
102 self.sk = MasterSecretKey(p, q, r, g_G_q, Hs)
103
104
105 def keygen(self, v: "description of a predicate") -> "SK_f":
106 R5 = self.pk.g_G_r**Element.random(self.pairing, Zr)
107 Q6 = self.sk.g_G_q**Element.random(self.pairing, Zr)
108 Rs = []
109 for i in range(self.security):
110 # build r1
111 r1 = get_random(self.sk.p)
112 # build r2
113 r2 = get_random(self.sk.p)
114 Rs.append((r1, r2))
115 f1 = get_random(self.sk.q)
116 f2 = get_random(self.sk.q)
117 K = R5*Q6
118 for pos in range(self.security):
119 # get h1, h2
120 h1, h2 = self.sk.Hs[pos]
121 # get r1, r2
122 r1, r2 = Rs[pos]
123 # form the intermediate value
124 ir1 = -r1
125 ir2 = -r2
126 i = (h1**(-r1)) * (h2**(-r2))
127 K = K * i
128 Ks = []
129 for pos in range(self.security):
130 r1, r2 = Rs[pos]
131 K1 = (self.pk.g_G_p**r1) * (self.sk.g_G_q**(f1*v[pos]))
132 K2 = (self.pk.g_G_p**r2) * (self.sk.g_G_q**(f2*v[pos]))
133 Ks.append((K1, K2))
134 return (K, Ks)
135
75136
76 def keygen(sk: "master secret key", f: "description of a predicate") -> "SK_f":
77 pass
137 def encrypt(self, x: "vector of elements in Zr") -> "ciphertext":
138 s = Element.random(self.pairing, Zr)
139 a = Element.random(self.pairing, Zr)
140 b = Element.random(self.pairing, Zr)
141 Rs = []
142 for i in range(self.security):
143 r1 = self.pk.g_G_r**Element.random(self.pairing, Zr)
144 r2 = self.pk.g_G_r**Element.random(self.pairing, Zr)
145 Rs.append((r1, r2))
146 C0 = self.pk.g_G_p**s
147 Cs = []
148 for i in range(self.security):
149 c1i = (self.pk.vector[i][0]**s)
150 c1i2 = (self.pk.Q**(a*x[i]))*Rs[i][0]
151 c1 = c1i*c1i2
152 c2i = (self.pk.vector[i][1]**s)
153 c2i2 = (self.pk.Q**(b*x[i]))*Rs[i][1]
154 c2 = c2i*c2i2
155 Cs.append((c1, c2))
156 return (C0, Cs)
78157
79 def encrypt(pk: "public key", i: "attribute", m: "message") -> "ciphertext":
80 pass
81
82 def decrypt(c: "ciphertext", sk_f: "secret key corresponding to predicate f") -> "message or T":
83 pass
158 def decrypt(self, c: "ciphertext", sk_f: "secret key corresponding to predicate f") -> "message or T":
159 output = self.pairing.apply(c[0], sk_f[0])
160 for i in range(self.security):
161 j = self.pairing.apply(c[1][i][0], sk_f[1][i][0])
162 k = self.pairing.apply(c[1][i][1], sk_f[1][i][1])
163 output = output * j * k
164 return output
84165
85166#############################################
86167# Test logic #
87168#############################################
88169
89if __name__ == "__main__":
170def test():
171 # we're testing the ability to evaluate a polynomial,
172 # specifically:
173 # X^2 + 27X + 152
174 c = Cryptosystem(3)
175 # build the secret key corresponding to the above polynomial
176 skf = c.keygen([0, 27, 152])
177 print(skf)
178 # we now build the vector corresponding to 19, a solution to
179 # the above
180 d0 = Element(c.pairing, Zr, 19**2 % c.n)
181 d1 = Element(c.pairing, Zr, 19 % c.n)
182 d2 = Element(c.pairing, Zr, 1 % c.n)
183 v = [d0, d1, d2]
184 e = c.encrypt(v)
185 print(e)
186 # decrypt- should be 0
187 print("output: ", c.decrypt(e, skf))
188
189def test2():
190 # build the polynomial vector
191 Pv = [1, -27, 152] # = X^2 - 27X + 152 = (X - 8)(X - 19)
192 # build the X vector
193 Xv = [19**3, 19**2, 19**1]
194 # build the random primes
195 p = get_random_prime(100)
196 q = get_random_prime(100)
197 r = get_random_prime(100)
198 n = p*q*r
199 # build the parameters
200 params = Parameters(n=n)
201 # build the pairing
202 pairing = Pairing(params)
203 # get the generators for G_p, G_q, G_r
204 g_G_p = Element.random(pairing, G1)**q*r
205 g_G_q = Element.random(pairing, G1)**p*r
206 g_G_r = Element.random(pairing, G1)**p*q
207 # test the generators
208 assert(pairing.apply(g_G_p, g_G_r) == 1)
209 assert(pairing.apply(g_G_r, g_G_q) == 1)
210 # select the random integers modulo n
211 a = Element.random(pairing, Zr)
212 b = Element.random(pairing, Zr)
213 # get random integers modulo q
214 f1 = Element.random(pairing, Zr)
215 f2 = Element.random(pairing, Zr)
216 # perform the check
217 result = Element.zero(pairing, GT)
218 for pos, i in enumerate(Pv):
219 result += pairing.apply(g_G_q, g_G_q)**(((a*f1+b*f2)) * Xv[pos]*i)
220 return result
90221
91 import sys
222if __name__ == "__main__":
223 test()
Makefile
(2 / 1)
  
1414
1515play:
1616 $(BUILD)
17 cd $(BUILD_DIR); python3 -i -c "from pypbc import *"
17 cd $(BUILD_DIR); python3 -i -c "from pypbc import *; from KSW import *"
1818 $(CLEAN)
1919
2020test:
2121 $(BUILD)
2222 chmod +x build/lib.linux-i686-3.0/test.py
2323 $(BUILD_DIR)/test.py -v
24 python3 $(BUILD_DIR)/KSW.py
2425 $(CLEAN)
2526
2627commit:
pypbc.c
(39 / 12)
  
354354 // incref the pairing we depend on
355355 Py_INCREF(p);
356356
357 // set the pairing
358 e3->pairing = e1->pairing;
359
357360 // mark it ready
358361 e3->ready = 1;
359362
768768// multiplies two elements
769769// note that elements from any ring can be multiplied by those in Zr.
770770PyObject *Element_mult(PyObject* a, PyObject *b) {
771 // convert both objects to Elements
771 // convert a to an element
772772 Element *e1 = (Element*)a;
773 Element *e2 = (Element*)b;
774 // make sure they're in the same ring
775 if (e1->group != e2->group && e2->group != Zr) {
776 PyErr_SetString(PyExc_ValueError, "elements must be in the same group or Zr.");
777 return NULL;
778 }
773
779774 // build the result element
780775 Element *e3 = (Element *)ElementType.tp_alloc(&ElementType, 0);
776
781777 // note that the result is in the same ring *and pairing*
782778 element_init_same_as(e3->pbc_element, e1->pbc_element);
783779 e3->group = e1->group;
784780 Py_INCREF(e1->pairing);
785781 e3->pairing = e1->pairing;
786 // add the elements and store the result in e3
787 if (e2->group != Zr) {
788 element_mul(e3->pbc_element, e1->pbc_element, e2->pbc_element);
789 } else {
790 element_mul_zn(e3->pbc_element, e1->pbc_element, e2->pbc_element);
782
783 // check to see if b is an integer
784 if(PyLong_Check(b)) {
785 // cast it to an MPZ
786 mpz_t i;
787 mpz_init(i);
788 pynum_to_mpz(b, i);
789 element_mul_mpz(e3->pbc_element, e1->pbc_element, i);
790 mpz_clear(i);
791 } else if (PyObject_TypeCheck(b, &ElementType)) {
792 Element *e2 = (Element*)b;
793 // make sure they're in the same group
794 if (e1->group != e2->group && e2->group != Zr) {
795 PyErr_SetString(PyExc_ValueError, "elements must be in the same group or Zr.");
796 return NULL;
797 }
798 // add the elements and store the result in e3
799 if (e2->group != Zr) {
800 element_mul(e3->pbc_element, e1->pbc_element, e2->pbc_element);
801 } else {
802 element_mul_zn(e3->pbc_element, e1->pbc_element, e2->pbc_element);
803 }
791804 }
792805 // cast and return
793806 e3->ready = 1;
834834// raises element a to the power of b
835835// b can be either an element or an integer
836836PyObject *Element_pow(PyObject* a, PyObject *b, PyObject *c) {
837
838 // check the types
839 if (!PyObject_TypeCheck(a, &ElementType)) {
840 PyErr_SetString(PyExc_TypeError, "Argument 1 must be an element.");
841 return NULL;
842 }
843
837844 // convert a to a pbc type
838845 Element *e1 = (Element*)a;
839846
867867 return NULL;
868868 }
869869 element_pow_zn(e3->pbc_element, e1->pbc_element, e2->pbc_element);
870 } else {
871 PyErr_SetString(PyExc_TypeError, "Argument 2 must be an integer or element.");
872 return NULL;
870873 }
874
871875 // cast and return
872876 e3->ready = 1;
873877 return (PyObject*)e3;
setup.py
(1 / 1)
  
1313 author="Geremy Condra",
1414 author_email="debatem1@gmail.com",
1515 url="geremycondra.net",
16 py_modules=["test"],
16 py_modules=["test", "KSW"],
1717 ext_modules=[pbc]
1818)
test.py
(31 / 0)
  
151151 self.e2 = Element(self.pairing, Zr, value=5)
152152 self.e3 = self.e1 * self.e2
153153 self.failUnlessEqual(str(self.e3), "15")
154 try: self.e3 * 5
155 except: self.fail()
156 self.e4 = self.pairing.apply(Element.random(self.pairing, G1), Element.random(self.pairing, G2))
157 self.e5 = self.pairing.apply(Element.random(self.pairing, G1), Element.random(self.pairing, G2))
158 try: self.e4 * self.e5
159 except: self.fail()
154160
155161 def test_pow(self):
156162 self.e1 = Element(self.pairing, Zr, value=3)
157163 self.e2 = Element(self.pairing, Zr, value=2)
158164 self.e3 = pow(self.e1, self.e2)
159165 self.failUnlessEqual(str(self.e3), "9")
166 try:
167 self.e1**(1,2)
168 self.fail()
169 except:
170 pass
160171
161172 def test_cmp(self):
162173 self.e1 = Element.random(self.pairing, G1)
258258
259259 # compare
260260 self.failIfEqual(temp1, temp2)
261
262 def test_auth(self):
263 # taken from paul miller's PBC::Crypt module tutorial
264 params = Parameters(qbits=512, rbits=160)
265 pairing = Pairing(params)
266 p = Element.random(pairing, G2)
267 s = Element.random(pairing, Zr)
268 public_key = p**s
269 # not actually from a hash. I don't really care.
270 Q_0 = Element.from_hash(pairing, G1, "node_id=22609")
271 # ditto
272 Q_1 = Element.from_hash(pairing, G1, "node_id=9073")
273 d_0 = Q_0**s
274 d_1 = Q_1**s
275 k_01_a = pairing.apply(Q_0, d_1)
276 k_01_b = pairing.apply(d_0, Q_1)
277 self.failUnlessEqual(k_01_a, k_01_b)
278 k_10_a = pairing.apply(Q_1, d_0)
279 k_10_b = pairing.apply(d_1, Q_0)
280 self.failUnlessEqual(k_10_a, k_10_b)
261281
262282
263283if __name__ == '__main__':