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,15 @@
1
+ #ifndef __BASE64_H__
2
+ #define __BASE64_H__
3
+
4
+ #include <stdio.h>
5
+ #include <string.h>
6
+ #include <stdlib.h>
7
+
8
+ #define TRUE 1
9
+ #define FALSE 0
10
+
11
+ void *NewBase64Decode(const char *inputBuffer, size_t length, size_t *outputLength);
12
+
13
+ char *NewBase64Encode(const void *inputBuffer, size_t length, int separateLines, size_t *outputLength);
14
+
15
+ #endif
File without changes
File without changes
@@ -0,0 +1,647 @@
1
+ '''
2
+ **ABE with Privacy Protection and Accountability (JYJXGD20)**
3
+
4
+ *Authors:* Jiguo Li, Yichen Zhang, Jianting Ning, Xinyi Huang, Geong Sen Poh, Debang Wang
5
+
6
+ | **Title:** "Attribute Based Encryption with Privacy Protection and Accountability for CloudIoT"
7
+ | **Published in:** IEEE Transactions on Cloud Computing, 2020
8
+ | **Available from:** https://ieeexplore.ieee.org/abstract/document/9003205
9
+ | **Notes:** Two schemes implemented: (1) CP policy hiding (class CP_Hiding_ABE), (2) CP policy hiding with accountability under white box assumption (class CP_Hiding_Accountability_ABE)
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: Ahmed Bakr
20
+ :Date: 08/2023
21
+ '''
22
+
23
+ from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
24
+ from charm.toolbox.ABEnc import ABEnc
25
+
26
+ from typing import Dict, List
27
+
28
+
29
+ class Attribute:
30
+ def __init__(self, attr_name, values_list: List[str] = []):
31
+ # Validation
32
+ self.__validate_attribute_values_name(attr_name)
33
+ for value_str in values_list:
34
+ self.__validate_attribute_values_name(value_str)
35
+
36
+ self.name = attr_name
37
+ self.values = values_list
38
+
39
+ @staticmethod
40
+ def __validate_attribute_values_name(attr_value_name: str):
41
+ assert attr_value_name.find('_') == -1, "Attribute name cannot contain an '_'"
42
+
43
+ def add_value(self, value: str):
44
+ self.__validate_attribute_values_name(value) # Validation
45
+ self.values.append(value)
46
+
47
+ def set_values(self, values_list: List[str]):
48
+ self.values = values_list
49
+
50
+ def get_attribute_values_full_name(self):
51
+ """
52
+ Attribute values full name is in the following format: 'attrName_value'
53
+ """
54
+ full_names_list = []
55
+ for value in self.values:
56
+ full_names_list.append(self.name + "_" + value)
57
+
58
+ return full_names_list
59
+
60
+ @staticmethod
61
+ def get_full_attribute_value_name(attr_name: str, value_name: str):
62
+ Attribute.__validate_attribute_values_name(attr_name) # Validation
63
+ Attribute.__validate_attribute_values_name(value_name) # Validation
64
+ return attr_name + '_' + value_name
65
+
66
+
67
+ class CP_Hiding_ABE(ABEnc):
68
+ """
69
+ Cipher text policy hiding attribute based encryption (Section 3 in the paper).
70
+ """
71
+ def __init__(self, group_obj):
72
+ ABEnc.__init__(self)
73
+ self._group = group_obj
74
+ self.attributes_dict: Dict[str, List[str]] = None
75
+
76
+ def setup(self, attributes_dict: Dict[str, List[str]]):
77
+ """
78
+ System Setup algorithm. This algorithm is performed by TA.
79
+ Inputs:
80
+ - None
81
+ Outputs:
82
+ - MSK: TA's master secret key.
83
+ - PK: Public Parameters.
84
+ """
85
+ self.attributes_dict = attributes_dict
86
+ g = self._group.random(G1)
87
+ u = self._group.random(G1)
88
+ v = self._group.random(G1)
89
+ h = self._group.random(G1)
90
+ w = self._group.random(G1)
91
+
92
+ alpha = self._group.random(ZR)
93
+
94
+ MSK = alpha
95
+ PK = {'g': g,
96
+ 'e_gg': pair(g, g),
97
+ 'u': u,
98
+ 'h': h,
99
+ 'w': w,
100
+ 'v': v,
101
+ 'e_gg_alpha': pair(g, g) ** alpha}
102
+ return MSK, PK
103
+
104
+ def key_gen(self, MSK, PK, attributes_list):
105
+ """
106
+ Key generation for a user based on his list of attributes. This algorithm is performed by TA.
107
+ Inputs:
108
+ - MSK: Master Secret Key of the TA.
109
+ - PK: Public parameters and the public key of the TA.
110
+ - attributes_list: List of attributes held by this user, where each attribute is in the format:
111
+ 'attrName_value'
112
+ Outputs:
113
+ - SK: User's secret key.
114
+ """
115
+ self._validate_attributes_list(attributes_list)
116
+ r = self._group.random(ZR)
117
+ g = PK['g']
118
+ w = PK['w']
119
+ u = PK['u']
120
+ h = PK['h']
121
+ v = PK['v']
122
+ alpha = MSK
123
+
124
+ K_0 = (g ** alpha) * (w ** r)
125
+ K_1 = g ** r
126
+ K_2 = {}
127
+ K_3 = {}
128
+ for full_attr_value_name in attributes_list:
129
+ # attr_name = full_attr_value_name.split('_')[0]
130
+ r_i = self._group.random(ZR)
131
+ K_i_2 = g ** r_i
132
+ hash_attr_val_in_z_p = self._group.hash(full_attr_value_name, type=ZR)
133
+ K_i_3 = (((u ** hash_attr_val_in_z_p) * h) ** r_i) * v ** (-r)
134
+ K_2[full_attr_value_name] = K_i_2
135
+ K_3[full_attr_value_name] = K_i_3
136
+ SK = {'attributes_list': attributes_list, 'K_0': K_0, 'K_1': K_1, 'K_2': K_2, 'K_3': K_3}
137
+ return SK
138
+
139
+ def _validate_attributes_list(self, attributes_list):
140
+ """
141
+ each attribute is in the format: 'attrName_value'
142
+ """
143
+ for attr_value in attributes_list:
144
+ assert attr_value.find('_') == attr_value.rfind('_') and attr_value.find('_') != -1, (
145
+ "The format is 'attrName_value'")
146
+ splitted_str = attr_value.split('_')
147
+ assert len(splitted_str[0]) > 0 and len(splitted_str[1])> 0, "The format is 'attrName_value'"
148
+
149
+ def encrypt(self, m, PK, access_policy: Dict[str, List[str]]):
150
+ """
151
+ Encrypt a message using an access policy. This function is performed by a data user who wants to encrypt his
152
+ message with an access policy. They consider only and-gates in their policy.
153
+ Note: The access policy is hidden into the ciphertext.
154
+ Inputs:
155
+ - PK: Public parameters and the public key of the TA.
156
+ - m: Message to be encrypted in G_T.
157
+ - access_policy: Access policy that will be used to encrypt the message. It has to be and gated policy,
158
+ which means that each attribute can have only one value.
159
+ Outputs:
160
+ - CT: Cipher text.
161
+ """
162
+ g = PK['g']
163
+ w = PK['w']
164
+ v = PK['v']
165
+ u = PK['u']
166
+ h = PK['h']
167
+ s = self._group.random(ZR)
168
+ s_n = s
169
+ access_policy_len = len(access_policy)
170
+ C = m * PK['e_gg_alpha'] ** s
171
+ C_1 = g ** s
172
+ C_i_1 = {}
173
+ C_i_3 = {}
174
+ C_i_2 = {}
175
+ for idx, attr_name in enumerate(access_policy):
176
+ if idx < access_policy_len - 1:
177
+ s_i = self._group.random(ZR)
178
+ s_n = s_n - s_i
179
+ else:
180
+ s_i = s_n
181
+ t_i = self._group.random(ZR)
182
+ C_i_1[attr_name] = (w ** s_i) * (v ** t_i)
183
+ C_i_3[attr_name] = g ** t_i
184
+
185
+ for attr_value in self.attributes_dict[attr_name]:
186
+ full_attr_value_name = Attribute.get_full_attribute_value_name(attr_name, attr_value)
187
+ if attr_value in access_policy[attr_name]:
188
+ hash_attr_val_in_z_p = self._group.hash(full_attr_value_name, type=ZR)
189
+ C_i_ai_2 = ((u ** hash_attr_val_in_z_p) * h) ** (-t_i)
190
+ else:
191
+ C_i_ai_2 = self._group.random(G1)
192
+ C_i_2[full_attr_value_name] = C_i_ai_2
193
+ CT = {'C': C,
194
+ 'C_1': C_1,
195
+ 'C_i_1': C_i_1,
196
+ 'C_i_3': C_i_3,
197
+ 'C_i_ai_2': C_i_2}
198
+ return CT
199
+
200
+ def decrypt(self, CT, PK, SK):
201
+ """
202
+ Decrypt a cipher text. This algorithm is performed by a data user who has the required attributes to decipher
203
+ the ciphertext that was encrypted using an access policy.
204
+ Inputs:
205
+ - CT: Cipher text.
206
+ - PK: Public parameters and the public key of the TA.
207
+ - SK: User's secret key.
208
+ Outputs:
209
+ - m: The original decrypted message.
210
+ """
211
+ nominator = pair(CT['C_1'], SK['K_0'])
212
+ denominator = self._group.init(GT, 1)
213
+ for attr_name in CT['C_i_1']:
214
+ # Find the attribute value that exists inside both the user's key for attr_name
215
+ found_attribute_value_full_name = None
216
+ for attr_value_full_name in SK['K_2']:
217
+ if attr_value_full_name.find(attr_name) == 0:
218
+ found_attribute_value_full_name = attr_value_full_name
219
+ if not found_attribute_value_full_name:
220
+ return False # The user does not have the necessary attributes to decrypt
221
+
222
+ denominator = (denominator * pair(CT['C_i_1'][attr_name], SK['K_1']) *
223
+ pair(CT['C_i_ai_2'][found_attribute_value_full_name],
224
+ SK['K_2'][found_attribute_value_full_name]) *
225
+ pair(CT['C_i_3'][attr_name], SK['K_3'][found_attribute_value_full_name]))
226
+ B = nominator / denominator
227
+ recovered_message = CT['C'] / B
228
+ return recovered_message
229
+
230
+ class CP_Hiding_Accountability_ABE(CP_Hiding_ABE):
231
+ """
232
+ Cipher text policy hiding attribute based encryption (Section 4 in the paper).
233
+ """
234
+ def __init__(self, group_obj):
235
+ CP_Hiding_ABE.__init__(self, group_obj)
236
+ self._user_ID_to_w_pow_k_dict = {} # Updated inside the key generation function to map the user ID to his
237
+ # associated R = w ** k.
238
+
239
+ def setup(self, attributes_dict: Dict[str, List[str]]):
240
+ """
241
+ System Setup algorithm. This algorithm is performed by TA.
242
+ Inputs:
243
+ - None
244
+ Outputs:
245
+ - MSK: TA's master secret key.
246
+ - PK: Public Parameters.
247
+ """
248
+ self.attributes_dict = attributes_dict
249
+ g = self._group.random(G1)
250
+ u = self._group.random(G1)
251
+ v = self._group.random(G1)
252
+ h = self._group.random(G1)
253
+ w = self._group.random(G1)
254
+
255
+ alpha = self._group.random(ZR)
256
+ x = self._group.random(ZR)
257
+ y = self._group.random(ZR)
258
+
259
+ X = g ** x
260
+ Y = g ** y
261
+
262
+ MSK = {
263
+ 'alpha': alpha,
264
+ 'x': x,
265
+ 'y': y
266
+ }
267
+ PK = {'g': g,
268
+ 'e_gg': pair(g, g),
269
+ 'u': u,
270
+ 'h': h,
271
+ 'w': w,
272
+ 'v': v,
273
+ 'e_gg_alpha': pair(g, g) ** alpha,
274
+ 'X': X,
275
+ 'Y': Y
276
+ }
277
+ return MSK, PK
278
+
279
+ def key_gen(self, MSK, PK, ID, attributes_list):
280
+ """
281
+ Key generation for a user based on his list of attributes. This algorithm is performed by TA and the user.
282
+ Part of the key generation is executed as an interaction between the user and the TA, as the user generates
283
+ a random number (k) that he does not share with the TA. However, he shares with it w**k, and proves knowledge of
284
+ (k) to TA using any ZKP algorithm.
285
+ Inputs:
286
+ - MSK: Master Secret Key of the TA.
287
+ - PK: Public parameters and the public key of the TA.
288
+ - ID: User's unique identifier.
289
+ - attributes_list: List of attributes held by this user, where each attribute is in the format:
290
+ 'attrName_value'
291
+ Outputs:
292
+ - SK: User's secret key.
293
+ """
294
+ w = PK['w']
295
+
296
+ # The part executed by the user
297
+ k = self._group.random(ZR) # Select a secret KFN (Key Family Number).
298
+ R = w ** k
299
+
300
+ # User is going to send R to the TA and prove knowledge of k using Shnorr's ZKP.
301
+ zkp_prover = ShnorrInteractiveZKP.Prover(k, self._group) # The user.
302
+ zkp_verifier = ShnorrInteractiveZKP.Verifier(self._group) # The TA.
303
+ pk = {'g': w} # Work around to user (w) as the group point instead of (g)
304
+ u = zkp_prover.create_prover_commitments(pk)
305
+ c = zkp_verifier.create_verifier_challenge()
306
+ z = zkp_prover.create_proof(c)
307
+ assert zkp_verifier.is_proof_verified(z, pk, u, R), \
308
+ "User failed to proof knowledge of (k) that is used to calculate R"
309
+
310
+ SK = self.key_gen_TA(MSK, PK, ID, R, attributes_list)
311
+
312
+ # The user gets the SK and adds his secret KFN to it.
313
+ SK['k'] = k
314
+ return SK
315
+
316
+ def key_gen_TA(self, MSK, PK, ID, R, attributes_list):
317
+ """
318
+ Key generation for a user based on his list of attributes. This algorithm is performed by TA and the user.
319
+ Part of the key generation is executed as an interaction between the user and the TA, as the user generates
320
+ a random number (k) that he does not share with the TA. However, he shares with it w**k, and proves knowledge of
321
+ (k) to TA using any ZKP algorithm.
322
+ Inputs:
323
+ - MSK: Master Secret Key of the TA.
324
+ - PK: Public parameters and the public key of the TA.
325
+ - ID: User's unique identifier.
326
+ - R: w ** k, where (w) is a public point on the curve, and (k) is the secret KFN selected by the user.
327
+ - attributes_list: List of attributes held by this user, where each attribute is in the format:
328
+ 'attrName_value'
329
+ Outputs:
330
+ - SK: User's secret key.
331
+ """
332
+ self._validate_attributes_list(attributes_list)
333
+ r = self._group.random(ZR)
334
+ g = PK['g']
335
+ w = PK['w']
336
+ u = PK['u']
337
+ h = PK['h']
338
+ v = PK['v']
339
+ alpha = MSK['alpha']
340
+ x = MSK['x']
341
+ y = MSK['y']
342
+
343
+ d = self._group.random(ZR) # TODO: AB: If (x + ID + y * d) mod p = 0, then choose another d
344
+
345
+ K_0 = (g ** (alpha / (x + ID + y * d))) * (R ** r)
346
+ K_1 = g ** r
347
+ K_2 = g ** (x * r)
348
+ K_3 = g ** (y * r)
349
+ T1 = ID
350
+ T3 = d
351
+ K_i_2 = {}
352
+ K_i_3 = {}
353
+ for full_attr_value_name in attributes_list:
354
+ # attr_name = full_attr_value_name.split('_')[0]
355
+ r_i = self._group.random(ZR)
356
+ K_i_2[full_attr_value_name] = g ** r_i
357
+ hash_attr_val_in_z_p = self._group.hash(full_attr_value_name, type=ZR)
358
+ K_i_3[full_attr_value_name] = (((u ** hash_attr_val_in_z_p) * h) ** r_i) * v ** (-r * (x + ID + y * d))
359
+
360
+ self._user_ID_to_w_pow_k_dict[T1] = R
361
+
362
+ SK = {'attributes_list': attributes_list, 'K_0': K_0, 'K_1': K_1, 'K_2': K_2, 'K_3': K_3, 'K_i_2': K_i_2,
363
+ 'K_i_3': K_i_3, 'T1': T1, 'T3': T3}
364
+ return SK
365
+
366
+ def encrypt(self, m, PK, access_policy: Dict[str, List[str]]):
367
+ """
368
+ Encrypt a message using an access policy. This function is performed by a data user who wants to encrypt his
369
+ message with an access policy. They consider only and-gates in their policy.
370
+ Note: The access policy is hidden into the ciphertext.
371
+ Inputs:
372
+ - PK: Public parameters and the public key of the TA.
373
+ - m: Message to be encrypted in G_T.
374
+ - access_policy: Access policy that will be used to encrypt the message. It has to be and gated policy,
375
+ which means that each attribute can have only one value.
376
+ Outputs:
377
+ - CT: Cipher text.
378
+ """
379
+ g = PK['g']
380
+ w = PK['w']
381
+ v = PK['v']
382
+ u = PK['u']
383
+ h = PK['h']
384
+ X = PK['X']
385
+ Y = PK['Y']
386
+ s = self._group.random(ZR)
387
+ s_n = s
388
+ access_policy_len = len(access_policy)
389
+ C = m * PK['e_gg_alpha'] ** s
390
+ C_1 = g ** s
391
+ C_2 = X ** s
392
+ C_3 = Y ** s
393
+ C_i_1 = {}
394
+ C_i_3 = {}
395
+ C_i_2 = {}
396
+ for idx, attr_name in enumerate(access_policy):
397
+ if idx < access_policy_len - 1:
398
+ s_i = self._group.random(ZR)
399
+ s_n = s_n - s_i
400
+ else:
401
+ s_i = s_n
402
+ t_i = self._group.random(ZR)
403
+ C_i_1[attr_name] = (w ** s_i) * (v ** t_i)
404
+ C_i_3[attr_name] = g ** t_i
405
+
406
+ for attr_value in self.attributes_dict[attr_name]:
407
+ full_attr_value_name = Attribute.get_full_attribute_value_name(attr_name, attr_value)
408
+ if attr_value in access_policy[attr_name]:
409
+ hash_attr_val_in_z_p = self._group.hash(full_attr_value_name, type=ZR)
410
+ C_i_ai_2 = ((u ** hash_attr_val_in_z_p) * h) ** (-t_i)
411
+ else:
412
+ C_i_ai_2 = self._group.random(G1)
413
+ C_i_2[full_attr_value_name] = C_i_ai_2
414
+ CT = {'C': C,
415
+ 'C_1': C_1,
416
+ 'C_2': C_2,
417
+ 'C_3': C_3,
418
+ 'C_i_1': C_i_1,
419
+ 'C_i_3': C_i_3,
420
+ 'C_i_ai_2': C_i_2}
421
+ return CT
422
+
423
+ def decrypt(self, CT, PK, SK):
424
+ """
425
+ Decrypt a cipher text. This algorithm is performed by a data user who has the required attributes to decipher
426
+ the ciphertext that was encrypted using an access policy.
427
+ Inputs:
428
+ - CT: Cipher text.
429
+ - PK: Public parameters and the public key of the TA.
430
+ - SK: User's secret key.
431
+ Outputs:
432
+ - m: The original decrypted message.
433
+ """
434
+ nominator = pair((CT['C_1'] ** SK['T1']) * CT['C_2'] * (CT['C_3'] ** SK['T3']), SK['K_0'])
435
+ denominator = self._group.init(GT, 1)
436
+ for attr_name in CT['C_i_1']:
437
+ # Find the attribute value that exists inside both the user's key for attr_name
438
+ found_attribute_value_full_name = None
439
+ for attr_value_full_name in SK['K_i_2']:
440
+ if attr_value_full_name.find(attr_name) == 0:
441
+ found_attribute_value_full_name = attr_value_full_name
442
+ if not found_attribute_value_full_name:
443
+ return False # The user does not have the necessary attributes to decrypt
444
+
445
+ denominator = (denominator * ((pair(CT['C_i_1'][attr_name], (SK['K_1'] ** SK['T1']) * SK['K_2'] * (SK['K_3'] ** SK['T3'])) *
446
+ pair(CT['C_i_ai_2'][found_attribute_value_full_name],
447
+ SK['K_i_2'][found_attribute_value_full_name]) *
448
+ pair(CT['C_i_3'][attr_name], SK['K_i_3'][found_attribute_value_full_name])) ** SK['k']))
449
+ B = nominator / denominator
450
+ recovered_message = CT['C'] / B
451
+ return recovered_message
452
+
453
+ def trace(self, SK_suspected, authentic_user_IDs_list, PK):
454
+ """
455
+ Trace function is executed by the auditor. The auditor checks the suspected SK and determines who is misbehaving
456
+ : the user who owns SK or the TA. If this function is called, it means that either the user or the TA is
457
+ misbehaving. The trigger how this function is triggered and how the malicious activity is detected is out of
458
+ this paper's scope.
459
+ Inputs:
460
+ - SK_suspected: Secret key of the suspected user under the white box model, which means that it has access
461
+ to the full secret key of the user.
462
+ - authentic_user_IDs_list: A list of the authentic user IDs issued by a trusted third party outside the
463
+ system.
464
+ - PK: Public parameters and the public key of the TA.
465
+ Outputs:
466
+ - {'user': True/False,
467
+ 'TA': True/False} ; Only one of them will be true and the other will be false.
468
+ """
469
+ assert self._is_SK_well_formed(SK_suspected), "SK is not well formed."
470
+ user_id = SK_suspected['T1']
471
+ if user_id not in authentic_user_IDs_list:
472
+ return {'user': False, 'TA': True} # The TA issued a fake ID for a fake or not illegible user.
473
+ w_pow_k_ID = self._user_ID_to_w_pow_k_dict[user_id]
474
+ k = SK_suspected['k']
475
+ w = PK['w']
476
+ if w**k != w_pow_k_ID:
477
+ return {'user': True, 'TA': False} # User is misbehaving and gave his keys to someone else.
478
+ else:
479
+ return {'user': False, 'TA': True} # The TA is misbehaving.
480
+
481
+ def _is_SK_well_formed(self, SK):
482
+ search_keys = ['attributes_list', 'K_0', 'K_1', 'K_2', 'K_3', 'K_i_2', 'K_i_3', 'T1', 'T3', 'k']
483
+ for a_search_key in search_keys:
484
+ if a_search_key not in SK:
485
+ return False
486
+ return True
487
+
488
+
489
+
490
+ class ShnorrInteractiveZKP():
491
+ """
492
+ Shnorr's Interactive ZKP
493
+ """
494
+ class Prover:
495
+ def __init__(self, secret_x, groupObj):
496
+ self.__r = None
497
+ self.group = groupObj
498
+ self.__x = secret_x
499
+
500
+ def create_prover_commitments(self, pk):
501
+ """
502
+ 1) This function is executed by the prover to send a random value to the verifier
503
+ """
504
+ self.__r = self.group.random()
505
+ u = (pk['g'] ** self.__r)
506
+ return u
507
+
508
+ def create_proof(self, c):
509
+ """
510
+ 3) This function is executed by the prover after he received the challenge value (c) from the verifier
511
+ """
512
+ z = self.__r + c * self.__x
513
+ return z # proof
514
+
515
+ class Verifier:
516
+
517
+ def __init__(self, groupObj):
518
+ self.group = groupObj
519
+
520
+ def create_verifier_challenge(self):
521
+ """
522
+ 2) This function is executed by the verifier after he had received the value u from the prover to send a challenge value to the prover.
523
+ """
524
+ self.c = self.group.random()
525
+ return self.c
526
+
527
+ def is_proof_verified(self, z, pk, u, h):
528
+ """
529
+ 4) This function is executed by the verifier to verify the authenticity of the proof sent by the prover
530
+ z: Created by the prover in create_proof function
531
+ u: Created by the prover in create_prover_commitments function
532
+ h: g^x, where x is the secret key of the prover that he wants to prove that he knows it.
533
+ """
534
+ if (pk['g'] ** z) == u * h ** self.c:
535
+ return True
536
+ return False
537
+
538
+
539
+ def main():
540
+ CP_policy_hiding_ABE_test()
541
+ CP_policy_hiding_with_accountability_test()
542
+
543
+
544
+ def CP_policy_hiding_ABE_test():
545
+ print("************************************* CP policy hiding ABE test *******************************************")
546
+ attr1_values = ['val1', 'val2', 'val3']
547
+ attr2_values = ['val1', 'val4']
548
+ attributes_dict = {
549
+ 'attr1': attr1_values,
550
+ 'attr2': attr2_values
551
+ }
552
+ user1_attributes = ['attr1_val2', 'attr2_val4']
553
+ user2_attributes = ['attr1_val2', 'attr2_val1']
554
+ # The access policy that will be used to encrypt the message
555
+ access_policy = {'attr1': ['val1', 'val2'], # Set of attributes allowed for 'attr1' in the access policy.
556
+ 'attr2': ['val4'] # Set of attributes allowed for 'attr2' in the access policy.
557
+ }
558
+ attr1 = Attribute('attr1', attr1_values)
559
+ attr2 = Attribute('attr2', attr2_values)
560
+ attr1_values = attr1.get_attribute_values_full_name()
561
+ attr2_values = attr2.get_attribute_values_full_name()
562
+ print("attribute 1 full values names: ", attr1_values)
563
+ print("attribute 2 full values names: ", attr2_values)
564
+ group_obj = PairingGroup('SS512')
565
+ cp_hiding_ABE = CP_Hiding_ABE(group_obj)
566
+ MSK, PK = cp_hiding_ABE.setup(attributes_dict) # TA's MSK, PK
567
+ print("MSK: ", MSK)
568
+ print("PK: ", PK)
569
+ user1_SK = cp_hiding_ABE.key_gen(MSK, PK, user1_attributes)
570
+ print('user1 SK: ', user1_SK)
571
+ user2_SK = cp_hiding_ABE.key_gen(MSK, PK, user2_attributes)
572
+ print('user2 SK: ', user1_SK)
573
+ rand_msg = group_obj.random(GT)
574
+ CT = cp_hiding_ABE.encrypt(rand_msg, PK, access_policy)
575
+ print("CT: ", CT)
576
+ recovered_message = cp_hiding_ABE.decrypt(CT, PK, user1_SK)
577
+ print("recovered message: ", recovered_message)
578
+ # No error is generated since user 1's attributes matches the access policy embedded inside the CT.
579
+ assert recovered_message == rand_msg, "Random message does not match the recovered message"
580
+ # User 2 tries to decrypt CT.
581
+ recovered_message = cp_hiding_ABE.decrypt(CT, PK, user2_SK)
582
+ print("recovered message: ", recovered_message)
583
+ # An error is generated since user 2 does not have the required attributes to decrypt CT.
584
+ # assert recovered_message == rand_msg, "Random message does not match the recovered message" # Uncomment to raise the error.
585
+ print("***********************************************************************************************************")
586
+
587
+
588
+ def CP_policy_hiding_with_accountability_test():
589
+ print("*************************** CP policy hiding ABE with accountability test *********************************")
590
+ attr1_values = ['val1', 'val2', 'val3']
591
+ attr2_values = ['val1', 'val4']
592
+ attributes_dict = {
593
+ 'attr1': attr1_values,
594
+ 'attr2': attr2_values
595
+ }
596
+ user1_attributes = ['attr1_val2', 'attr2_val4']
597
+ user2_attributes = ['attr1_val2', 'attr2_val1']
598
+
599
+ user1_ID = 123
600
+ user2_ID = 57534
601
+ # The access policy that will be used to encrypt the message
602
+ access_policy = {'attr1': ['val1', 'val2'], # Set of attributes allowed for 'attr1' in the access policy.
603
+ 'attr2': ['val4'] # Set of attributes allowed for 'attr2' in the access policy.
604
+ }
605
+ attr1 = Attribute('attr1', attr1_values)
606
+ attr2 = Attribute('attr2', attr2_values)
607
+ attr1_values = attr1.get_attribute_values_full_name()
608
+ attr2_values = attr2.get_attribute_values_full_name()
609
+ print("attribute 1 full values names: ", attr1_values)
610
+ print("attribute 2 full values names: ", attr2_values)
611
+ group_obj = PairingGroup('SS512')
612
+ cp_hiding_ABE = CP_Hiding_Accountability_ABE(group_obj)
613
+ MSK, PK = cp_hiding_ABE.setup(attributes_dict) # TA's MSK, PK
614
+ print("MSK: ", MSK)
615
+ print("PK: ", PK)
616
+
617
+ user1_ID = group_obj.init(ZR, user1_ID)
618
+ user2_ID = group_obj.init(ZR, user2_ID)
619
+
620
+ user1_SK = cp_hiding_ABE.key_gen(MSK, PK, user1_ID, user1_attributes)
621
+ print('user1 SK: ', user1_SK)
622
+ user2_SK = cp_hiding_ABE.key_gen(MSK, PK, user2_ID, user2_attributes)
623
+ print('user2 SK: ', user1_SK)
624
+ rand_msg = group_obj.random(GT)
625
+ CT = cp_hiding_ABE.encrypt(rand_msg, PK, access_policy)
626
+ print("CT: ", CT)
627
+ recovered_message = cp_hiding_ABE.decrypt(CT, PK, user1_SK)
628
+ print("recovered message: ", recovered_message)
629
+ # No error is generated since user 1's attributes matches the access policy embedded inside the CT.
630
+ assert recovered_message == rand_msg, "Random message does not match the recovered message"
631
+
632
+ # User 2 tries to decrypt CT.
633
+ recovered_message = cp_hiding_ABE.decrypt(CT, PK, user2_SK)
634
+ print("recovered message: ", recovered_message)
635
+ # An error is generated since user 2 does not have the required attributes to decrypt CT.
636
+ # assert recovered_message == rand_msg, "Random message does not match the recovered message" # Uncomment to raise the error.
637
+
638
+ authentic_user_IDs_list = [123]
639
+ # User 2's ID is not in the authentic list, which means that his ID is fabricated and this malicious action is
640
+ # traced to the TA.
641
+ misbehaving_result = cp_hiding_ABE.trace(user2_SK, authentic_user_IDs_list, PK)
642
+ print("Misbehaving result for user2 SK: ", misbehaving_result)
643
+ print("***********************************************************************************************************")
644
+
645
+
646
+ if __name__ == "__main__":
647
+ main()