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.
- charm/__init__.py +5 -0
- charm/adapters/__init__.py +0 -0
- charm/adapters/abenc_adapt_hybrid.py +90 -0
- charm/adapters/dabenc_adapt_hybrid.py +145 -0
- charm/adapters/ibenc_adapt_hybrid.py +72 -0
- charm/adapters/ibenc_adapt_identityhash.py +80 -0
- charm/adapters/kpabenc_adapt_hybrid.py +91 -0
- charm/adapters/pkenc_adapt_bchk05.py +121 -0
- charm/adapters/pkenc_adapt_chk04.py +91 -0
- charm/adapters/pkenc_adapt_hybrid.py +98 -0
- charm/adapters/pksig_adapt_naor01.py +89 -0
- charm/config.py +7 -0
- charm/core/__init__.py +0 -0
- charm/core/benchmark/benchmark_util.c +353 -0
- charm/core/benchmark/benchmark_util.h +61 -0
- charm/core/benchmark/benchmarkmodule.c +476 -0
- charm/core/benchmark/benchmarkmodule.h +162 -0
- charm/core/benchmark.cpython-313-darwin.so +0 -0
- charm/core/crypto/AES/AES.c +1464 -0
- charm/core/crypto/AES.cpython-313-darwin.so +0 -0
- charm/core/crypto/DES/DES.c +113 -0
- charm/core/crypto/DES.cpython-313-darwin.so +0 -0
- charm/core/crypto/DES3/DES3.c +26 -0
- charm/core/crypto/DES3.cpython-313-darwin.so +0 -0
- charm/core/crypto/__init__.py +0 -0
- charm/core/crypto/cryptobase/XOR.c +80 -0
- charm/core/crypto/cryptobase/_counter.c +496 -0
- charm/core/crypto/cryptobase/_counter.h +54 -0
- charm/core/crypto/cryptobase/block_template.c +900 -0
- charm/core/crypto/cryptobase/block_template.h +69 -0
- charm/core/crypto/cryptobase/cryptobasemodule.c +220 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt.h +90 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_argchk.h +44 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_cfg.h +186 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_cipher.h +941 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_custom.h +556 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_des.c +1912 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_hash.h +407 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_mac.h +496 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_macros.h +435 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_math.h +534 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_misc.h +103 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_pk.h +653 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_pkcs.h +90 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_prng.h +199 -0
- charm/core/crypto/cryptobase/stream_template.c +271 -0
- charm/core/crypto/cryptobase/strxor.c +229 -0
- charm/core/crypto/cryptobase.cpython-313-darwin.so +0 -0
- charm/core/engine/__init__.py +5 -0
- charm/core/engine/protocol.py +293 -0
- charm/core/engine/util.py +174 -0
- charm/core/math/__init__.py +0 -0
- charm/core/math/elliptic_curve/ecmodule.c +1986 -0
- charm/core/math/elliptic_curve/ecmodule.h +230 -0
- charm/core/math/elliptic_curve.cpython-313-darwin.so +0 -0
- charm/core/math/elliptic_curve.pyi +63 -0
- charm/core/math/integer/integermodule.c +2539 -0
- charm/core/math/integer/integermodule.h +145 -0
- charm/core/math/integer.cpython-313-darwin.so +0 -0
- charm/core/math/integer.pyi +76 -0
- charm/core/math/pairing/miracl/miracl_config.h +37 -0
- charm/core/math/pairing/miracl/miracl_interface.h +118 -0
- charm/core/math/pairing/miracl/miracl_interface2.h +126 -0
- charm/core/math/pairing/miracl/pairingmodule2.c +2094 -0
- charm/core/math/pairing/miracl/pairingmodule2.h +307 -0
- charm/core/math/pairing/pairingmodule.c +2230 -0
- charm/core/math/pairing/pairingmodule.h +241 -0
- charm/core/math/pairing/relic/pairingmodule3.c +1853 -0
- charm/core/math/pairing/relic/pairingmodule3.h +233 -0
- charm/core/math/pairing/relic/relic_interface.c +1337 -0
- charm/core/math/pairing/relic/relic_interface.h +217 -0
- charm/core/math/pairing/relic/test_relic.c +171 -0
- charm/core/math/pairing.cpython-313-darwin.so +0 -0
- charm/core/math/pairing.pyi +69 -0
- charm/core/utilities/base64.c +248 -0
- charm/core/utilities/base64.h +15 -0
- charm/schemes/__init__.py +0 -0
- charm/schemes/abenc/__init__.py +0 -0
- charm/schemes/abenc/abenc_accountability_jyjxgd20.py +647 -0
- charm/schemes/abenc/abenc_bsw07.py +146 -0
- charm/schemes/abenc/abenc_ca_cpabe_ar17.py +684 -0
- charm/schemes/abenc/abenc_dacmacs_yj14.py +298 -0
- charm/schemes/abenc/abenc_lsw08.py +159 -0
- charm/schemes/abenc/abenc_maabe_rw15.py +236 -0
- charm/schemes/abenc/abenc_maabe_yj14.py +297 -0
- charm/schemes/abenc/abenc_tbpre_lww14.py +309 -0
- charm/schemes/abenc/abenc_unmcpabe_yahk14.py +223 -0
- charm/schemes/abenc/abenc_waters09.py +144 -0
- charm/schemes/abenc/abenc_yct14.py +208 -0
- charm/schemes/abenc/abenc_yllc15.py +178 -0
- charm/schemes/abenc/ac17.py +248 -0
- charm/schemes/abenc/bsw07.py +141 -0
- charm/schemes/abenc/cgw15.py +277 -0
- charm/schemes/abenc/dabe_aw11.py +204 -0
- charm/schemes/abenc/dfa_fe12.py +144 -0
- charm/schemes/abenc/pk_hve08.py +179 -0
- charm/schemes/abenc/waters11.py +143 -0
- charm/schemes/aggrsign_MuSig.py +150 -0
- charm/schemes/aggrsign_bls.py +267 -0
- charm/schemes/blindsig_ps16.py +654 -0
- charm/schemes/chamhash_adm05.py +113 -0
- charm/schemes/chamhash_rsa_hw09.py +100 -0
- charm/schemes/commit/__init__.py +0 -0
- charm/schemes/commit/commit_gs08.py +77 -0
- charm/schemes/commit/commit_pedersen92.py +53 -0
- charm/schemes/encap_bchk05.py +62 -0
- charm/schemes/grpsig/__init__.py +0 -0
- charm/schemes/grpsig/groupsig_bgls04.py +114 -0
- charm/schemes/grpsig/groupsig_bgls04_var.py +115 -0
- charm/schemes/hibenc/__init__.py +0 -0
- charm/schemes/hibenc/hibenc_bb04.py +105 -0
- charm/schemes/hibenc/hibenc_lew11.py +193 -0
- charm/schemes/ibenc/__init__.py +0 -0
- charm/schemes/ibenc/clpkc_rp03.py +119 -0
- charm/schemes/ibenc/ibenc_CW13_z.py +168 -0
- charm/schemes/ibenc/ibenc_bb03.py +94 -0
- charm/schemes/ibenc/ibenc_bf01.py +121 -0
- charm/schemes/ibenc/ibenc_ckrs09.py +120 -0
- charm/schemes/ibenc/ibenc_cllww12_z.py +172 -0
- charm/schemes/ibenc/ibenc_lsw08.py +120 -0
- charm/schemes/ibenc/ibenc_sw05.py +238 -0
- charm/schemes/ibenc/ibenc_waters05.py +144 -0
- charm/schemes/ibenc/ibenc_waters05_z.py +164 -0
- charm/schemes/ibenc/ibenc_waters09.py +107 -0
- charm/schemes/ibenc/ibenc_waters09_z.py +147 -0
- charm/schemes/joye_scheme.py +106 -0
- charm/schemes/lem_scheme.py +207 -0
- charm/schemes/pk_fre_ccv11.py +107 -0
- charm/schemes/pk_vrf.py +127 -0
- charm/schemes/pkenc/__init__.py +0 -0
- charm/schemes/pkenc/pkenc_cs98.py +108 -0
- charm/schemes/pkenc/pkenc_elgamal85.py +122 -0
- charm/schemes/pkenc/pkenc_gm82.py +98 -0
- charm/schemes/pkenc/pkenc_paillier99.py +118 -0
- charm/schemes/pkenc/pkenc_rabin.py +254 -0
- charm/schemes/pkenc/pkenc_rsa.py +186 -0
- charm/schemes/pksig/__init__.py +0 -0
- charm/schemes/pksig/pksig_CW13_z.py +135 -0
- charm/schemes/pksig/pksig_bls04.py +87 -0
- charm/schemes/pksig/pksig_boyen.py +156 -0
- charm/schemes/pksig/pksig_chch.py +97 -0
- charm/schemes/pksig/pksig_chp.py +70 -0
- charm/schemes/pksig/pksig_cl03.py +150 -0
- charm/schemes/pksig/pksig_cl04.py +87 -0
- charm/schemes/pksig/pksig_cllww12_z.py +142 -0
- charm/schemes/pksig/pksig_cyh.py +132 -0
- charm/schemes/pksig/pksig_dsa.py +76 -0
- charm/schemes/pksig/pksig_ecdsa.py +71 -0
- charm/schemes/pksig/pksig_hess.py +104 -0
- charm/schemes/pksig/pksig_hw.py +110 -0
- charm/schemes/pksig/pksig_lamport.py +63 -0
- charm/schemes/pksig/pksig_ps01.py +135 -0
- charm/schemes/pksig/pksig_ps02.py +124 -0
- charm/schemes/pksig/pksig_ps03.py +119 -0
- charm/schemes/pksig/pksig_rsa_hw09.py +206 -0
- charm/schemes/pksig/pksig_schnorr91.py +77 -0
- charm/schemes/pksig/pksig_waters.py +115 -0
- charm/schemes/pksig/pksig_waters05.py +121 -0
- charm/schemes/pksig/pksig_waters09.py +121 -0
- charm/schemes/pre_mg07.py +150 -0
- charm/schemes/prenc/pre_afgh06.py +126 -0
- charm/schemes/prenc/pre_bbs98.py +123 -0
- charm/schemes/prenc/pre_nal16.py +216 -0
- charm/schemes/protocol_a01.py +272 -0
- charm/schemes/protocol_ao00.py +215 -0
- charm/schemes/protocol_cns07.py +274 -0
- charm/schemes/protocol_schnorr91.py +125 -0
- charm/schemes/sigma1.py +64 -0
- charm/schemes/sigma2.py +129 -0
- charm/schemes/sigma3.py +126 -0
- charm/schemes/threshold/__init__.py +59 -0
- charm/schemes/threshold/dkls23_dkg.py +556 -0
- charm/schemes/threshold/dkls23_presign.py +1089 -0
- charm/schemes/threshold/dkls23_sign.py +761 -0
- charm/schemes/threshold/xrpl_wallet.py +967 -0
- charm/test/__init__.py +0 -0
- charm/test/adapters/__init__.py +0 -0
- charm/test/adapters/abenc_adapt_hybrid_test.py +29 -0
- charm/test/adapters/dabenc_adapt_hybrid_test.py +56 -0
- charm/test/adapters/ibenc_adapt_hybrid_test.py +36 -0
- charm/test/adapters/ibenc_adapt_identityhash_test.py +32 -0
- charm/test/adapters/kpabenc_adapt_hybrid_test.py +30 -0
- charm/test/benchmark/abenc_yllc15_bench.py +92 -0
- charm/test/benchmark/benchmark_test.py +148 -0
- charm/test/benchmark_threshold.py +260 -0
- charm/test/conftest.py +38 -0
- charm/test/fuzz/__init__.py +1 -0
- charm/test/fuzz/conftest.py +5 -0
- charm/test/fuzz/fuzz_policy_parser.py +76 -0
- charm/test/fuzz/fuzz_serialization.py +83 -0
- charm/test/schemes/__init__.py +0 -0
- charm/test/schemes/abenc/__init__.py +0 -0
- charm/test/schemes/abenc/abenc_bsw07_test.py +39 -0
- charm/test/schemes/abenc/abenc_dacmacs_yj14_test.py +16 -0
- charm/test/schemes/abenc/abenc_lsw08_test.py +33 -0
- charm/test/schemes/abenc/abenc_maabe_yj14_test.py +16 -0
- charm/test/schemes/abenc/abenc_tbpre_lww14_test.py +16 -0
- charm/test/schemes/abenc/abenc_waters09_test.py +38 -0
- charm/test/schemes/abenc/abenc_yllc15_test.py +74 -0
- charm/test/schemes/chamhash_adm05_test.py +31 -0
- charm/test/schemes/chamhash_rsa_hw09_test.py +29 -0
- charm/test/schemes/commit/__init__.py +0 -0
- charm/test/schemes/commit/commit_gs08_test.py +24 -0
- charm/test/schemes/commit/commit_pedersen92_test.py +26 -0
- charm/test/schemes/dabe_aw11_test.py +45 -0
- charm/test/schemes/encap_bchk05_test.py +21 -0
- charm/test/schemes/grpsig/__init__.py +0 -0
- charm/test/schemes/grpsig/groupsig_bgls04_test.py +35 -0
- charm/test/schemes/grpsig/groupsig_bgls04_var_test.py +39 -0
- charm/test/schemes/hibenc/__init__.py +0 -0
- charm/test/schemes/hibenc/hibenc_bb04_test.py +28 -0
- charm/test/schemes/ibenc/__init__.py +0 -0
- charm/test/schemes/ibenc/ibenc_bb03_test.py +26 -0
- charm/test/schemes/ibenc/ibenc_bf01_test.py +24 -0
- charm/test/schemes/ibenc/ibenc_ckrs09_test.py +25 -0
- charm/test/schemes/ibenc/ibenc_lsw08_test.py +31 -0
- charm/test/schemes/ibenc/ibenc_sw05_test.py +32 -0
- charm/test/schemes/ibenc/ibenc_waters05_test.py +31 -0
- charm/test/schemes/ibenc/ibenc_waters09_test.py +27 -0
- charm/test/schemes/pk_vrf_test.py +29 -0
- charm/test/schemes/pkenc/__init__.py +0 -0
- charm/test/schemes/pkenc_test.py +255 -0
- charm/test/schemes/pksig/__init__.py +0 -0
- charm/test/schemes/pksig_test.py +376 -0
- charm/test/schemes/rsa_alg_test.py +340 -0
- charm/test/schemes/threshold_test.py +1792 -0
- charm/test/serialize/__init__.py +0 -0
- charm/test/serialize/serialize_test.py +40 -0
- charm/test/toolbox/__init__.py +0 -0
- charm/test/toolbox/conversion_test.py +30 -0
- charm/test/toolbox/ecgroup_test.py +53 -0
- charm/test/toolbox/integer_arithmetic_test.py +441 -0
- charm/test/toolbox/paddingschemes_test.py +238 -0
- charm/test/toolbox/policy_parser_stress_test.py +969 -0
- charm/test/toolbox/secretshare_test.py +28 -0
- charm/test/toolbox/symcrypto_test.py +108 -0
- charm/test/toolbox/test_policy_expression.py +16 -0
- charm/test/vectors/__init__.py +1 -0
- charm/test/vectors/test_bls_vectors.py +289 -0
- charm/test/vectors/test_pedersen_vectors.py +315 -0
- charm/test/vectors/test_schnorr_vectors.py +368 -0
- charm/test/zkp_compiler/__init__.py +9 -0
- charm/test/zkp_compiler/benchmark_zkp.py +258 -0
- charm/test/zkp_compiler/test_and_proof.py +240 -0
- charm/test/zkp_compiler/test_batch_verify.py +248 -0
- charm/test/zkp_compiler/test_dleq_proof.py +264 -0
- charm/test/zkp_compiler/test_or_proof.py +231 -0
- charm/test/zkp_compiler/test_proof_serialization.py +121 -0
- charm/test/zkp_compiler/test_range_proof.py +241 -0
- charm/test/zkp_compiler/test_representation_proof.py +325 -0
- charm/test/zkp_compiler/test_schnorr_proof.py +221 -0
- charm/test/zkp_compiler/test_thread_safety.py +169 -0
- charm/test/zkp_compiler/test_zkp_parser.py +139 -0
- charm/toolbox/ABEnc.py +26 -0
- charm/toolbox/ABEncMultiAuth.py +66 -0
- charm/toolbox/ABEnumeric.py +800 -0
- charm/toolbox/Commit.py +24 -0
- charm/toolbox/DFA.py +89 -0
- charm/toolbox/FSA.py +1254 -0
- charm/toolbox/Hash.py +39 -0
- charm/toolbox/IBEnc.py +62 -0
- charm/toolbox/IBSig.py +64 -0
- charm/toolbox/PKEnc.py +66 -0
- charm/toolbox/PKSig.py +56 -0
- charm/toolbox/PREnc.py +32 -0
- charm/toolbox/ZKProof.py +289 -0
- charm/toolbox/__init__.py +0 -0
- charm/toolbox/bitstring.py +49 -0
- charm/toolbox/broadcast.py +220 -0
- charm/toolbox/conversion.py +100 -0
- charm/toolbox/eccurve.py +149 -0
- charm/toolbox/ecgroup.py +143 -0
- charm/toolbox/enum.py +60 -0
- charm/toolbox/hash_module.py +91 -0
- charm/toolbox/integergroup.py +323 -0
- charm/toolbox/iterate.py +22 -0
- charm/toolbox/matrixops.py +76 -0
- charm/toolbox/mpc_utils.py +296 -0
- charm/toolbox/msp.py +175 -0
- charm/toolbox/mta.py +985 -0
- charm/toolbox/node.py +120 -0
- charm/toolbox/ot/__init__.py +22 -0
- charm/toolbox/ot/base_ot.py +374 -0
- charm/toolbox/ot/dpf.py +642 -0
- charm/toolbox/ot/mpfss.py +228 -0
- charm/toolbox/ot/ot_extension.py +589 -0
- charm/toolbox/ot/silent_ot.py +378 -0
- charm/toolbox/paddingschemes.py +423 -0
- charm/toolbox/paddingschemes_test.py +238 -0
- charm/toolbox/pairingcurves.py +85 -0
- charm/toolbox/pairinggroup.py +186 -0
- charm/toolbox/policy_expression_spec.py +70 -0
- charm/toolbox/policytree.py +189 -0
- charm/toolbox/reCompiler.py +346 -0
- charm/toolbox/redundancyschemes.py +65 -0
- charm/toolbox/schemebase.py +188 -0
- charm/toolbox/secretshare.py +104 -0
- charm/toolbox/secretutil.py +174 -0
- charm/toolbox/securerandom.py +73 -0
- charm/toolbox/sigmaprotocol.py +46 -0
- charm/toolbox/specialprimes.py +45 -0
- charm/toolbox/symcrypto.py +279 -0
- charm/toolbox/threshold_sharing.py +553 -0
- charm/toolbox/xmlserialize.py +94 -0
- charm/toolbox/zknode.py +105 -0
- charm/zkp_compiler/__init__.py +89 -0
- charm/zkp_compiler/and_proof.py +460 -0
- charm/zkp_compiler/batch_verify.py +324 -0
- charm/zkp_compiler/dleq_proof.py +423 -0
- charm/zkp_compiler/or_proof.py +305 -0
- charm/zkp_compiler/range_proof.py +417 -0
- charm/zkp_compiler/representation_proof.py +466 -0
- charm/zkp_compiler/schnorr_proof.py +273 -0
- charm/zkp_compiler/thread_safe.py +150 -0
- charm/zkp_compiler/zk_demo.py +489 -0
- charm/zkp_compiler/zkp_factory.py +330 -0
- charm/zkp_compiler/zkp_generator.py +370 -0
- charm/zkp_compiler/zkparser.py +269 -0
- charm_crypto_framework-0.61.1.dist-info/METADATA +337 -0
- charm_crypto_framework-0.61.1.dist-info/RECORD +323 -0
- charm_crypto_framework-0.61.1.dist-info/WHEEL +5 -0
- charm_crypto_framework-0.61.1.dist-info/licenses/LICENSE.txt +165 -0
- 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()
|