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,297 @@
1
+ '''
2
+ **Multi-Authority ABE for Cloud Storage (YJ14)**
3
+
4
+ *Authors:* Kan Yang, Xiaohua Jia
5
+
6
+ | **Title:** "Expressive, Efficient, and Revocable Data Access Control for Multi-Authority Cloud Storage"
7
+ | **Published in:** IEEE Transactions on Parallel and Distributed Systems, Volume 25, Issue 7, 2014
8
+ | **Available from:** http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6620875
9
+ | **Notes:** Supports expressive access policies with efficient 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 MAABE(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
+ b = self.group.random()
45
+ g_a = g ** a
46
+ g_b = g ** b
47
+ GPP = {'g': g, 'g_a': g_a, 'g_b': g_b, 'H': H}
48
+ GMK = {'a': a, 'b': b}
49
+
50
+ return (GPP, GMK)
51
+
52
+ def registerUser(self, GPP):
53
+ '''Generate user keys (executed by the user).'''
54
+ g = GPP['g']
55
+ ugsk1 = self.group.random()
56
+ ugsk2 = self.group.random()
57
+ ugpk1 = g ** ugsk1
58
+ ugpk2 = g ** ugsk2
59
+
60
+ return ((ugpk1, ugsk2), { 'pk': ugpk2, 'sk': ugsk1 }) # (private, public)
61
+
62
+ def setupAuthority(self, GPP, authorityid, attributes, authorities):
63
+ '''Generate attribute authority keys (executed by attribute authority)'''
64
+ if authorityid not in authorities:
65
+ alpha = self.group.random()
66
+ beta = self.group.random()
67
+ gamma = self.group.random()
68
+ SK = {'alpha': alpha, 'beta': beta, 'gamma': gamma}
69
+ PK = {
70
+ 'e_alpha': pair(GPP['g'], GPP['g']) ** alpha,
71
+ 'g_beta': GPP['g'] ** beta,
72
+ 'g_beta_inv': GPP['g'] ** ~beta
73
+ }
74
+ authAttrs = {}
75
+ authorities[authorityid] = (SK, PK, authAttrs)
76
+ else:
77
+ SK, PK, authAttrs = authorities[authorityid]
78
+ for attrib in attributes:
79
+ if attrib in authAttrs:
80
+ continue
81
+ versionKey = self.group.random() # random or really 'choose' ?
82
+ h = GPP['H'](attrib)
83
+ pk = h ** versionKey
84
+ authAttrs[attrib] = {
85
+ 'VK': versionKey, #secret
86
+ 'PK1': pk, #public
87
+ 'PK2': pk ** SK['gamma'] #public
88
+ }
89
+ return (SK, PK, authAttrs)
90
+
91
+ def keygen(self, GPP, authority, attribute, userObj, USK = None):
92
+ '''Generate user keys for a specific attribute (executed on attribute authority)'''
93
+ if 't' not in userObj:
94
+ userObj['t'] = self.group.random() #private to AA
95
+ t = userObj['t']
96
+
97
+ ASK, APK, authAttrs = authority
98
+ u = userObj
99
+ if USK is None:
100
+ USK = {}
101
+ if 'K' not in USK or 'KS' not in USK or 'AK' not in USK:
102
+ USK['K'] = \
103
+ (GPP['g'] ** ASK['alpha']) * \
104
+ (GPP['g_a'] ** u['sk']) * \
105
+ (GPP['g_b'] ** t)
106
+ USK['KS'] = GPP['g'] ** t
107
+ USK['AK'] = {}
108
+ AK = (u['pk'] ** (t * ASK['beta'])) * \
109
+ ((authAttrs[attribute]['PK1'] ** ASK['beta']) ** (u['sk'] + ASK['gamma']))
110
+ USK['AK'][attribute] = AK
111
+ return USK
112
+
113
+ def encrypt(self, GPP, policy_str, k, authority):
114
+ '''Generate the cipher-text from the content(-key) and a policy (executed by the content owner)'''
115
+ #GPP are global parameters
116
+ #k is the content key (group element based on AES key)
117
+ #policy_str is the policy string
118
+ #authority is the authority tuple
119
+
120
+ _, APK, authAttrs = authority
121
+
122
+ policy = self.util.createPolicy(policy_str)
123
+ secret = self.group.random()
124
+ shares = self.util.calculateSharesList(secret, policy)
125
+ shares = dict([(x[0].getAttributeAndIndex(), x[1]) for x in shares])
126
+
127
+ C1 = k * (APK['e_alpha'] ** secret)
128
+ C2 = GPP['g'] ** secret
129
+ C3 = GPP['g_b'] ** secret
130
+ C = {}
131
+ CS = {}
132
+ D = {}
133
+ DS = {}
134
+
135
+ for attr, s_share in shares.items():
136
+ k_attr = self.util.strip_index(attr)
137
+ r_i = self.group.random()
138
+ attrPK = authAttrs[attr]
139
+ C[attr] = (GPP['g_a'] ** s_share) * ~(attrPK['PK1'] ** r_i)
140
+ CS[attr] = GPP['g'] ** r_i
141
+ D[attr] = APK['g_beta_inv'] ** r_i
142
+ DS[attr] = attrPK['PK2'] ** r_i
143
+
144
+ return {'C1': C1, 'C2': C2, 'C3': C3, 'C': C, 'CS': CS, 'D': D, 'DS': DS, 'policy': policy_str}
145
+
146
+ def decrypt(self, GPP, CT, user):
147
+ '''Decrypts the content(-key) from the cipher-text (executed by user/content consumer)'''
148
+ UASK = user['authoritySecretKeys']
149
+ USK = user['keys']
150
+ usr_attribs = list(UASK['AK'].keys())
151
+ policy = self.util.createPolicy(CT['policy'])
152
+ pruned = self.util.prune(policy, usr_attribs)
153
+ if pruned == False:
154
+ return False
155
+ coeffs = self.util.getCoefficients(policy)
156
+
157
+ first = pair(CT['C2'], UASK['K']) * ~pair(CT['C3'], UASK['KS'])
158
+ n_a = 1
159
+
160
+ ugpk1, ugsk2 = USK
161
+ e_gg_auns = 1
162
+
163
+ for attr in pruned:
164
+ x = attr.getAttributeAndIndex()
165
+ y = attr.getAttribute()
166
+ temp = \
167
+ pair(CT['C'][y], ugpk1) * \
168
+ pair(CT['D'][y], UASK['AK'][y]) * \
169
+ pair(CT['CS'][y], ~(UASK['KS'] ** ugsk2)) * \
170
+ ~pair(GPP['g'], CT['DS'][y])
171
+ e_gg_auns *= temp ** (coeffs[x] * n_a)
172
+ return CT['C1'] / (first / e_gg_auns)
173
+
174
+ def ukeygen(self, GPP, authority, attribute, userObj):
175
+ '''Generate update keys for users and cloud provider (executed by attribute authority?)'''
176
+ ASK, _, authAttrs = authority
177
+ oldVersionKey = authAttrs[attribute]['VK']
178
+ newVersionKey = oldVersionKey
179
+ while oldVersionKey == newVersionKey:
180
+ newVersionKey = self.group.random()
181
+ authAttrs[attribute]['VK'] = newVersionKey
182
+
183
+ u_uid = userObj['sk']
184
+ UKs = GPP['H'](attribute) ** (ASK['beta'] * (newVersionKey - oldVersionKey) * (u_uid + ASK['gamma']))
185
+ UKc = (newVersionKey/oldVersionKey, (oldVersionKey - newVersionKey)/(oldVersionKey * ASK['gamma']))
186
+
187
+ authAttrs[attribute]['PK1'] = authAttrs[attribute]['PK1'] ** UKc[0]
188
+ authAttrs[attribute]['PK2'] = authAttrs[attribute]['PK2'] ** UKc[0]
189
+
190
+ return { 'UKs': UKs, 'UKc': UKc }
191
+
192
+ def skupdate(self, USK, attribute, UKs):
193
+ '''Updates the user attribute secret key for the specified attribute (executed by non-revoked user)'''
194
+ USK['AK'][attribute] = USK['AK'][attribute] * UKs
195
+
196
+ def ctupdate(self, GPP, CT, attribute, UKc):
197
+ '''Updates the cipher-text using the update key, because of the revoked attribute (executed by cloud provider)'''
198
+ CT['C'][attribute] = CT['C'][attribute] * (CT['DS'][attribute] ** UKc[1])
199
+ CT['DS'][attribute] = CT['DS'][attribute] ** UKc[0]
200
+
201
+ def basicTest():
202
+ print("RUN basicTest")
203
+ groupObj = PairingGroup('SS512')
204
+ maabe = MAABE(groupObj)
205
+ GPP, GMK = maabe.setup()
206
+
207
+ users = {} # public user data
208
+ authorities = {}
209
+
210
+ authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"]
211
+ authority1 = "authority1"
212
+
213
+ maabe.setupAuthority(GPP, authority1, authorityAttributes, authorities)
214
+
215
+ alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None }
216
+ alice['keys'], users[alice['id']] = maabe.registerUser(GPP)
217
+
218
+ for attr in authorityAttributes[0:-1]:
219
+ maabe.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys'])
220
+
221
+ k = groupObj.random(GT)
222
+
223
+ policy_str = '((ONE or THREE) and (TWO or FOUR))'
224
+
225
+ CT = maabe.encrypt(GPP, policy_str, k, authorities[authority1])
226
+
227
+ PT = maabe.decrypt(GPP, CT, alice)
228
+
229
+ # print "k", k
230
+ # print "PT", PT
231
+
232
+ assert k == PT, 'FAILED DECRYPTION!'
233
+ print('SUCCESSFUL DECRYPTION')
234
+
235
+ def revokedTest():
236
+ print("RUN revokedTest")
237
+ groupObj = PairingGroup('SS512')
238
+ maabe = MAABE(groupObj)
239
+ GPP, GMK = maabe.setup()
240
+
241
+ users = {} # public user data
242
+ authorities = {}
243
+
244
+ authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"]
245
+ authority1 = "authority1"
246
+
247
+ maabe.setupAuthority(GPP, authority1, authorityAttributes, authorities)
248
+
249
+ alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None }
250
+ alice['keys'], users[alice['id']] = maabe.registerUser(GPP)
251
+
252
+ bob = { 'id': 'bob', 'authoritySecretKeys': {}, 'keys': None }
253
+ bob['keys'], users[bob['id']] = maabe.registerUser(GPP)
254
+
255
+ for attr in authorityAttributes[0:-1]:
256
+ maabe.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys'])
257
+ maabe.keygen(GPP, authorities[authority1], attr, users[bob['id']], bob['authoritySecretKeys'])
258
+
259
+ k = groupObj.random(GT)
260
+
261
+ policy_str = '((ONE or THREE) and (TWO or FOUR))'
262
+
263
+ CT = maabe.encrypt(GPP, policy_str, k, authorities[authority1])
264
+
265
+ PT1a = maabe.decrypt(GPP, CT, alice)
266
+ PT1b = maabe.decrypt(GPP, CT, bob)
267
+
268
+ assert k == PT1a, 'FAILED DECRYPTION (1a)!'
269
+ assert k == PT1b, 'FAILED DECRYPTION (1b)!'
270
+ print('SUCCESSFUL DECRYPTION 1')
271
+
272
+ # revoke bob on "ONE"
273
+ attribute = "ONE"
274
+ UK = maabe.ukeygen(GPP, authorities[authority1], attribute, users[alice['id']])
275
+ maabe.skupdate(alice['authoritySecretKeys'], attribute, UK['UKs'])
276
+ maabe.ctupdate(GPP, CT, attribute, UK['UKc'])
277
+
278
+ PT2a = maabe.decrypt(GPP, CT, alice)
279
+ PT2b = maabe.decrypt(GPP, CT, bob)
280
+
281
+ assert k == PT2a, 'FAILED DECRYPTION (2a)!'
282
+ assert k != PT2b, 'SUCCESSFUL DECRYPTION (2b)!'
283
+ print('SUCCESSFUL DECRYPTION 2')
284
+
285
+ def test():
286
+ groupObj = PairingGroup('SS512')
287
+ # k = groupObj.random()
288
+ #print "k", k, ~k, k * ~k
289
+ # g = groupObj.random(G1)
290
+ # print "g", g, pair(g, g)
291
+ # gt = groupObj.random(GT)
292
+ # print "gt", gt
293
+
294
+ if __name__ == '__main__':
295
+ basicTest()
296
+ revokedTest()
297
+ # test()
@@ -0,0 +1,309 @@
1
+ '''
2
+ **Time-Based Proxy Re-Encryption (LWW14)**
3
+
4
+ *Authors:* Qin Liu, Guojun Wang, Jie Wu
5
+
6
+ | **Title:** "Time-based proxy re-encryption scheme for secure data sharing in a cloud environment"
7
+ | **Published in:** Information Sciences, Volume 258, 2014
8
+ | **Available from:** http://www.sciencedirect.com/science/article/pii/S0020025512006275
9
+ | **Notes:** Time-based access control with proxy re-encryption for cloud storage
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
+
26
+ from functools import reduce
27
+
28
+ # taken from https://gist.github.com/endolith/114336
29
+ def gcd(*numbers):
30
+ """Return the greatest common divisor of the given integers"""
31
+ import sys
32
+ if sys.version_info < (3, 5):
33
+ from fractions import gcd
34
+ else:
35
+ from math import gcd
36
+ return reduce(gcd, numbers)
37
+
38
+ # taken from https://gist.github.com/endolith/114336
39
+ def lcm(numbers):
40
+ """Return lowest common multiple."""
41
+ def lcm(a, b):
42
+ return (a * b) // gcd(a, b)
43
+ return reduce(lcm, numbers, 1)
44
+
45
+ class TBPRE(object):
46
+ def __init__(self, groupObj):
47
+ self.util = SecretUtil(groupObj, verbose=False) #Create Secret Sharing Scheme
48
+ self.group = groupObj #:Prime order group
49
+ #self.users = {}
50
+ #self.authorities = {}
51
+
52
+ def setup(self, attributes):
53
+ '''Global Setup (executed by CA)'''
54
+ P0 = self.group.random(G1) # generator
55
+ P1 = self.group.random(G1) # random element
56
+ s = self.group.random()
57
+ mk0 = self.group.random()
58
+ mk1 = self.group.random()
59
+ Q0 = P0 ** mk0
60
+ SK1 = P1 ** mk0
61
+
62
+ Htemp = lambda x, y: self.group.hash(x + y, ZR)
63
+ H = {
64
+ 'user': lambda x: self.group.hash(str(x), ZR), # first convert G1 to str, then hash
65
+ 'attr': lambda x: Htemp(x,"_attribute"),
66
+ 'sy': lambda x: Htemp(x,"_year"),
67
+ 'sym': lambda x: Htemp(x,"_year_month"),
68
+ 'symd': lambda x: Htemp(x,"_year_month_day")
69
+ }
70
+
71
+ PK = { 'A': {}, 'Q0': Q0, 'P0': P0, 'P1': P1 }
72
+ MK = { 'A': {}, 'mk0': mk0, 'mk1': mk1, 'SK1': SK1 }
73
+ for attribute in attributes:
74
+ ska = self.group.random()
75
+ PKa = P0 ** ska
76
+ PK['A'][attribute] = PKa
77
+ MK['A'][attribute] = ska
78
+
79
+ #self.MK = MK # private
80
+ #self.s = s # sent to cloud service provider
81
+ #self.PK = PK # public
82
+
83
+ return (MK, PK, s, H)
84
+
85
+ def registerUser(self, PK, H):
86
+ '''Registers a user by id (executed by user)'''
87
+ sku = self.group.random()
88
+ PKu = PK['P0'] ** sku
89
+ mku = H['user'](PKu)
90
+
91
+ #self.users[userid] = { 'PKu': PKu, 'mku': mku }
92
+ return (sku, { 'PKu': PKu, 'mku': mku }) # (private, public)
93
+
94
+ def hashDate(self, H, time, s):
95
+ hash = s
96
+ key = 'y'
97
+ if "year" in time:
98
+ hash = H['sy'](time['year']) ** hash
99
+ else:
100
+ print("Error: time has to contain at least 'year'")
101
+ return None, None
102
+ if "month" in time:
103
+ hash = H['sym'](time['month']) ** hash
104
+ key = 'ym'
105
+ if "day" in time:
106
+ hash = H['symd'](time['day']) ** hash
107
+ key = 'ymd'
108
+ elif "day" in time:
109
+ print("Error: time has to contain 'month' if it contains 'year'")
110
+ return None, None
111
+ return hash, key
112
+
113
+ def timeSuffices(self, timeRange, needle):
114
+ # assumes that the time obj is valid
115
+ if timeRange['year'] != needle['year']:
116
+ return False
117
+ if 'month' not in timeRange:
118
+ return True
119
+ if 'month' not in needle:
120
+ return None # Error
121
+ if timeRange['month'] != needle['month']:
122
+ return False
123
+ if 'day' not in timeRange:
124
+ return True
125
+ if 'day' not in needle:
126
+ return None # Error
127
+ return timeRange['day'] == needle['day']
128
+
129
+ def policyTerm(self, user, policy):
130
+ userAttributes = user['A'].keys()
131
+ for i, term in zip(range(len(policy)), policy):
132
+ notFound = False
133
+ for termAttr in term:
134
+ if termAttr not in userAttributes:
135
+ notFound = True
136
+ break
137
+ if not notFound:
138
+ return i
139
+ return False
140
+
141
+ def keygen(self, MK, PK, H, s, user, pubuser, attribute, time):
142
+ '''Generate user keys for a specific attribute (executed by CA)'''
143
+
144
+ hash, key = self.hashDate(H, time, s)
145
+ if hash is None:
146
+ return None
147
+
148
+ if 'SKu' not in user:
149
+ user['SKu'] = PK['P0'] ** (MK['mk1'] * pubuser['mku'])
150
+ PKat = PK['A'][attribute] * (PK['P0'] ** hash)
151
+ SKua = MK['SK1'] * (PKat ** (MK['mk1'] * pubuser['mku']))
152
+
153
+ if 'A' not in user:
154
+ user['A'] = {}
155
+ if attribute not in user['A']:
156
+ user['A'][attribute] = []
157
+ user['A'][attribute].append((time, SKua))
158
+
159
+ def encrypt(self, PK, policy, F):
160
+ '''Generate the cipher-text from the content(-key) and a policy (executed by the content owner)'''
161
+ r = self.group.random()
162
+ nA = lcm(map(lambda x: len(x), policy))
163
+ U0 = PK['P0'] ** r
164
+ attributes = []
165
+ U = []
166
+ for term in policy:
167
+ Ui = 1
168
+ for attribute in term:
169
+ Ui *= PK['A'][attribute]
170
+ U.append(Ui ** r)
171
+ V = F * pair(PK['Q0'], PK['P1'] ** (r * nA))
172
+ return { 'A': policy, 'U0': U0, 'U': U, 'V': V, 'nA': nA }
173
+
174
+ def decrypt(self, CT, user, term = None):
175
+ '''Decrypts the content(-key) from the cipher-text (executed by user/content consumer)'''
176
+ if term is None:
177
+ term = self.policyTerm(user, CT['A'])
178
+ if term is False:
179
+ print("Error: user attributes don't satisfy the policy")
180
+ return None
181
+
182
+ sumSK = 1
183
+ for attribute in CT['A'][term]:
184
+ foundTimeSlot = False
185
+ for timeRange, SKua in user['A'][attribute]:
186
+ if self.timeSuffices(timeRange, CT['t']):
187
+ foundTimeSlot = True
188
+ sumSK *= SKua
189
+ break
190
+ if not foundTimeSlot:
191
+ print("Error: could not find time slot in user attribute keys")
192
+ return None
193
+
194
+
195
+ n = CT['nA'] // len(CT['A'][term])
196
+ return CT['Vt'] / (pair(CT['U0t'], sumSK ** n) / pair(user['SKu'], CT['Ut']['year'][term] ** n)) # TODO: fix year
197
+
198
+ def reencrypt(self, PK, H, s, CT, currentTime):
199
+ '''Re-encrypts the cipher-text using the current time (executed by cloud service provider)'''
200
+ if 'year' not in currentTime or 'month' not in currentTime or 'day' not in currentTime:
201
+ print("Error: pass proper current time containing 'year', 'month' and 'day'")
202
+ return None
203
+
204
+ day = currentTime
205
+ month = dict(day)
206
+ del month['day']
207
+ year = dict(month)
208
+ del year['month']
209
+
210
+ day, daykey = self.hashDate(H, day, s)
211
+ month, monthkey = self.hashDate(H, month, s)
212
+ year, yearkey = self.hashDate(H, year, s)
213
+
214
+ rs = self.group.random()
215
+ U0t = CT['U0'] * (PK['P0'] ** rs)
216
+
217
+ Ut = { 'year': [], 'month': [], 'day': [] }
218
+ for term, Ui in zip(CT['A'], CT['U']):
219
+ Uit_year = Ui
220
+ Uit_month = Ui
221
+ Uit_day = Ui
222
+ for attribute in term:
223
+ Uit_year *= (PK['A'][attribute] ** rs) * (U0t ** year)
224
+ Uit_month *= (PK['A'][attribute] ** rs) * (U0t ** month)
225
+ Uit_day *= (PK['A'][attribute] ** rs) * (U0t ** day)
226
+ Ut['year'].append(Uit_year)
227
+ Ut['month'].append(Uit_month)
228
+ Ut['day'].append(Uit_day)
229
+
230
+ Vt = CT['V'] * pair(PK['Q0'], PK['P1'] ** (rs * CT['nA']))
231
+
232
+ return { 'A': CT['A'], 'U0t': U0t, 'Ut': Ut, 'Vt': Vt, 'nA': CT['nA'], 't': currentTime }
233
+
234
+ def basicTest():
235
+ print("RUN basicTest")
236
+ groupObj = PairingGroup('SS512')
237
+ tbpre = TBPRE(groupObj)
238
+ attributes = ["ONE", "TWO", "THREE", "FOUR"]
239
+ MK, PK, s, H = tbpre.setup(attributes)
240
+
241
+ users = {} # public
242
+
243
+ alice = { 'id': 'alice' }
244
+ alice['sku'], users[alice['id']] = tbpre.registerUser(PK, H)
245
+ alice2 = { 'id': 'alice2' }
246
+ alice2['sku'], users[alice2['id']] = tbpre.registerUser(PK, H)
247
+
248
+ year = { 'year': "2014" }
249
+ pastYear = { 'year': "2013" }
250
+
251
+ for attr in attributes[0:-1]:
252
+ tbpre.keygen(MK, PK, H, s, alice, users[alice['id']], attr, year)
253
+ tbpre.keygen(MK, PK, H, s, alice2, users[alice2['id']], attr, pastYear)
254
+
255
+ k = groupObj.random(GT)
256
+
257
+ policy = [['ONE', 'THREE'], ['TWO', 'FOUR']] # [['ONE' and 'THREE'] or ['TWO' and 'FOUR']]
258
+ currentDate = { 'year': "2014", 'month': "2", 'day': "15" }
259
+
260
+ CT = tbpre.encrypt(PK, policy, k)
261
+ CTt = tbpre.reencrypt(PK, H, s, CT, currentDate)
262
+ PT = tbpre.decrypt(CTt, alice)
263
+
264
+ assert k == PT, 'FAILED DECRYPTION! 1'
265
+ print('SUCCESSFUL DECRYPTION 1')
266
+
267
+ PT2 = tbpre.decrypt(CTt, alice2)
268
+
269
+ assert k != PT2, 'SUCCESSFUL DECRYPTION! 2'
270
+ print('DECRYPTION correctly failed')
271
+
272
+ def basicTest2():
273
+ '''Month-based attributes are used'''
274
+ print("RUN basicTest2")
275
+ groupObj = PairingGroup('SS512')
276
+ tbpre = TBPRE(groupObj)
277
+ attributes = ["ONE", "TWO", "THREE", "FOUR"]
278
+ MK, PK, s, H = tbpre.setup(attributes)
279
+
280
+ users = {} # public
281
+
282
+ alice = { 'id': 'alice' }
283
+ alice['sku'], users[alice['id']] = tbpre.registerUser(PK, H)
284
+
285
+ year = { 'year': "2014", 'month': '2' }
286
+
287
+ for attr in attributes[0:-1]:
288
+ tbpre.keygen(MK, PK, H, s, alice, users[alice['id']], attr, year)
289
+
290
+ k = groupObj.random(GT)
291
+
292
+ policy = [['ONE', 'THREE'], ['TWO', 'FOUR']] # [['ONE' and 'THREE'] or ['TWO' and 'FOUR']]
293
+ currentDate = { 'year': "2014", 'month': "2", 'day': "15" }
294
+
295
+ CT = tbpre.encrypt(PK, policy, k)
296
+ CTt = tbpre.reencrypt(PK, H, s, CT, currentDate)
297
+ PT = tbpre.decrypt(CTt, alice)
298
+
299
+ assert k == PT, 'FAILED DECRYPTION!'
300
+ print('SUCCESSFUL DECRYPTION')
301
+
302
+ def test():
303
+ # print 1, lcm(1, 2)
304
+ print(2, lcm([1, 2]))
305
+
306
+ if __name__ == '__main__':
307
+ basicTest()
308
+ # basicTest2()
309
+ # test()