charm-crypto-framework 0.61.1__cp313-cp313-macosx_10_13_universal2.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. charm/__init__.py +5 -0
  2. charm/adapters/__init__.py +0 -0
  3. charm/adapters/abenc_adapt_hybrid.py +90 -0
  4. charm/adapters/dabenc_adapt_hybrid.py +145 -0
  5. charm/adapters/ibenc_adapt_hybrid.py +72 -0
  6. charm/adapters/ibenc_adapt_identityhash.py +80 -0
  7. charm/adapters/kpabenc_adapt_hybrid.py +91 -0
  8. charm/adapters/pkenc_adapt_bchk05.py +121 -0
  9. charm/adapters/pkenc_adapt_chk04.py +91 -0
  10. charm/adapters/pkenc_adapt_hybrid.py +98 -0
  11. charm/adapters/pksig_adapt_naor01.py +89 -0
  12. charm/config.py +7 -0
  13. charm/core/__init__.py +0 -0
  14. charm/core/benchmark/benchmark_util.c +353 -0
  15. charm/core/benchmark/benchmark_util.h +61 -0
  16. charm/core/benchmark/benchmarkmodule.c +476 -0
  17. charm/core/benchmark/benchmarkmodule.h +162 -0
  18. charm/core/benchmark.cpython-313-darwin.so +0 -0
  19. charm/core/crypto/AES/AES.c +1464 -0
  20. charm/core/crypto/AES.cpython-313-darwin.so +0 -0
  21. charm/core/crypto/DES/DES.c +113 -0
  22. charm/core/crypto/DES.cpython-313-darwin.so +0 -0
  23. charm/core/crypto/DES3/DES3.c +26 -0
  24. charm/core/crypto/DES3.cpython-313-darwin.so +0 -0
  25. charm/core/crypto/__init__.py +0 -0
  26. charm/core/crypto/cryptobase/XOR.c +80 -0
  27. charm/core/crypto/cryptobase/_counter.c +496 -0
  28. charm/core/crypto/cryptobase/_counter.h +54 -0
  29. charm/core/crypto/cryptobase/block_template.c +900 -0
  30. charm/core/crypto/cryptobase/block_template.h +69 -0
  31. charm/core/crypto/cryptobase/cryptobasemodule.c +220 -0
  32. charm/core/crypto/cryptobase/libtom/tomcrypt.h +90 -0
  33. charm/core/crypto/cryptobase/libtom/tomcrypt_argchk.h +44 -0
  34. charm/core/crypto/cryptobase/libtom/tomcrypt_cfg.h +186 -0
  35. charm/core/crypto/cryptobase/libtom/tomcrypt_cipher.h +941 -0
  36. charm/core/crypto/cryptobase/libtom/tomcrypt_custom.h +556 -0
  37. charm/core/crypto/cryptobase/libtom/tomcrypt_des.c +1912 -0
  38. charm/core/crypto/cryptobase/libtom/tomcrypt_hash.h +407 -0
  39. charm/core/crypto/cryptobase/libtom/tomcrypt_mac.h +496 -0
  40. charm/core/crypto/cryptobase/libtom/tomcrypt_macros.h +435 -0
  41. charm/core/crypto/cryptobase/libtom/tomcrypt_math.h +534 -0
  42. charm/core/crypto/cryptobase/libtom/tomcrypt_misc.h +103 -0
  43. charm/core/crypto/cryptobase/libtom/tomcrypt_pk.h +653 -0
  44. charm/core/crypto/cryptobase/libtom/tomcrypt_pkcs.h +90 -0
  45. charm/core/crypto/cryptobase/libtom/tomcrypt_prng.h +199 -0
  46. charm/core/crypto/cryptobase/stream_template.c +271 -0
  47. charm/core/crypto/cryptobase/strxor.c +229 -0
  48. charm/core/crypto/cryptobase.cpython-313-darwin.so +0 -0
  49. charm/core/engine/__init__.py +5 -0
  50. charm/core/engine/protocol.py +293 -0
  51. charm/core/engine/util.py +174 -0
  52. charm/core/math/__init__.py +0 -0
  53. charm/core/math/elliptic_curve/ecmodule.c +1986 -0
  54. charm/core/math/elliptic_curve/ecmodule.h +230 -0
  55. charm/core/math/elliptic_curve.cpython-313-darwin.so +0 -0
  56. charm/core/math/elliptic_curve.pyi +63 -0
  57. charm/core/math/integer/integermodule.c +2539 -0
  58. charm/core/math/integer/integermodule.h +145 -0
  59. charm/core/math/integer.cpython-313-darwin.so +0 -0
  60. charm/core/math/integer.pyi +76 -0
  61. charm/core/math/pairing/miracl/miracl_config.h +37 -0
  62. charm/core/math/pairing/miracl/miracl_interface.h +118 -0
  63. charm/core/math/pairing/miracl/miracl_interface2.h +126 -0
  64. charm/core/math/pairing/miracl/pairingmodule2.c +2094 -0
  65. charm/core/math/pairing/miracl/pairingmodule2.h +307 -0
  66. charm/core/math/pairing/pairingmodule.c +2230 -0
  67. charm/core/math/pairing/pairingmodule.h +241 -0
  68. charm/core/math/pairing/relic/pairingmodule3.c +1853 -0
  69. charm/core/math/pairing/relic/pairingmodule3.h +233 -0
  70. charm/core/math/pairing/relic/relic_interface.c +1337 -0
  71. charm/core/math/pairing/relic/relic_interface.h +217 -0
  72. charm/core/math/pairing/relic/test_relic.c +171 -0
  73. charm/core/math/pairing.cpython-313-darwin.so +0 -0
  74. charm/core/math/pairing.pyi +69 -0
  75. charm/core/utilities/base64.c +248 -0
  76. charm/core/utilities/base64.h +15 -0
  77. charm/schemes/__init__.py +0 -0
  78. charm/schemes/abenc/__init__.py +0 -0
  79. charm/schemes/abenc/abenc_accountability_jyjxgd20.py +647 -0
  80. charm/schemes/abenc/abenc_bsw07.py +146 -0
  81. charm/schemes/abenc/abenc_ca_cpabe_ar17.py +684 -0
  82. charm/schemes/abenc/abenc_dacmacs_yj14.py +298 -0
  83. charm/schemes/abenc/abenc_lsw08.py +159 -0
  84. charm/schemes/abenc/abenc_maabe_rw15.py +236 -0
  85. charm/schemes/abenc/abenc_maabe_yj14.py +297 -0
  86. charm/schemes/abenc/abenc_tbpre_lww14.py +309 -0
  87. charm/schemes/abenc/abenc_unmcpabe_yahk14.py +223 -0
  88. charm/schemes/abenc/abenc_waters09.py +144 -0
  89. charm/schemes/abenc/abenc_yct14.py +208 -0
  90. charm/schemes/abenc/abenc_yllc15.py +178 -0
  91. charm/schemes/abenc/ac17.py +248 -0
  92. charm/schemes/abenc/bsw07.py +141 -0
  93. charm/schemes/abenc/cgw15.py +277 -0
  94. charm/schemes/abenc/dabe_aw11.py +204 -0
  95. charm/schemes/abenc/dfa_fe12.py +144 -0
  96. charm/schemes/abenc/pk_hve08.py +179 -0
  97. charm/schemes/abenc/waters11.py +143 -0
  98. charm/schemes/aggrsign_MuSig.py +150 -0
  99. charm/schemes/aggrsign_bls.py +267 -0
  100. charm/schemes/blindsig_ps16.py +654 -0
  101. charm/schemes/chamhash_adm05.py +113 -0
  102. charm/schemes/chamhash_rsa_hw09.py +100 -0
  103. charm/schemes/commit/__init__.py +0 -0
  104. charm/schemes/commit/commit_gs08.py +77 -0
  105. charm/schemes/commit/commit_pedersen92.py +53 -0
  106. charm/schemes/encap_bchk05.py +62 -0
  107. charm/schemes/grpsig/__init__.py +0 -0
  108. charm/schemes/grpsig/groupsig_bgls04.py +114 -0
  109. charm/schemes/grpsig/groupsig_bgls04_var.py +115 -0
  110. charm/schemes/hibenc/__init__.py +0 -0
  111. charm/schemes/hibenc/hibenc_bb04.py +105 -0
  112. charm/schemes/hibenc/hibenc_lew11.py +193 -0
  113. charm/schemes/ibenc/__init__.py +0 -0
  114. charm/schemes/ibenc/clpkc_rp03.py +119 -0
  115. charm/schemes/ibenc/ibenc_CW13_z.py +168 -0
  116. charm/schemes/ibenc/ibenc_bb03.py +94 -0
  117. charm/schemes/ibenc/ibenc_bf01.py +121 -0
  118. charm/schemes/ibenc/ibenc_ckrs09.py +120 -0
  119. charm/schemes/ibenc/ibenc_cllww12_z.py +172 -0
  120. charm/schemes/ibenc/ibenc_lsw08.py +120 -0
  121. charm/schemes/ibenc/ibenc_sw05.py +238 -0
  122. charm/schemes/ibenc/ibenc_waters05.py +144 -0
  123. charm/schemes/ibenc/ibenc_waters05_z.py +164 -0
  124. charm/schemes/ibenc/ibenc_waters09.py +107 -0
  125. charm/schemes/ibenc/ibenc_waters09_z.py +147 -0
  126. charm/schemes/joye_scheme.py +106 -0
  127. charm/schemes/lem_scheme.py +207 -0
  128. charm/schemes/pk_fre_ccv11.py +107 -0
  129. charm/schemes/pk_vrf.py +127 -0
  130. charm/schemes/pkenc/__init__.py +0 -0
  131. charm/schemes/pkenc/pkenc_cs98.py +108 -0
  132. charm/schemes/pkenc/pkenc_elgamal85.py +122 -0
  133. charm/schemes/pkenc/pkenc_gm82.py +98 -0
  134. charm/schemes/pkenc/pkenc_paillier99.py +118 -0
  135. charm/schemes/pkenc/pkenc_rabin.py +254 -0
  136. charm/schemes/pkenc/pkenc_rsa.py +186 -0
  137. charm/schemes/pksig/__init__.py +0 -0
  138. charm/schemes/pksig/pksig_CW13_z.py +135 -0
  139. charm/schemes/pksig/pksig_bls04.py +87 -0
  140. charm/schemes/pksig/pksig_boyen.py +156 -0
  141. charm/schemes/pksig/pksig_chch.py +97 -0
  142. charm/schemes/pksig/pksig_chp.py +70 -0
  143. charm/schemes/pksig/pksig_cl03.py +150 -0
  144. charm/schemes/pksig/pksig_cl04.py +87 -0
  145. charm/schemes/pksig/pksig_cllww12_z.py +142 -0
  146. charm/schemes/pksig/pksig_cyh.py +132 -0
  147. charm/schemes/pksig/pksig_dsa.py +76 -0
  148. charm/schemes/pksig/pksig_ecdsa.py +71 -0
  149. charm/schemes/pksig/pksig_hess.py +104 -0
  150. charm/schemes/pksig/pksig_hw.py +110 -0
  151. charm/schemes/pksig/pksig_lamport.py +63 -0
  152. charm/schemes/pksig/pksig_ps01.py +135 -0
  153. charm/schemes/pksig/pksig_ps02.py +124 -0
  154. charm/schemes/pksig/pksig_ps03.py +119 -0
  155. charm/schemes/pksig/pksig_rsa_hw09.py +206 -0
  156. charm/schemes/pksig/pksig_schnorr91.py +77 -0
  157. charm/schemes/pksig/pksig_waters.py +115 -0
  158. charm/schemes/pksig/pksig_waters05.py +121 -0
  159. charm/schemes/pksig/pksig_waters09.py +121 -0
  160. charm/schemes/pre_mg07.py +150 -0
  161. charm/schemes/prenc/pre_afgh06.py +126 -0
  162. charm/schemes/prenc/pre_bbs98.py +123 -0
  163. charm/schemes/prenc/pre_nal16.py +216 -0
  164. charm/schemes/protocol_a01.py +272 -0
  165. charm/schemes/protocol_ao00.py +215 -0
  166. charm/schemes/protocol_cns07.py +274 -0
  167. charm/schemes/protocol_schnorr91.py +125 -0
  168. charm/schemes/sigma1.py +64 -0
  169. charm/schemes/sigma2.py +129 -0
  170. charm/schemes/sigma3.py +126 -0
  171. charm/schemes/threshold/__init__.py +59 -0
  172. charm/schemes/threshold/dkls23_dkg.py +556 -0
  173. charm/schemes/threshold/dkls23_presign.py +1089 -0
  174. charm/schemes/threshold/dkls23_sign.py +761 -0
  175. charm/schemes/threshold/xrpl_wallet.py +967 -0
  176. charm/test/__init__.py +0 -0
  177. charm/test/adapters/__init__.py +0 -0
  178. charm/test/adapters/abenc_adapt_hybrid_test.py +29 -0
  179. charm/test/adapters/dabenc_adapt_hybrid_test.py +56 -0
  180. charm/test/adapters/ibenc_adapt_hybrid_test.py +36 -0
  181. charm/test/adapters/ibenc_adapt_identityhash_test.py +32 -0
  182. charm/test/adapters/kpabenc_adapt_hybrid_test.py +30 -0
  183. charm/test/benchmark/abenc_yllc15_bench.py +92 -0
  184. charm/test/benchmark/benchmark_test.py +148 -0
  185. charm/test/benchmark_threshold.py +260 -0
  186. charm/test/conftest.py +38 -0
  187. charm/test/fuzz/__init__.py +1 -0
  188. charm/test/fuzz/conftest.py +5 -0
  189. charm/test/fuzz/fuzz_policy_parser.py +76 -0
  190. charm/test/fuzz/fuzz_serialization.py +83 -0
  191. charm/test/schemes/__init__.py +0 -0
  192. charm/test/schemes/abenc/__init__.py +0 -0
  193. charm/test/schemes/abenc/abenc_bsw07_test.py +39 -0
  194. charm/test/schemes/abenc/abenc_dacmacs_yj14_test.py +16 -0
  195. charm/test/schemes/abenc/abenc_lsw08_test.py +33 -0
  196. charm/test/schemes/abenc/abenc_maabe_yj14_test.py +16 -0
  197. charm/test/schemes/abenc/abenc_tbpre_lww14_test.py +16 -0
  198. charm/test/schemes/abenc/abenc_waters09_test.py +38 -0
  199. charm/test/schemes/abenc/abenc_yllc15_test.py +74 -0
  200. charm/test/schemes/chamhash_adm05_test.py +31 -0
  201. charm/test/schemes/chamhash_rsa_hw09_test.py +29 -0
  202. charm/test/schemes/commit/__init__.py +0 -0
  203. charm/test/schemes/commit/commit_gs08_test.py +24 -0
  204. charm/test/schemes/commit/commit_pedersen92_test.py +26 -0
  205. charm/test/schemes/dabe_aw11_test.py +45 -0
  206. charm/test/schemes/encap_bchk05_test.py +21 -0
  207. charm/test/schemes/grpsig/__init__.py +0 -0
  208. charm/test/schemes/grpsig/groupsig_bgls04_test.py +35 -0
  209. charm/test/schemes/grpsig/groupsig_bgls04_var_test.py +39 -0
  210. charm/test/schemes/hibenc/__init__.py +0 -0
  211. charm/test/schemes/hibenc/hibenc_bb04_test.py +28 -0
  212. charm/test/schemes/ibenc/__init__.py +0 -0
  213. charm/test/schemes/ibenc/ibenc_bb03_test.py +26 -0
  214. charm/test/schemes/ibenc/ibenc_bf01_test.py +24 -0
  215. charm/test/schemes/ibenc/ibenc_ckrs09_test.py +25 -0
  216. charm/test/schemes/ibenc/ibenc_lsw08_test.py +31 -0
  217. charm/test/schemes/ibenc/ibenc_sw05_test.py +32 -0
  218. charm/test/schemes/ibenc/ibenc_waters05_test.py +31 -0
  219. charm/test/schemes/ibenc/ibenc_waters09_test.py +27 -0
  220. charm/test/schemes/pk_vrf_test.py +29 -0
  221. charm/test/schemes/pkenc/__init__.py +0 -0
  222. charm/test/schemes/pkenc_test.py +255 -0
  223. charm/test/schemes/pksig/__init__.py +0 -0
  224. charm/test/schemes/pksig_test.py +376 -0
  225. charm/test/schemes/rsa_alg_test.py +340 -0
  226. charm/test/schemes/threshold_test.py +1792 -0
  227. charm/test/serialize/__init__.py +0 -0
  228. charm/test/serialize/serialize_test.py +40 -0
  229. charm/test/toolbox/__init__.py +0 -0
  230. charm/test/toolbox/conversion_test.py +30 -0
  231. charm/test/toolbox/ecgroup_test.py +53 -0
  232. charm/test/toolbox/integer_arithmetic_test.py +441 -0
  233. charm/test/toolbox/paddingschemes_test.py +238 -0
  234. charm/test/toolbox/policy_parser_stress_test.py +969 -0
  235. charm/test/toolbox/secretshare_test.py +28 -0
  236. charm/test/toolbox/symcrypto_test.py +108 -0
  237. charm/test/toolbox/test_policy_expression.py +16 -0
  238. charm/test/vectors/__init__.py +1 -0
  239. charm/test/vectors/test_bls_vectors.py +289 -0
  240. charm/test/vectors/test_pedersen_vectors.py +315 -0
  241. charm/test/vectors/test_schnorr_vectors.py +368 -0
  242. charm/test/zkp_compiler/__init__.py +9 -0
  243. charm/test/zkp_compiler/benchmark_zkp.py +258 -0
  244. charm/test/zkp_compiler/test_and_proof.py +240 -0
  245. charm/test/zkp_compiler/test_batch_verify.py +248 -0
  246. charm/test/zkp_compiler/test_dleq_proof.py +264 -0
  247. charm/test/zkp_compiler/test_or_proof.py +231 -0
  248. charm/test/zkp_compiler/test_proof_serialization.py +121 -0
  249. charm/test/zkp_compiler/test_range_proof.py +241 -0
  250. charm/test/zkp_compiler/test_representation_proof.py +325 -0
  251. charm/test/zkp_compiler/test_schnorr_proof.py +221 -0
  252. charm/test/zkp_compiler/test_thread_safety.py +169 -0
  253. charm/test/zkp_compiler/test_zkp_parser.py +139 -0
  254. charm/toolbox/ABEnc.py +26 -0
  255. charm/toolbox/ABEncMultiAuth.py +66 -0
  256. charm/toolbox/ABEnumeric.py +800 -0
  257. charm/toolbox/Commit.py +24 -0
  258. charm/toolbox/DFA.py +89 -0
  259. charm/toolbox/FSA.py +1254 -0
  260. charm/toolbox/Hash.py +39 -0
  261. charm/toolbox/IBEnc.py +62 -0
  262. charm/toolbox/IBSig.py +64 -0
  263. charm/toolbox/PKEnc.py +66 -0
  264. charm/toolbox/PKSig.py +56 -0
  265. charm/toolbox/PREnc.py +32 -0
  266. charm/toolbox/ZKProof.py +289 -0
  267. charm/toolbox/__init__.py +0 -0
  268. charm/toolbox/bitstring.py +49 -0
  269. charm/toolbox/broadcast.py +220 -0
  270. charm/toolbox/conversion.py +100 -0
  271. charm/toolbox/eccurve.py +149 -0
  272. charm/toolbox/ecgroup.py +143 -0
  273. charm/toolbox/enum.py +60 -0
  274. charm/toolbox/hash_module.py +91 -0
  275. charm/toolbox/integergroup.py +323 -0
  276. charm/toolbox/iterate.py +22 -0
  277. charm/toolbox/matrixops.py +76 -0
  278. charm/toolbox/mpc_utils.py +296 -0
  279. charm/toolbox/msp.py +175 -0
  280. charm/toolbox/mta.py +985 -0
  281. charm/toolbox/node.py +120 -0
  282. charm/toolbox/ot/__init__.py +22 -0
  283. charm/toolbox/ot/base_ot.py +374 -0
  284. charm/toolbox/ot/dpf.py +642 -0
  285. charm/toolbox/ot/mpfss.py +228 -0
  286. charm/toolbox/ot/ot_extension.py +589 -0
  287. charm/toolbox/ot/silent_ot.py +378 -0
  288. charm/toolbox/paddingschemes.py +423 -0
  289. charm/toolbox/paddingschemes_test.py +238 -0
  290. charm/toolbox/pairingcurves.py +85 -0
  291. charm/toolbox/pairinggroup.py +186 -0
  292. charm/toolbox/policy_expression_spec.py +70 -0
  293. charm/toolbox/policytree.py +189 -0
  294. charm/toolbox/reCompiler.py +346 -0
  295. charm/toolbox/redundancyschemes.py +65 -0
  296. charm/toolbox/schemebase.py +188 -0
  297. charm/toolbox/secretshare.py +104 -0
  298. charm/toolbox/secretutil.py +174 -0
  299. charm/toolbox/securerandom.py +73 -0
  300. charm/toolbox/sigmaprotocol.py +46 -0
  301. charm/toolbox/specialprimes.py +45 -0
  302. charm/toolbox/symcrypto.py +279 -0
  303. charm/toolbox/threshold_sharing.py +553 -0
  304. charm/toolbox/xmlserialize.py +94 -0
  305. charm/toolbox/zknode.py +105 -0
  306. charm/zkp_compiler/__init__.py +89 -0
  307. charm/zkp_compiler/and_proof.py +460 -0
  308. charm/zkp_compiler/batch_verify.py +324 -0
  309. charm/zkp_compiler/dleq_proof.py +423 -0
  310. charm/zkp_compiler/or_proof.py +305 -0
  311. charm/zkp_compiler/range_proof.py +417 -0
  312. charm/zkp_compiler/representation_proof.py +466 -0
  313. charm/zkp_compiler/schnorr_proof.py +273 -0
  314. charm/zkp_compiler/thread_safe.py +150 -0
  315. charm/zkp_compiler/zk_demo.py +489 -0
  316. charm/zkp_compiler/zkp_factory.py +330 -0
  317. charm/zkp_compiler/zkp_generator.py +370 -0
  318. charm/zkp_compiler/zkparser.py +269 -0
  319. charm_crypto_framework-0.61.1.dist-info/METADATA +337 -0
  320. charm_crypto_framework-0.61.1.dist-info/RECORD +323 -0
  321. charm_crypto_framework-0.61.1.dist-info/WHEEL +5 -0
  322. charm_crypto_framework-0.61.1.dist-info/licenses/LICENSE.txt +165 -0
  323. charm_crypto_framework-0.61.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,298 @@
1
+ '''
2
+ **DAC-MACS: Data Access Control for Multi-Authority Cloud Storage (YJ14)**
3
+
4
+ *Authors:* Kan Yang, Xiaohua Jia
5
+
6
+ | **Title:** "DAC-MACS: Effective Data Access Control for Multi-Authority Cloud Storage Systems"
7
+ | **Published in:** Security for Cloud Storage Systems - SpringerBriefs in Computer Science, 2014
8
+ | **Available from:** http://link.springer.com/chapter/10.1007/978-1-4614-7873-7_4
9
+ | **Notes:** Multi-authority scheme with efficient attribute revocation
10
+
11
+ .. rubric:: Scheme Properties
12
+
13
+ * **Type:** ciphertext-policy attribute-based encryption (public key)
14
+ * **Setting:** Pairing groups
15
+ * **Assumption:** Decisional Bilinear Diffie-Hellman
16
+
17
+ .. rubric:: Implementation
18
+
19
+ :Authors: artjomb
20
+ :Date: 07/2014
21
+ '''
22
+
23
+ from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,GT,pair
24
+ from charm.toolbox.secretutil import SecretUtil
25
+ from charm.toolbox.ABEncMultiAuth import ABEncMultiAuth
26
+
27
+ class DACMACS(object):
28
+ def __init__(self, groupObj):
29
+ self.util = SecretUtil(groupObj, verbose=False) #Create Secret Sharing Scheme
30
+ self.group = groupObj #:Prime order group
31
+
32
+ def setup(self):
33
+ '''Global Setup (executed by CA)'''
34
+ #:In global setup, a bilinear group G of prime order p is chosen
35
+ #:The global public parameters, GP and p, and a generator g of G. A random oracle H maps global identities GID to elements of G
36
+
37
+ #:group contains
38
+ #:the prime order p is contained somewhere within the group object
39
+ g = self.group.random(G1)
40
+ #: The oracle that maps global identities GID onto elements of G
41
+ #:H = lambda str: g** group.hash(str)
42
+ H = lambda x: self.group.hash(x, G1)
43
+ a = self.group.random()
44
+ g_a = g ** a
45
+ GPP = {'g': g, 'g_a': g_a, 'H': H}
46
+ GMK = {'a': a}
47
+
48
+ return (GPP, GMK)
49
+
50
+ def registerUser(self, GPP):
51
+ '''Generate user keys (executed by the user).'''
52
+ g = GPP['g']
53
+ u = self.group.random()
54
+ z = self.group.random()
55
+ g_u = g ** u
56
+ g_z = g ** (1 / z)
57
+
58
+ return ((g_u, z), { 'g_z': g_z, 'u': u }) # (private, public)
59
+
60
+ def setupAuthority(self, GPP, authorityid, attributes, authorities):
61
+ '''Generate attribute authority keys (executed by attribute authority)'''
62
+ if authorityid not in authorities:
63
+ alpha = self.group.random()
64
+ beta = self.group.random()
65
+ gamma = self.group.random()
66
+ SK = {'alpha': alpha, 'beta': beta, 'gamma': gamma}
67
+ PK = {
68
+ 'e_alpha': pair(GPP['g'], GPP['g']) ** alpha,
69
+ 'g_beta_inv': GPP['g'] ** (1/beta),
70
+ 'g_beta_gamma': GPP['g'] ** (gamma/beta)
71
+ }
72
+ authAttrs = {}
73
+ authorities[authorityid] = (SK, PK, authAttrs)
74
+ else:
75
+ SK, PK, authAttrs = authorities[authorityid]
76
+ for attrib in attributes:
77
+ if attrib in authAttrs:
78
+ continue
79
+ versionKey = self.group.random() # random or really 'choose' ?
80
+ h = GPP['H'](attrib)
81
+ pk = ((GPP['g'] ** versionKey) * h) ** SK['gamma']
82
+ authAttrs[attrib] = {
83
+ 'VK': versionKey, #secret
84
+ 'PK': pk, #public
85
+ }
86
+ return (SK, PK, authAttrs)
87
+
88
+ def keygen(self, GPP, authority, attribute, userObj, USK = None):
89
+ '''Generate user keys for a specific attribute (executed on attribute authority)'''
90
+ if 't' not in userObj:
91
+ userObj['t'] = self.group.random() #private to AA
92
+ t = userObj['t']
93
+
94
+ ASK, APK, authAttrs = authority
95
+ u = userObj
96
+ if USK is None:
97
+ USK = {}
98
+ if 'K' not in USK or 'L' not in USK or 'R' not in USK or 'AK' not in USK:
99
+ USK['K'] = \
100
+ (u['g_z'] ** ASK['alpha']) * \
101
+ (GPP['g_a'] ** u['u']) * \
102
+ (GPP['g_a'] ** (t / ASK['beta']))
103
+ USK['L'] = u['g_z'] ** (ASK['beta'] * t)
104
+ USK['R'] = GPP['g_a'] ** t
105
+ USK['AK'] = {}
106
+ AK = (u['g_z'] ** (ASK['beta'] * ASK['gamma'] * t)) * \
107
+ (authAttrs[attribute]['PK'] ** (ASK['beta'] * u['u']))
108
+ USK['AK'][attribute] = AK
109
+ return USK
110
+
111
+ def encrypt(self, GPP, policy_str, k, authority):
112
+ '''Generate the cipher-text from the content(-key) and a policy (executed by the content owner)'''
113
+ #GPP are global parameters
114
+ #k is the content key (group element based on AES key)
115
+ #policy_str is the policy string
116
+ #authority is the authority tuple
117
+
118
+ _, APK, authAttrs = authority
119
+
120
+ policy = self.util.createPolicy(policy_str)
121
+ secret = self.group.random()
122
+ shares = self.util.calculateSharesList(secret, policy)
123
+ shares = dict([(x[0].getAttributeAndIndex(), x[1]) for x in shares])
124
+
125
+ C1 = k * (APK['e_alpha'] ** secret)
126
+ C2 = GPP['g'] ** secret
127
+ C3 = APK['g_beta_inv'] ** secret
128
+ C = {}
129
+ D = {}
130
+ DS = {}
131
+
132
+ for attr, s_share in shares.items():
133
+ k_attr = self.util.strip_index(attr)
134
+ r_i = self.group.random()
135
+ attrPK = authAttrs[attr]
136
+ C[attr] = (GPP['g_a'] ** s_share) * ~(attrPK['PK'] ** r_i)
137
+ D[attr] = APK['g_beta_inv'] ** r_i
138
+ DS[attr] = ~(APK['g_beta_gamma'] ** r_i)
139
+
140
+ return {'C1': C1, 'C2': C2, 'C3': C3, 'C': C, 'D': D, 'DS': DS, 'policy': policy_str}
141
+
142
+ def generateTK(self, GPP, CT, UASK, g_u):
143
+ '''Generates a token using the user's attribute secret keys to offload the decryption process (executed by cloud provider)'''
144
+ usr_attribs = list(UASK['AK'].keys())
145
+ policy = self.util.createPolicy(CT['policy'])
146
+ pruned = self.util.prune(policy, usr_attribs)
147
+ if pruned == False:
148
+ return False
149
+ coeffs = self.util.getCoefficients(policy)
150
+
151
+ dividend = pair(CT['C2'], UASK['K']) * ~pair(UASK['R'], CT['C3'])
152
+ n_a = 1
153
+ divisor = 1
154
+
155
+ for attr in pruned:
156
+ x = attr.getAttributeAndIndex()
157
+ y = attr.getAttribute()
158
+ temp = \
159
+ pair(CT['C'][y], g_u) * \
160
+ pair(CT['D'][y], UASK['AK'][y]) * \
161
+ pair(CT['DS'][y], UASK['L'])
162
+ divisor *= temp ** (coeffs[x] * n_a)
163
+ return dividend / divisor
164
+
165
+ def decrypt(self, CT, TK, z):
166
+ '''Decrypts the content(-key) from the cipher-text using the token and the user secret key (executed by user/content consumer)'''
167
+ return CT['C1'] / (TK ** z)
168
+
169
+ def ukeygen(self, GPP, authority, attribute, userObj):
170
+ '''Generate update keys for users and cloud provider (executed by attribute authority?)'''
171
+ ASK, _, authAttrs = authority
172
+ oldVersionKey = authAttrs[attribute]['VK']
173
+ newVersionKey = oldVersionKey
174
+ while oldVersionKey == newVersionKey:
175
+ newVersionKey = self.group.random()
176
+ authAttrs[attribute]['VK'] = newVersionKey
177
+
178
+ u = userObj['u']
179
+
180
+ AUK = ASK['gamma'] * (newVersionKey - oldVersionKey)
181
+ KUK = GPP['g'] ** (u * ASK['beta'] * AUK)
182
+ CUK = ASK['beta'] * AUK / ASK['gamma']
183
+
184
+ authAttrs[attribute]['PK'] = authAttrs[attribute]['PK'] * (GPP['g'] ** AUK)
185
+
186
+ return { 'KUK': KUK, 'CUK': CUK }
187
+
188
+ def skupdate(self, USK, attribute, KUK):
189
+ '''Updates the user attribute secret key for the specified attribute (executed by non-revoked user)'''
190
+ USK['AK'][attribute] = USK['AK'][attribute] * KUK
191
+
192
+ def ctupdate(self, GPP, CT, attribute, CUK):
193
+ '''Updates the cipher-text using the update key, because of the revoked attribute (executed by cloud provider)'''
194
+ CT['C'][attribute] = CT['C'][attribute] * (CT['DS'][attribute] ** CUK)
195
+
196
+ def basicTest():
197
+ print("RUN basicTest")
198
+ groupObj = PairingGroup('SS512')
199
+ dac = DACMACS(groupObj)
200
+ GPP, GMK = dac.setup()
201
+
202
+ users = {} # public user data
203
+ authorities = {}
204
+
205
+ authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"]
206
+ authority1 = "authority1"
207
+
208
+ dac.setupAuthority(GPP, authority1, authorityAttributes, authorities)
209
+
210
+ alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None }
211
+ alice['keys'], users[alice['id']] = dac.registerUser(GPP)
212
+
213
+ for attr in authorityAttributes[0:-1]:
214
+ dac.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys'])
215
+
216
+ k = groupObj.random(GT)
217
+
218
+ policy_str = '((ONE or THREE) and (TWO or FOUR))'
219
+
220
+ CT = dac.encrypt(GPP, policy_str, k, authorities[authority1])
221
+
222
+ TK = dac.generateTK(GPP, CT, alice['authoritySecretKeys'], alice['keys'][0])
223
+
224
+ PT = dac.decrypt(CT, TK, alice['keys'][1])
225
+
226
+ # print "k", k
227
+ # print "PT", PT
228
+
229
+ assert k == PT, 'FAILED DECRYPTION!'
230
+ print('SUCCESSFUL DECRYPTION')
231
+
232
+ def revokedTest():
233
+ print("RUN revokedTest")
234
+ groupObj = PairingGroup('SS512')
235
+ dac = DACMACS(groupObj)
236
+ GPP, GMK = dac.setup()
237
+
238
+ users = {} # public user data
239
+ authorities = {}
240
+
241
+ authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"]
242
+ authority1 = "authority1"
243
+
244
+ dac.setupAuthority(GPP, authority1, authorityAttributes, authorities)
245
+
246
+ alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None }
247
+ alice['keys'], users[alice['id']] = dac.registerUser(GPP)
248
+
249
+ bob = { 'id': 'bob', 'authoritySecretKeys': {}, 'keys': None }
250
+ bob['keys'], users[bob['id']] = dac.registerUser(GPP)
251
+
252
+ for attr in authorityAttributes[0:-1]:
253
+ dac.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys'])
254
+ dac.keygen(GPP, authorities[authority1], attr, users[bob['id']], bob['authoritySecretKeys'])
255
+
256
+ k = groupObj.random(GT)
257
+
258
+ policy_str = '((ONE or THREE) and (TWO or FOUR))'
259
+
260
+ CT = dac.encrypt(GPP, policy_str, k, authorities[authority1])
261
+
262
+ TK1a = dac.generateTK(GPP, CT, alice['authoritySecretKeys'], alice['keys'][0])
263
+ PT1a = dac.decrypt(CT, TK1a, alice['keys'][1])
264
+ TK1b = dac.generateTK(GPP, CT, bob['authoritySecretKeys'], bob['keys'][0])
265
+ PT1b = dac.decrypt(CT, TK1b, bob['keys'][1])
266
+
267
+ assert k == PT1a, 'FAILED DECRYPTION (1a)!'
268
+ assert k == PT1b, 'FAILED DECRYPTION (1b)!'
269
+ print('SUCCESSFUL DECRYPTION 1')
270
+
271
+ # revoke bob on "ONE"
272
+ attribute = "ONE"
273
+ UK = dac.ukeygen(GPP, authorities[authority1], attribute, users[alice['id']])
274
+ dac.skupdate(alice['authoritySecretKeys'], attribute, UK['KUK'])
275
+ dac.ctupdate(GPP, CT, attribute, UK['CUK'])
276
+
277
+ TK2a = dac.generateTK(GPP, CT, alice['authoritySecretKeys'], alice['keys'][0])
278
+ PT2a = dac.decrypt(CT, TK2a, alice['keys'][1])
279
+ TK2b = dac.generateTK(GPP, CT, bob['authoritySecretKeys'], bob['keys'][0])
280
+ PT2b = dac.decrypt(CT, TK2b, bob['keys'][1])
281
+
282
+ assert k == PT2a, 'FAILED DECRYPTION (2a)!'
283
+ assert k != PT2b, 'SUCCESSFUL DECRYPTION (2b)!'
284
+ print('SUCCESSFUL DECRYPTION 2')
285
+
286
+ def test():
287
+ groupObj = PairingGroup('SS512')
288
+ # k = groupObj.random()
289
+ #print "k", k, ~k, k * ~k
290
+ # g = groupObj.random(G1)
291
+ # print "g", g, pair(g, g)
292
+ # gt = groupObj.random(GT)
293
+ # print "gt", gt
294
+
295
+ if __name__ == '__main__':
296
+ basicTest()
297
+ revokedTest()
298
+ # test()
@@ -0,0 +1,159 @@
1
+ '''
2
+ **Key-Policy Attribute-Based Encryption (LSW08)**
3
+
4
+ *Authors:* Allison Lewko, Amit Sahai, Brent Waters
5
+
6
+ | **Title:** "Revocation Systems with Very Small Private Keys"
7
+ | **Published in:** IEEE Symposium on Security and Privacy, 2010
8
+ | **Available from:** http://eprint.iacr.org/2008/309.pdf
9
+ | **Notes:** Large Universe Construction
10
+
11
+ .. rubric:: Scheme Properties
12
+
13
+ * **Type:** key-policy attribute-based encryption (public key)
14
+ * **Setting:** Pairing groups
15
+ * **Assumption:** Decisional Bilinear Diffie-Hellman
16
+
17
+ .. rubric:: Implementation
18
+
19
+ :Authors: J. Ayo Akinyele
20
+ :Date: 12/2010
21
+ '''
22
+
23
+ from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
24
+ from charm.toolbox.secretutil import SecretUtil
25
+ from charm.toolbox.ABEnc import ABEnc
26
+
27
+ debug = False
28
+ class KPabe(ABEnc):
29
+ """
30
+ >>> from charm.toolbox.pairinggroup import PairingGroup,GT
31
+ >>> group = PairingGroup('MNT224')
32
+ >>> kpabe = KPabe(group)
33
+ >>> (master_public_key, master_key) = kpabe.setup()
34
+ >>> policy = '(ONE or THREE) and (THREE or TWO)'
35
+ >>> attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ]
36
+ >>> secret_key = kpabe.keygen(master_public_key, master_key, policy)
37
+ >>> msg=group.random(GT)
38
+ >>> cipher_text = kpabe.encrypt(master_public_key, msg, attributes)
39
+ >>> decrypted_msg = kpabe.decrypt(cipher_text, secret_key)
40
+ >>> decrypted_msg == msg
41
+ True
42
+ """
43
+
44
+ def __init__(self, groupObj, verbose=False):
45
+ ABEnc.__init__(self)
46
+ global group, util
47
+ group = groupObj
48
+ util = SecretUtil(group, verbose)
49
+
50
+ def setup(self):
51
+ # pick random exponents
52
+ alpha1, alpha2, b = group.random(ZR), group.random(ZR), group.random(ZR)
53
+
54
+ alpha = alpha1 * alpha2
55
+ g_G1, g_G2 = group.random(G1), group.random(G2) # PK 1,2
56
+ h_G1, h_G2 = group.random(G1), group.random(G2) # PK 3
57
+ g1b = g_G1 ** b
58
+ e_gg_alpha = pair(g_G1,g_G2) ** alpha
59
+
60
+ #public parameters # 'g_G2^b':(g_G2 ** b), 'g_G2^b2':g_G2 ** (b * b),
61
+ pk = { 'g_G1':g_G1, 'g_G2':g_G2, 'g_G1_b':g1b,
62
+ 'g_G1_b2':g1b ** b, 'h_G1_b':h_G1 ** b, 'e(gg)_alpha':e_gg_alpha }
63
+ #secret parameters
64
+ mk = { 'alpha1':alpha1, 'alpha2':alpha2, 'b':b, 'h_G1':h_G1, 'h_G2':h_G2 }
65
+ return (pk, mk)
66
+
67
+ def keygen(self, pk, mk, policy_str):
68
+ policy = util.createPolicy(policy_str)
69
+ attr_list = util.getAttributeList(policy)
70
+
71
+ s = mk['alpha1']; secret = s
72
+ shares = util.calculateSharesDict(secret, policy)
73
+
74
+ D = { 'policy': policy_str }
75
+ for x in attr_list:
76
+ y = util.strip_index(x)
77
+ d = []; r = group.random(ZR)
78
+ if not self.negatedAttr(x): # meaning positive
79
+ d.append((pk['g_G1'] ** (mk['alpha2'] * shares[x])) * (group.hash(y, G1) ** r)) # compute D1 for attribute x
80
+ d.append((pk['g_G2'] ** r)) # compute D2 for attribute x
81
+ #else:
82
+ #d.append((pk['g2_G1'] ** shares[x]) * (pk['g_G1_b2'] ** r)) # compute D3
83
+ #d.append((pk['g_G1_b'] ** (r * group.hash(x))) * (pk['h_G1'] ** r)) # compute D4
84
+ #d.append(pk['g_G1'] ** -r) # compute D5
85
+ D[x] = d
86
+ if debug: print("Access Policy for key: %s" % policy)
87
+ if debug: print("Attribute list: %s" % attr_list)
88
+ return D
89
+
90
+ def negatedAttr(self, attribute):
91
+ if type(attribute) != str: attr = attribute.getAttribute()
92
+ else: attr = attribute
93
+ if attr[0] == '!':
94
+ if debug: print("Checking... => %s" % attr[0])
95
+ return True
96
+ return False
97
+
98
+ def encrypt(self, pk, M, attr_list):
99
+ if debug: print('Encryption Algorithm...')
100
+ # s will hold secret
101
+ t = group.init(ZR, 0)
102
+ s = group.random(); sx = [s]
103
+ for i in range(len(attr_list)):
104
+ sx.append(group.random(ZR))
105
+ sx[0] -= sx[i]
106
+
107
+ E3 = {}
108
+ #E4, E5 = {}, {}
109
+ for i in range(len(attr_list)):
110
+ attr = attr_list[i]
111
+ E3[attr] = group.hash(attr, G1) ** s
112
+ #E4[attr] = pk['g_G1_b'] ** sx[i]
113
+ #E5[attr] = (pk['g_G1_b2'] ** (sx[i] * group.hash(attr))) * (pk['h_G1_b'] ** sx[i])
114
+
115
+ E1 = (pk['e(gg)_alpha'] ** s) * M
116
+ E2 = pk['g_G2'] ** s
117
+ return {'E1':E1, 'E2':E2, 'E3':E3, 'attributes':attr_list }
118
+
119
+ def decrypt(self, E, D):
120
+ policy = util.createPolicy(D['policy'])
121
+ attrs = util.prune(policy, E['attributes'])
122
+ if attrs == False:
123
+ return False
124
+ coeff = util.getCoefficients(policy)
125
+
126
+ Z = {}; prodT = 1
127
+ for i in range(len(attrs)):
128
+ x = attrs[i].getAttribute()
129
+ y = attrs[i].getAttributeAndIndex()
130
+ if not self.negatedAttr(y):
131
+ Z[y] = pair(D[y][0], E['E2']) / pair(E['E3'][x], D[y][1])
132
+ prodT *= Z[y] ** coeff[y]
133
+
134
+ return E['E1'] / prodT
135
+
136
+ def main():
137
+ groupObj = PairingGroup('MNT224')
138
+ kpabe = KPabe(groupObj)
139
+
140
+ (pk, mk) = kpabe.setup()
141
+
142
+ policy = '(ONE or THREE) and (THREE or TWO)'
143
+ attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ]
144
+ msg = groupObj.random(GT)
145
+
146
+ mykey = kpabe.keygen(pk, mk, policy)
147
+
148
+ if debug: print("Encrypt under these attributes: ", attributes)
149
+ ciphertext = kpabe.encrypt(pk, msg, attributes)
150
+ if debug: print(ciphertext)
151
+
152
+ rec_msg = kpabe.decrypt(ciphertext, mykey)
153
+
154
+ assert msg == rec_msg
155
+ if debug: print("Successful Decryption!")
156
+
157
+ if __name__ == "__main__":
158
+ debug = True
159
+ main()
@@ -0,0 +1,236 @@
1
+ '''
2
+ **Multi-Authority Attribute-Based Encryption (RW15)**
3
+
4
+ *Authors:* Yannis Rouselakis, Brent Waters
5
+
6
+ | **Title:** "Efficient Statically-Secure Large-Universe Multi-Authority Attribute-Based Encryption"
7
+ | **Published in:** Financial Cryptography and Data Security, 2015
8
+ | **Available from:** http://eprint.iacr.org/2015/016.pdf
9
+ | **Notes:** Implementation based on maabe_rw12.py (https://sites.google.com/site/yannisrouselakis/rwabe)
10
+
11
+ .. rubric:: Scheme Properties
12
+
13
+ * **Type:** multi-authority attribute-based encryption (public key)
14
+ * **Setting:** Bilinear pairing group of prime order
15
+ * **Assumption:** Complex q-type assumption
16
+
17
+ .. rubric:: Implementation
18
+
19
+ :Authors: Yannis Rouselakis
20
+ :Date: 11/2012
21
+ '''
22
+
23
+ from charm.toolbox.pairinggroup import *
24
+ from charm.toolbox.secretutil import SecretUtil
25
+ from charm.toolbox.ABEncMultiAuth import ABEncMultiAuth
26
+ import re
27
+
28
+ debug = False
29
+
30
+
31
+ def merge_dicts(*dict_args):
32
+ """
33
+ Given any number of dicts, shallow copy and merge into a new dict,
34
+ precedence goes to key value pairs in latter dicts.
35
+ """
36
+ result = {}
37
+ for dictionary in dict_args:
38
+ result.update(dictionary)
39
+ return result
40
+
41
+
42
+ class MaabeRW15(ABEncMultiAuth):
43
+ """
44
+ Efficient Statically-Secure Large-Universe Multi-Authority Attribute-Based Encryption
45
+ Rouselakis - Waters
46
+
47
+ >>> group = PairingGroup('SS512')
48
+ >>> maabe = MaabeRW15(group)
49
+ >>> public_parameters = maabe.setup()
50
+
51
+ Setup the attribute authorities
52
+ >>> attributes1 = ['ONE', 'TWO']
53
+ >>> attributes2 = ['THREE', 'FOUR']
54
+ >>> (public_key1, secret_key1) = maabe.authsetup(public_parameters, 'UT')
55
+ >>> (public_key2, secret_key2) = maabe.authsetup(public_parameters, 'OU')
56
+ >>> public_keys = {'UT': public_key1, 'OU': public_key2}
57
+
58
+ Setup a user and give him some keys
59
+ >>> gid = "bob"
60
+ >>> user_attributes1 = ['STUDENT@UT', 'PHD@UT']
61
+ >>> user_attributes2 = ['STUDENT@OU']
62
+ >>> user_keys1 = maabe.multiple_attributes_keygen(public_parameters, secret_key1, gid, user_attributes1)
63
+ >>> user_keys2 = maabe.multiple_attributes_keygen(public_parameters, secret_key2, gid, user_attributes2)
64
+ >>> user_keys = {'GID': gid, 'keys': merge_dicts(user_keys1, user_keys2)}
65
+
66
+ Create a random message
67
+ >>> message = group.random(GT)
68
+
69
+ Encrypt the message
70
+ >>> access_policy = '(STUDENT@UT or PROFESSOR@OU) and (STUDENT@UT or MASTERS@OU)'
71
+ >>> cipher_text = maabe.encrypt(public_parameters, public_keys, message, access_policy)
72
+
73
+ Decrypt the message
74
+ >>> decrypted_message = maabe.decrypt(public_parameters, user_keys, cipher_text)
75
+ >>> decrypted_message == message
76
+ True
77
+ """
78
+
79
+ def __init__(self, group, verbose=False):
80
+ ABEncMultiAuth.__init__(self)
81
+ self.group = group
82
+ self.util = SecretUtil(group, verbose)
83
+
84
+ def setup(self):
85
+ g1 = self.group.random(G1)
86
+ g2 = self.group.random(G2)
87
+ egg = pair(g1, g2)
88
+ H = lambda x: self.group.hash(x, G2)
89
+ F = lambda x: self.group.hash(x, G2)
90
+ gp = {'g1': g1, 'g2': g2, 'egg': egg, 'H': H, 'F': F}
91
+ if debug:
92
+ print("Setup")
93
+ print(gp)
94
+ return gp
95
+
96
+ def unpack_attribute(self, attribute):
97
+ """
98
+ Unpacks an attribute in attribute name, authority name and index
99
+ :param attribute: The attribute to unpack
100
+ :return: The attribute name, authority name and the attribute index, if present.
101
+
102
+ >>> group = PairingGroup('SS512')
103
+ >>> maabe = MaabeRW15(group)
104
+ >>> maabe.unpack_attribute('STUDENT@UT')
105
+ ('STUDENT', 'UT', None)
106
+ >>> maabe.unpack_attribute('STUDENT@UT_2')
107
+ ('STUDENT', 'UT', '2')
108
+ """
109
+ parts = re.split(r"[@_]", attribute)
110
+ assert len(parts) > 1, "No @ char in [attribute@authority] name"
111
+ return parts[0], parts[1], None if len(parts) < 3 else parts[2]
112
+
113
+ def authsetup(self, gp, name):
114
+ """
115
+ Setup an attribute authority.
116
+ :param gp: The global parameters
117
+ :param name: The name of the authority
118
+ :return: The public and private key of the authority
119
+ """
120
+ alpha, y = self.group.random(), self.group.random()
121
+ egga = gp['egg'] ** alpha
122
+ gy = gp['g1'] ** y
123
+ pk = {'name': name, 'egga': egga, 'gy': gy}
124
+ sk = {'name': name, 'alpha': alpha, 'y': y}
125
+ if debug:
126
+ print("Authsetup: %s" % name)
127
+ print(pk)
128
+ print(sk)
129
+ return pk, sk
130
+
131
+ def keygen(self, gp, sk, gid, attribute):
132
+ """
133
+ Generate a user secret key for the attribute.
134
+ :param gp: The global parameters.
135
+ :param sk: The secret key of the attribute authority.
136
+ :param gid: The global user identifier.
137
+ :param attribute: The attribute.
138
+ :return: The secret key for the attribute for the user with identifier gid.
139
+ """
140
+ _, auth, _ = self.unpack_attribute(attribute)
141
+ assert sk['name'] == auth, "Attribute %s does not belong to authority %s" % (attribute, sk['name'])
142
+
143
+ t = self.group.random()
144
+ K = gp['g2'] ** sk['alpha'] * gp['H'](gid) ** sk['y'] * gp['F'](attribute) ** t
145
+ KP = gp['g1'] ** t
146
+ if debug:
147
+ print("Keygen")
148
+ print("User: %s, Attribute: %s" % (gid, attribute))
149
+ print({'K': K, 'KP': KP})
150
+ return {'K': K, 'KP': KP}
151
+
152
+ def multiple_attributes_keygen(self, gp, sk, gid, attributes):
153
+ """
154
+ Generate a dictionary of secret keys for a user for a list of attributes.
155
+ :param gp: The global parameters.
156
+ :param sk: The secret key of the attribute authority.
157
+ :param gid: The global user identifier.
158
+ :param attributes: The list of attributes.
159
+ :return: A dictionary with attribute names as keys, and secret keys for the attributes as values.
160
+ """
161
+ uk = {}
162
+ for attribute in attributes:
163
+ uk[attribute] = self.keygen(gp, sk, gid, attribute)
164
+ return uk
165
+
166
+ def encrypt(self, gp, pks, message, policy_str):
167
+ """
168
+ Encrypt a message under an access policy
169
+ :param gp: The global parameters.
170
+ :param pks: The public keys of the relevant attribute authorities, as dict from authority name to public key.
171
+ :param message: The message to encrypt.
172
+ :param policy_str: The access policy to use.
173
+ :return: The encrypted message.
174
+ """
175
+ s = self.group.random() # secret to be shared
176
+ w = self.group.init(ZR, 0) # 0 to be shared
177
+
178
+ policy = self.util.createPolicy(policy_str)
179
+ attribute_list = self.util.getAttributeList(policy)
180
+
181
+ secret_shares = self.util.calculateSharesDict(s, policy) # These are correctly set to be exponents in Z_p
182
+ zero_shares = self.util.calculateSharesDict(w, policy)
183
+
184
+ C0 = message * (gp['egg'] ** s)
185
+ C1, C2, C3, C4 = {}, {}, {}, {}
186
+ for i in attribute_list:
187
+ attribute_name, auth, _ = self.unpack_attribute(i)
188
+ attr = "%s@%s" % (attribute_name, auth)
189
+ tx = self.group.random()
190
+ C1[i] = gp['egg'] ** secret_shares[i] * pks[auth]['egga'] ** tx
191
+ C2[i] = gp['g1'] ** (-tx)
192
+ C3[i] = pks[auth]['gy'] ** tx * gp['g1'] ** zero_shares[i]
193
+ C4[i] = gp['F'](attr) ** tx
194
+ if debug:
195
+ print("Encrypt")
196
+ print(message)
197
+ print({'policy': policy_str, 'C0': C0, 'C1': C1, 'C2': C2, 'C3': C3, 'C4': C4})
198
+ return {'policy': policy_str, 'C0': C0, 'C1': C1, 'C2': C2, 'C3': C3, 'C4': C4}
199
+
200
+ def decrypt(self, gp, sk, ct):
201
+ """
202
+ Decrypt the ciphertext using the secret keys of the user.
203
+ :param gp: The global parameters.
204
+ :param sk: The secret keys of the user.
205
+ :param ct: The ciphertext to decrypt.
206
+ :return: The decrypted message.
207
+ :raise Exception: When the access policy can not be satisfied with the user's attributes.
208
+ """
209
+ policy = self.util.createPolicy(ct['policy'])
210
+ coefficients = self.util.getCoefficients(policy)
211
+ pruned_list = self.util.prune(policy, sk['keys'].keys())
212
+
213
+ if not pruned_list:
214
+ raise Exception("You don't have the required attributes for decryption!")
215
+
216
+ B = self.group.init(GT, 1)
217
+ for i in range(len(pruned_list)):
218
+ x = pruned_list[i].getAttribute() # without the underscore
219
+ y = pruned_list[i].getAttributeAndIndex() # with the underscore
220
+ B *= (ct['C1'][y] * pair(ct['C2'][y], sk['keys'][x]['K']) * pair(ct['C3'][y], gp['H'](sk['GID'])) * pair(
221
+ sk['keys'][x]['KP'], ct['C4'][y])) ** coefficients[y]
222
+ if debug:
223
+ print("Decrypt")
224
+ print("SK:")
225
+ print(sk)
226
+ print("Decrypted Message:")
227
+ print(ct['C0'] / B)
228
+ return ct['C0'] / B
229
+
230
+
231
+ if __name__ == '__main__':
232
+ debug = True
233
+
234
+ import doctest
235
+
236
+ doctest.testmod()