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,108 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Cramer-Shoup Public Key Encryption Scheme (CS98)**
|
|
3
|
+
|
|
4
|
+
*Authors:* R. Cramer, V. Shoup
|
|
5
|
+
|
|
6
|
+
| **Title:** "A Practical Public Key Cryptosystem Provably Secure Against Adaptive Chosen Ciphertext Attack"
|
|
7
|
+
| **Published in:** CRYPTO 1998
|
|
8
|
+
| **Available from:** http://knot.kaist.ac.kr/seminar/archive/46/46.pdf
|
|
9
|
+
| **Notes:**
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** encryption (public key)
|
|
14
|
+
* **Setting:** DDH-hard EC groups of prime order (F_p) or Integer Groups
|
|
15
|
+
* **Assumption:** DDH
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: Matthew Green
|
|
20
|
+
:Date: 1/2011
|
|
21
|
+
'''
|
|
22
|
+
from charm.toolbox.ecgroup import G
|
|
23
|
+
from charm.toolbox.PKEnc import PKEnc
|
|
24
|
+
|
|
25
|
+
# type definitions
|
|
26
|
+
#pk_t = { 'g1' : G, 'g2' : G, 'c' : G, 'd' : G, 'h' : G }
|
|
27
|
+
#sk_t = { 'x1' : ZR, 'x2' : ZR, 'y1' : ZR, 'y2' : ZR, 'z' : ZR }
|
|
28
|
+
#c_t = { 'u1' : G, 'u2' : G, 'e' : G, 'v' : G }
|
|
29
|
+
#str_t = str
|
|
30
|
+
|
|
31
|
+
debug = False
|
|
32
|
+
class CS98(PKEnc):
|
|
33
|
+
"""
|
|
34
|
+
>>> from charm.toolbox.eccurve import prime192v1
|
|
35
|
+
>>> from charm.toolbox.ecgroup import ECGroup
|
|
36
|
+
>>> groupObj = ECGroup(prime192v1)
|
|
37
|
+
>>> pkenc = CS98(groupObj)
|
|
38
|
+
>>> (public_key, secret_key) = pkenc.keygen()
|
|
39
|
+
>>> msg = b"hello world!!!123456"
|
|
40
|
+
>>> cipher_text = pkenc.encrypt(public_key, msg)
|
|
41
|
+
>>> decrypted_msg = pkenc.decrypt(public_key, secret_key, cipher_text)
|
|
42
|
+
>>> decrypted_msg == msg
|
|
43
|
+
True
|
|
44
|
+
>>> from charm.toolbox.integergroup import IntegerGroup, integer
|
|
45
|
+
>>> p = integer(156053402631691285300957066846581395905893621007563090607988086498527791650834395958624527746916581251903190331297268907675919283232442999706619659475326192111220545726433895802392432934926242553363253333261282122117343404703514696108330984423475697798156574052962658373571332699002716083130212467463571362679)
|
|
46
|
+
>>> q = integer(78026701315845642650478533423290697952946810503781545303994043249263895825417197979312263873458290625951595165648634453837959641616221499853309829737663096055610272863216947901196216467463121276681626666630641061058671702351757348054165492211737848899078287026481329186785666349501358041565106233731785681339)
|
|
47
|
+
>>> groupObj = IntegerGroup()
|
|
48
|
+
>>> pkenc = CS98(groupObj, p, q)
|
|
49
|
+
>>> (public_key, secret_key) = pkenc.keygen(1024)
|
|
50
|
+
>>> msg = b"hello world. test message"
|
|
51
|
+
>>> cipher_text = pkenc.encrypt(public_key, msg)
|
|
52
|
+
>>> decrypted_msg = pkenc.decrypt(public_key, secret_key, cipher_text)
|
|
53
|
+
>>> decrypted_msg == msg
|
|
54
|
+
True
|
|
55
|
+
"""
|
|
56
|
+
def __init__(self, groupObj, p=0, q=0):
|
|
57
|
+
PKEnc.__init__(self)
|
|
58
|
+
global group
|
|
59
|
+
group = groupObj
|
|
60
|
+
if group.groupSetting() == 'integer':
|
|
61
|
+
group.p, group.q, group.r = p, q, 2
|
|
62
|
+
|
|
63
|
+
# @output(pk_t, sk_t)
|
|
64
|
+
def keygen(self, secparam=0):
|
|
65
|
+
if group.groupSetting() == 'integer':
|
|
66
|
+
if group.p == 0 or group.q == 0:
|
|
67
|
+
group.paramgen(secparam)
|
|
68
|
+
p = group.p
|
|
69
|
+
g1, g2 = group.randomGen(), group.randomGen()
|
|
70
|
+
elif group.groupSetting() == 'elliptic_curve':
|
|
71
|
+
group.paramgen(secparam)
|
|
72
|
+
g1, g2 = group.random(G), group.random(G)
|
|
73
|
+
|
|
74
|
+
x1, x2, y1, y2, z = group.random(), group.random(), group.random(), group.random(), group.random()
|
|
75
|
+
c = ((g1 ** x1) * (g2 ** x2))
|
|
76
|
+
d = ((g1 ** y1) * (g2 ** y2))
|
|
77
|
+
h = (g1 ** z)
|
|
78
|
+
|
|
79
|
+
pk = { 'g1' : g1, 'g2' : g2, 'c' : c, 'd' : d, 'h' : h }
|
|
80
|
+
sk = { 'x1' : x1, 'x2' : x2, 'y1' : y1, 'y2' : y2, 'z' : z }
|
|
81
|
+
return (pk, sk)
|
|
82
|
+
|
|
83
|
+
# @input(pk_t, bytes)
|
|
84
|
+
# @output(c_t)
|
|
85
|
+
def encrypt(self, pk, M):
|
|
86
|
+
r = group.random()
|
|
87
|
+
u1 = (pk['g1'] ** r)
|
|
88
|
+
u2 = (pk['g2'] ** r)
|
|
89
|
+
e = group.encode(M) * (pk['h'] ** r)
|
|
90
|
+
alpha = group.hash((u1, u2, e))
|
|
91
|
+
v = (pk['c'] ** r) * (pk['d'] ** (r * alpha))
|
|
92
|
+
# Assemble the ciphertext
|
|
93
|
+
|
|
94
|
+
c = { 'u1' : u1, 'u2' : u2, 'e' : e, 'v' : v }
|
|
95
|
+
return c
|
|
96
|
+
|
|
97
|
+
# @input(pk_t, sk_t, c_t)
|
|
98
|
+
# @output(bytes)
|
|
99
|
+
def decrypt(self, pk, sk, c):
|
|
100
|
+
alpha = group.hash((c['u1'], c['u2'], c['e']))
|
|
101
|
+
v_prime = (c['u1'] ** (sk['x1'] + (sk['y1'] * alpha))) * (c['u2'] ** (sk['x2'] + (sk['y2'] * alpha)))
|
|
102
|
+
if (c['v'] != v_prime):
|
|
103
|
+
return 'ERROR'
|
|
104
|
+
|
|
105
|
+
if debug: print("c['v'] => %s" % c['v'])
|
|
106
|
+
if debug: print("v' => %s" % v_prime)
|
|
107
|
+
return group.decode(c['e'] / (c['u1'] ** sk['z']))
|
|
108
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**ElGamal Public Key Encryption Scheme (ElGamal85)**
|
|
3
|
+
|
|
4
|
+
*Authors:* T. ElGamal
|
|
5
|
+
|
|
6
|
+
| **Title:** "A Public Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms"
|
|
7
|
+
| **Published in:** CRYPTO 1984
|
|
8
|
+
| **Available from:** http://en.wikipedia.org/wiki/ElGamal_encryption
|
|
9
|
+
| **Notes:**
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** encryption (public key)
|
|
14
|
+
* **Setting:** DDH-hard prime order group
|
|
15
|
+
* **Assumption:** DDH
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: J. Ayo Akinyele
|
|
20
|
+
:Date: 3/2011
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
from charm.toolbox.PKEnc import PKEnc
|
|
24
|
+
from charm.toolbox.ecgroup import G
|
|
25
|
+
|
|
26
|
+
debug = False
|
|
27
|
+
class ElGamalCipher(dict):
|
|
28
|
+
def __init__(self, ct):
|
|
29
|
+
if type(ct) != dict: assert False, "Not a dictionary!"
|
|
30
|
+
if not set(ct).issubset(['c1', 'c2']): assert False, "'c1','c2' keys not present."
|
|
31
|
+
dict.__init__(self, ct)
|
|
32
|
+
|
|
33
|
+
def __add__(self, other):
|
|
34
|
+
if type(other) == int:
|
|
35
|
+
lhs_c1 = dict.__getitem__(self, 'c1')
|
|
36
|
+
lhs_c2 = dict.__getitem__(self, 'c2')
|
|
37
|
+
return ElGamalCipher({'c1':lhs_c1, 'c2':lhs_c2 + other})
|
|
38
|
+
else:
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
def __mul__(self, other):
|
|
42
|
+
if type(other) == int:
|
|
43
|
+
lhs_c1 = dict.__getitem__(self, 'c1')
|
|
44
|
+
lhs_c2 = dict.__getitem__(self, 'c2')
|
|
45
|
+
return ElGamalCipher({'c1':lhs_c1, 'c2':lhs_c2 * other})
|
|
46
|
+
else:
|
|
47
|
+
lhs_c1 = dict.__getitem__(self, 'c1')
|
|
48
|
+
rhs_c1 = dict.__getitem__(other, 'c1')
|
|
49
|
+
|
|
50
|
+
lhs_c2 = dict.__getitem__(self, 'c2')
|
|
51
|
+
rhs_c2 = dict.__getitem__(other, 'c2')
|
|
52
|
+
return ElGamalCipher({'c1':lhs_c1 * rhs_c1, 'c2':lhs_c2 * rhs_c2})
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
class ElGamal(PKEnc):
|
|
56
|
+
"""
|
|
57
|
+
>>> from charm.toolbox.eccurve import prime192v2
|
|
58
|
+
>>> from charm.toolbox.ecgroup import ECGroup
|
|
59
|
+
>>> groupObj = ECGroup(prime192v2)
|
|
60
|
+
>>> el = ElGamal(groupObj)
|
|
61
|
+
>>> (public_key, secret_key) = el.keygen()
|
|
62
|
+
>>> msg = b"hello world!12345678"
|
|
63
|
+
>>> cipher_text = el.encrypt(public_key, msg)
|
|
64
|
+
>>> decrypted_msg = el.decrypt(public_key, secret_key, cipher_text)
|
|
65
|
+
>>> decrypted_msg == msg
|
|
66
|
+
True
|
|
67
|
+
>>> from charm.toolbox.integergroup import IntegerGroupQ, integer
|
|
68
|
+
>>> p = integer(148829018183496626261556856344710600327516732500226144177322012998064772051982752493460332138204351040296264880017943408846937646702376203733370973197019636813306480144595809796154634625021213611577190781215296823124523899584781302512549499802030946698512327294159881907114777803654670044046376468983244647367)
|
|
69
|
+
>>> q = integer(74414509091748313130778428172355300163758366250113072088661006499032386025991376246730166069102175520148132440008971704423468823351188101866685486598509818406653240072297904898077317312510606805788595390607648411562261949792390651256274749901015473349256163647079940953557388901827335022023188234491622323683)
|
|
70
|
+
>>> groupObj = IntegerGroupQ()
|
|
71
|
+
>>> el = ElGamal(groupObj, p, q)
|
|
72
|
+
>>> (public_key, secret_key) = el.keygen()
|
|
73
|
+
>>> msg = b"hello world!"
|
|
74
|
+
>>> cipher_text = el.encrypt(public_key, msg)
|
|
75
|
+
>>> decrypted_msg = el.decrypt(public_key, secret_key, cipher_text)
|
|
76
|
+
>>> decrypted_msg == msg
|
|
77
|
+
True
|
|
78
|
+
"""
|
|
79
|
+
def __init__(self, groupObj, p=0, q=0):
|
|
80
|
+
PKEnc.__init__(self)
|
|
81
|
+
global group
|
|
82
|
+
group = groupObj
|
|
83
|
+
if group.groupSetting() == 'integer':
|
|
84
|
+
group.p, group.q, group.r = p, q, 2
|
|
85
|
+
|
|
86
|
+
def keygen(self, secparam=1024):
|
|
87
|
+
if group.groupSetting() == 'integer':
|
|
88
|
+
if group.p == 0 or group.q == 0:
|
|
89
|
+
group.paramgen(secparam)
|
|
90
|
+
g = group.randomGen()
|
|
91
|
+
elif group.groupSetting() == 'elliptic_curve':
|
|
92
|
+
g = group.random(G)
|
|
93
|
+
# x is private, g is public param
|
|
94
|
+
x = group.random(); h = g ** x
|
|
95
|
+
if debug:
|
|
96
|
+
print('Public parameters...')
|
|
97
|
+
print('h => %s' % h)
|
|
98
|
+
print('g => %s' % g)
|
|
99
|
+
print('Secret key...')
|
|
100
|
+
print('x => %s' % x)
|
|
101
|
+
pk = {'g':g, 'h':h }
|
|
102
|
+
sk = {'x':x}
|
|
103
|
+
return (pk, sk)
|
|
104
|
+
|
|
105
|
+
def encrypt(self, pk, M):
|
|
106
|
+
y = group.random()
|
|
107
|
+
c1 = pk['g'] ** y
|
|
108
|
+
s = pk['h'] ** y
|
|
109
|
+
# check M and make sure it's right size
|
|
110
|
+
c2 = group.encode(M) * s
|
|
111
|
+
return ElGamalCipher({'c1':c1, 'c2':c2})
|
|
112
|
+
|
|
113
|
+
def decrypt(self, pk, sk, c):
|
|
114
|
+
s = c['c1'] ** sk['x']
|
|
115
|
+
m = c['c2'] * (s ** -1)
|
|
116
|
+
if group.groupSetting() == 'integer':
|
|
117
|
+
M = group.decode(m % group.p)
|
|
118
|
+
elif group.groupSetting() == 'elliptic_curve':
|
|
119
|
+
M = group.decode(m)
|
|
120
|
+
if debug: print('m => %s' % m)
|
|
121
|
+
if debug: print('dec M => %s' % M)
|
|
122
|
+
return M
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Goldwasser-Micali Public Key Encryption Scheme (GM82)**
|
|
3
|
+
|
|
4
|
+
*Authors:* S. Goldwasser, S. Micali
|
|
5
|
+
|
|
6
|
+
| **Title:** "Probabilistic Encryption and How to Play Mental Poker Keeping Secret All Partial Information"
|
|
7
|
+
| **Published in:** 14th Symposium on Theory of Computing (STOC), 1982
|
|
8
|
+
| **Available from:** http://groups.csail.mit.edu/cis/pubs/shafi/1982-stoc.pdf
|
|
9
|
+
| **Notes:**
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** encryption (public key)
|
|
14
|
+
* **Setting:** Integer
|
|
15
|
+
* **Assumption:** Quadratic Residuosity
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: Guillermo Ramos
|
|
20
|
+
:Date: 01/2015
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
from charm.core.math.integer import legendre, gcd
|
|
24
|
+
from charm.toolbox.integergroup import RSAGroup, integer
|
|
25
|
+
from charm.toolbox.PKEnc import PKEnc
|
|
26
|
+
|
|
27
|
+
# Upper bound to the number of rounds the keygen is able to make
|
|
28
|
+
# to search for a quadratic non-residue
|
|
29
|
+
maxtimes = 30
|
|
30
|
+
|
|
31
|
+
# Is x a quadratic residue of N = p1*p2?
|
|
32
|
+
def isResidue(x, p1, p2):
|
|
33
|
+
return legendre(x, p1) == 1 or legendre(x, p2) == 1
|
|
34
|
+
|
|
35
|
+
# Goldwasser-Micali cryptosystem
|
|
36
|
+
class GM82(PKEnc):
|
|
37
|
+
"""
|
|
38
|
+
>>> gm82 = GM82()
|
|
39
|
+
>>> (pk, sk) = gm82.keygen(512)
|
|
40
|
+
>>> zero = gm82.encrypt(pk, 0)
|
|
41
|
+
>>> one = gm82.encrypt(pk, 1)
|
|
42
|
+
>>> gm82.decrypt(sk, zero)
|
|
43
|
+
0
|
|
44
|
+
>>> gm82.decrypt(sk, one)
|
|
45
|
+
1
|
|
46
|
+
>>> gm82.decrypt(sk, gm82.xor(pk, zero, zero))
|
|
47
|
+
0
|
|
48
|
+
>>> gm82.decrypt(sk, gm82.xor(pk, zero, one))
|
|
49
|
+
1
|
|
50
|
+
>>> gm82.decrypt(sk, gm82.xor(pk, one, zero))
|
|
51
|
+
1
|
|
52
|
+
>>> gm82.decrypt(sk, gm82.xor(pk, one, one))
|
|
53
|
+
0
|
|
54
|
+
"""
|
|
55
|
+
def __init__(self):
|
|
56
|
+
PKEnc.__init__(self)
|
|
57
|
+
self.group = RSAGroup()
|
|
58
|
+
|
|
59
|
+
def keygen(self, secparam):
|
|
60
|
+
self.group.paramgen(secparam)
|
|
61
|
+
|
|
62
|
+
# Find a random quadratic non-residue in the group
|
|
63
|
+
x = self.group.random()
|
|
64
|
+
times = 1
|
|
65
|
+
while times < maxtimes and isResidue(x, self.group.p, self.group.q):
|
|
66
|
+
x = self.group.random()
|
|
67
|
+
times += 1
|
|
68
|
+
|
|
69
|
+
# If we are not able to find a quadratic non-residue after 'maxtimes'
|
|
70
|
+
# trials, abort and output error
|
|
71
|
+
if times == maxtimes:
|
|
72
|
+
print("ERROR: non-residue not found after {} trials.".format(times))
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
pk = (self.group.n, x)
|
|
76
|
+
sk = (self.group.p, self.group.q)
|
|
77
|
+
return (pk, sk)
|
|
78
|
+
|
|
79
|
+
def encrypt(self, pk, m):
|
|
80
|
+
(n, x) = pk
|
|
81
|
+
|
|
82
|
+
y = self.group.random()
|
|
83
|
+
while gcd(n, y) != 1:
|
|
84
|
+
y = self.group.random()
|
|
85
|
+
|
|
86
|
+
if m == 0:
|
|
87
|
+
return y**2 % n
|
|
88
|
+
else:
|
|
89
|
+
return y**2 * x % n
|
|
90
|
+
|
|
91
|
+
def decrypt(self, sk, c):
|
|
92
|
+
(p, q) = sk
|
|
93
|
+
return 0 if isResidue(c, p, q) else 1
|
|
94
|
+
|
|
95
|
+
# Homomorphic XOR over ciphertexts
|
|
96
|
+
def xor(self, pk, c1, c2):
|
|
97
|
+
(n, _) = pk
|
|
98
|
+
return (c1 * c2) % n
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Paillier Public Key Encryption Scheme (Paillier99)**
|
|
3
|
+
|
|
4
|
+
*Authors:* P. Paillier
|
|
5
|
+
|
|
6
|
+
| **Title:** "Public-Key Cryptosystems Based on Composite Degree Residuosity Classes"
|
|
7
|
+
| **Published in:** EUROCRYPT 1999
|
|
8
|
+
| **Available from:** http://link.springer.com/chapter/10.1007%2F3-540-48910-X_16
|
|
9
|
+
| **Notes:** Additively homomorphic encryption scheme
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** encryption (public key)
|
|
14
|
+
* **Setting:** Integer
|
|
15
|
+
* **Assumption:** Composite Residuosity
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: J. Ayo Akinyele
|
|
20
|
+
:Date: 4/2011 (updated 2/2016)
|
|
21
|
+
'''
|
|
22
|
+
from charm.toolbox.integergroup import lcm,integer,toInt
|
|
23
|
+
from charm.toolbox.PKEnc import PKEnc
|
|
24
|
+
|
|
25
|
+
debug = False
|
|
26
|
+
"""A ciphertext class with homomorphic properties"""
|
|
27
|
+
class Ciphertext(dict):
|
|
28
|
+
"""
|
|
29
|
+
This tests the additively holomorphic properties of
|
|
30
|
+
the Paillier encryption scheme.
|
|
31
|
+
|
|
32
|
+
>>> from charm.toolbox.integergroup import RSAGroup
|
|
33
|
+
>>> group = RSAGroup()
|
|
34
|
+
>>> pai = Pai99(group)
|
|
35
|
+
>>> (public_key, secret_key) = pai.keygen()
|
|
36
|
+
|
|
37
|
+
>>> msg_1=12345678987654321
|
|
38
|
+
>>> msg_2=12345761234123409
|
|
39
|
+
>>> msg_3 = msg_1 + msg_2
|
|
40
|
+
|
|
41
|
+
>>> cipher_1 = pai.encrypt(public_key, msg_1)
|
|
42
|
+
>>> cipher_2 = pai.encrypt(public_key, msg_2)
|
|
43
|
+
>>> cipher_3 = cipher_1 + cipher_2
|
|
44
|
+
|
|
45
|
+
>>> decrypted_msg_3 = pai.decrypt(public_key, secret_key, cipher_3)
|
|
46
|
+
>>> decrypted_msg_3 == msg_3
|
|
47
|
+
True
|
|
48
|
+
"""
|
|
49
|
+
def __init__(self, ct, pk, key):
|
|
50
|
+
dict.__init__(self, ct)
|
|
51
|
+
self.pk, self.key = pk, key
|
|
52
|
+
|
|
53
|
+
def __add__(self, other):
|
|
54
|
+
if type(other) == int: # rhs must be Cipher
|
|
55
|
+
lhs = dict.__getitem__(self, self.key)
|
|
56
|
+
return Ciphertext({self.key:lhs * ((self.pk['g'] ** other) % self.pk['n2']) },
|
|
57
|
+
self.pk, self.key)
|
|
58
|
+
else: # neither are plain ints
|
|
59
|
+
lhs = dict.__getitem__(self, self.key)
|
|
60
|
+
rhs = dict.__getitem__(other, self.key)
|
|
61
|
+
return Ciphertext({self.key:(lhs * rhs) % self.pk['n2']},
|
|
62
|
+
self.pk, self.key)
|
|
63
|
+
|
|
64
|
+
def __mul__(self, other):
|
|
65
|
+
if type(other) == int:
|
|
66
|
+
lhs = dict.__getitem__(self, self.key)
|
|
67
|
+
return Ciphertext({self.key:(lhs ** other)}, self.pk, self.key)
|
|
68
|
+
|
|
69
|
+
def randomize(self, r): # need to provide random value
|
|
70
|
+
lhs = dict.__getitem__(self, self.key)
|
|
71
|
+
rhs = (integer(r) ** self.pk['n']) % self.pk['n2']
|
|
72
|
+
return Ciphertext({self.key:(lhs * rhs) % self.pk['n2']})
|
|
73
|
+
|
|
74
|
+
def __str__(self):
|
|
75
|
+
value = dict.__str__(self)
|
|
76
|
+
return value # + ", pk =" + str(pk)
|
|
77
|
+
|
|
78
|
+
class Pai99(PKEnc):
|
|
79
|
+
def __init__(self, groupObj):
|
|
80
|
+
PKEnc.__init__(self)
|
|
81
|
+
global group
|
|
82
|
+
group = groupObj
|
|
83
|
+
|
|
84
|
+
def L(self, u, n):
|
|
85
|
+
# computes L(u) => ((u - 1) / n)
|
|
86
|
+
U = integer(int(u) - 1)
|
|
87
|
+
if int(U) == 0:
|
|
88
|
+
return integer(0, n)
|
|
89
|
+
return U / n
|
|
90
|
+
|
|
91
|
+
def keygen(self, secparam=1024):
|
|
92
|
+
(p, q, n) = group.paramgen(secparam)
|
|
93
|
+
lam = lcm(p - 1, q - 1)
|
|
94
|
+
n2 = n ** 2
|
|
95
|
+
g = group.random(n2)
|
|
96
|
+
u = (self.L(((g % n2) ** lam), n) % n) ** -1
|
|
97
|
+
pk, sk = {'n':n, 'g':g, 'n2':n2}, {'lamda':lam, 'u':u}
|
|
98
|
+
return (pk, sk)
|
|
99
|
+
|
|
100
|
+
def encrypt(self, pk, m):
|
|
101
|
+
g, n, n2 = pk['g'], pk['n'], pk['n2']
|
|
102
|
+
r = group.random(pk['n'])
|
|
103
|
+
c = ((g % n2) ** m) * ((r % n2) ** n)
|
|
104
|
+
return Ciphertext({'c':c}, pk, 'c')
|
|
105
|
+
|
|
106
|
+
def decrypt(self, pk, sk, ct):
|
|
107
|
+
n, n2 = pk['n'], pk['n2']
|
|
108
|
+
m = ((self.L(ct['c'] ** sk['lamda'], n) % n) * sk['u']) % n
|
|
109
|
+
return toInt(m)
|
|
110
|
+
|
|
111
|
+
def encode(self, modulus, message):
|
|
112
|
+
# takes a string and represents as a bytes object
|
|
113
|
+
elem = integer(message)
|
|
114
|
+
return elem % modulus
|
|
115
|
+
|
|
116
|
+
def decode(self, pk, element):
|
|
117
|
+
pass
|
|
118
|
+
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Rabin Public Key Encryption Scheme (Rabin)**
|
|
3
|
+
|
|
4
|
+
*Authors:* M. O. Rabin
|
|
5
|
+
|
|
6
|
+
| **Title:** "Digitalized Signatures and Public-Key Functions as Intractable as Factorization"
|
|
7
|
+
| **Published in:** MIT Laboratory for Computer Science, 1979
|
|
8
|
+
| **Available from:**
|
|
9
|
+
| **Notes:**
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** encryption (public key)
|
|
14
|
+
* **Setting:** Integer
|
|
15
|
+
* **Assumption:** Integer Factorization
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: Christina Garman
|
|
20
|
+
:Date: 09/2011
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
from charm.core.math.integer import integer
|
|
24
|
+
from charm.toolbox.PKEnc import PKEnc
|
|
25
|
+
from charm.toolbox.PKSig import PKSig
|
|
26
|
+
from charm.toolbox.paddingschemes import OAEPEncryptionPadding,SAEPEncryptionPadding
|
|
27
|
+
from charm.toolbox.redundancyschemes import InMessageRedundancy
|
|
28
|
+
from charm.toolbox.conversion import Conversion
|
|
29
|
+
from charm.toolbox.bitstring import Bytes
|
|
30
|
+
from charm.toolbox.specialprimes import BlumWilliamsInteger
|
|
31
|
+
from math import ceil
|
|
32
|
+
|
|
33
|
+
debug = False
|
|
34
|
+
|
|
35
|
+
class Rabin():
|
|
36
|
+
def __init__(self, modulus=BlumWilliamsInteger()):
|
|
37
|
+
self.modulustype = modulus
|
|
38
|
+
|
|
39
|
+
# generate p,q and n
|
|
40
|
+
def paramgen(self, secparam):
|
|
41
|
+
(p, q, N) = self.modulustype.generateBlumWilliamsInteger(secparam)
|
|
42
|
+
|
|
43
|
+
yp = (p % q) ** -1
|
|
44
|
+
yq = (q % p) ** -1
|
|
45
|
+
|
|
46
|
+
return (p, yp, q, yq, N)
|
|
47
|
+
|
|
48
|
+
def keygen(self, s0, secparam=1024, params=None):
|
|
49
|
+
if params:
|
|
50
|
+
(N, p, q, yp, yq) = self.convert(params)
|
|
51
|
+
pk = { 'N':N, 'n':secparam, 's0':s0 }
|
|
52
|
+
sk = { 'p':p, 'q':q, 'N':N , 'yp':yp, 'yq':yq }
|
|
53
|
+
return (pk, sk)
|
|
54
|
+
|
|
55
|
+
(p, yp, q, yq, N) = self.paramgen(secparam)
|
|
56
|
+
|
|
57
|
+
pk = { 'N':N, 'n':secparam, 's0':s0 }
|
|
58
|
+
sk = { 'p':p, 'q':q, 'N':N , 'yp':yp, 'yq':yq }
|
|
59
|
+
|
|
60
|
+
return (pk, sk)
|
|
61
|
+
|
|
62
|
+
def convert(self, N, p, q, yp, yq):
|
|
63
|
+
return (integer(N), integer(p), integer(q), integer(yp), integer(yq))
|
|
64
|
+
|
|
65
|
+
class Rabin_Enc(Rabin,PKEnc):
|
|
66
|
+
"""
|
|
67
|
+
>>> rabin = Rabin_Enc()
|
|
68
|
+
>>> (public_key, secret_key) = rabin.keygen(128, 1024)
|
|
69
|
+
>>> msg = b'This is a test'
|
|
70
|
+
>>> cipher_text = rabin.encrypt(public_key, msg)
|
|
71
|
+
>>> decrypted_msg = rabin.decrypt(public_key, secret_key, cipher_text)
|
|
72
|
+
>>> decrypted_msg == msg
|
|
73
|
+
True
|
|
74
|
+
"""
|
|
75
|
+
def __init__(self, padding=SAEPEncryptionPadding(), redundancy=InMessageRedundancy(), params=None):
|
|
76
|
+
Rabin.__init__(self)
|
|
77
|
+
PKEnc.__init__(self)
|
|
78
|
+
self.paddingscheme = padding
|
|
79
|
+
self.redundancyscheme = redundancy
|
|
80
|
+
# m : Bytes
|
|
81
|
+
def encrypt(self, pk, m, salt=None):
|
|
82
|
+
if(self.paddingscheme.name == "SAEPEncryptionPadding"):
|
|
83
|
+
EM = self.paddingscheme.encode(m, pk['n'], pk['s0'])
|
|
84
|
+
else:
|
|
85
|
+
m = self.redundancyscheme.encode(m)
|
|
86
|
+
octetlen = int(ceil(int(pk['N']).bit_length() / 8.0))
|
|
87
|
+
EM = self.paddingscheme.encode(m, octetlen, "", salt)
|
|
88
|
+
|
|
89
|
+
if debug: print("EM == >", EM)
|
|
90
|
+
i = Conversion.OS2IP(EM)
|
|
91
|
+
ip = integer(i) % pk['N'] #Convert to modular integer
|
|
92
|
+
|
|
93
|
+
return (ip ** 2) % pk['N']
|
|
94
|
+
|
|
95
|
+
def decrypt(self, pk, sk, c):
|
|
96
|
+
p = sk['p']
|
|
97
|
+
q = sk['q']
|
|
98
|
+
yp = sk['yp']
|
|
99
|
+
yq = sk['yq']
|
|
100
|
+
|
|
101
|
+
mp = (c ** ((p+1)/4)) % p
|
|
102
|
+
mq = (c ** ((q+1)/4)) % q
|
|
103
|
+
|
|
104
|
+
if(not(((c % p) == (mp ** 2)) and ((c % q) == (mq ** 2)))):
|
|
105
|
+
assert False, "invalid ciphertext"
|
|
106
|
+
|
|
107
|
+
r1 = ((int(yp)*int(p)*int(mq)) + ((int(yq)*int(q)*int(mp)))) % int(sk['N'])
|
|
108
|
+
r2 = int(sk['N']) - int(r1)
|
|
109
|
+
|
|
110
|
+
s1 = (int(yp)*int(p)*int(mq) - int(yq)*int(q)*int(mp)) % int(sk['N'])
|
|
111
|
+
s2 = int(sk['N']) - int(s1)
|
|
112
|
+
|
|
113
|
+
m1 = r1 % int(sk['N'])
|
|
114
|
+
m2 = r2 % int(sk['N'])
|
|
115
|
+
m3 = s1 % int(sk['N'])
|
|
116
|
+
m4 = s2 % int(sk['N'])
|
|
117
|
+
|
|
118
|
+
if(self.paddingscheme.name == "SAEPEncryptionPadding"):
|
|
119
|
+
if(m1 < integer(int(sk['N'])//2)):
|
|
120
|
+
os1 = Conversion.IP2OS(int(m1))
|
|
121
|
+
if(m2 < integer(int(sk['N'])//2)):
|
|
122
|
+
os2 = Conversion.IP2OS(int(m2))
|
|
123
|
+
else:
|
|
124
|
+
if(m3 < integer(int(sk['N'])//2)):
|
|
125
|
+
os2 = Conversion.IP2OS(int(m3))
|
|
126
|
+
else:
|
|
127
|
+
os2 = Conversion.IP2OS(int(m4))
|
|
128
|
+
else:
|
|
129
|
+
if(m2 < integer(int(sk['N'])//2)):
|
|
130
|
+
os1 = Conversion.IP2OS(int(m2))
|
|
131
|
+
if(m3 < integer(int(sk['N'])//2)):
|
|
132
|
+
os2 = Conversion.IP2OS(int(m3))
|
|
133
|
+
else:
|
|
134
|
+
os2 = Conversion.IP2OS(int(m4))
|
|
135
|
+
else:
|
|
136
|
+
os1 = Conversion.IP2OS(int(m3))
|
|
137
|
+
os2 = Conversion.IP2OS(int(m4))
|
|
138
|
+
|
|
139
|
+
if debug:
|
|
140
|
+
print("OS1 =>", os1)
|
|
141
|
+
print("OS2 =>", os2)
|
|
142
|
+
|
|
143
|
+
(m1, t1) = self.paddingscheme.decode(os1, pk['n'], pk['s0'])
|
|
144
|
+
(m2, t2) = self.paddingscheme.decode(os2, pk['n'], pk['s0'])
|
|
145
|
+
|
|
146
|
+
if((t1 == Bytes.fill(b'\x00', pk['s0']/8)) and (t2 == Bytes.fill(b'\x00', pk['s0']/8))):
|
|
147
|
+
assert False, "invalid ciphertext"
|
|
148
|
+
|
|
149
|
+
if(t1 == Bytes.fill(b'\x00', pk['s0']/8)):
|
|
150
|
+
return m1
|
|
151
|
+
else:
|
|
152
|
+
if(t2 == Bytes.fill(b'\x00', pk['s0']/8)):
|
|
153
|
+
return m2
|
|
154
|
+
else:
|
|
155
|
+
assert False, "invalid ciphertext"
|
|
156
|
+
else:
|
|
157
|
+
octetlen = int(ceil(int(pk['N']).bit_length() / 8.0))
|
|
158
|
+
os1 = Conversion.IP2OS(int(m1), octetlen)
|
|
159
|
+
os2 = Conversion.IP2OS(int(m2), octetlen)
|
|
160
|
+
os3 = Conversion.IP2OS(int(m3), octetlen)
|
|
161
|
+
os4 = Conversion.IP2OS(int(m4), octetlen)
|
|
162
|
+
if debug:
|
|
163
|
+
print("OS1 =>", os1)
|
|
164
|
+
print("OS2 =>", os2)
|
|
165
|
+
print("OS3 =>", os3)
|
|
166
|
+
print("OS4 =>", os4)
|
|
167
|
+
|
|
168
|
+
for i in [os1, os2, os3, os4]:
|
|
169
|
+
(isMessage, message) = self.redundancyscheme.decode(self.paddingscheme.decode(i))
|
|
170
|
+
if(isMessage):
|
|
171
|
+
return message
|
|
172
|
+
|
|
173
|
+
class Rabin_Sig(Rabin, PKSig):
|
|
174
|
+
"""
|
|
175
|
+
RSASSA-PSS
|
|
176
|
+
|
|
177
|
+
>>> msg = b'This is a test message.'
|
|
178
|
+
>>> rabin = Rabin_Sig()
|
|
179
|
+
>>> (public_key, secret_key) = rabin.keygen(1024)
|
|
180
|
+
>>> signature = rabin.sign(secret_key, msg)
|
|
181
|
+
>>> rabin.verify(public_key, msg, signature)
|
|
182
|
+
True
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
def __init__(self, padding=OAEPEncryptionPadding()):
|
|
186
|
+
Rabin.__init__(self)
|
|
187
|
+
PKSig.__init__(self)
|
|
188
|
+
self.paddingscheme = padding
|
|
189
|
+
|
|
190
|
+
def sign(self,sk, M, salt=None):
|
|
191
|
+
#apply encoding
|
|
192
|
+
|
|
193
|
+
while True:
|
|
194
|
+
octetlen = int(ceil(int(sk['N']).bit_length() / 8.0))
|
|
195
|
+
em = self.paddingscheme.encode(M, octetlen, "", salt)
|
|
196
|
+
|
|
197
|
+
m = Conversion.OS2IP(em)
|
|
198
|
+
m = integer(m) % sk['N'] #ERRROR m is larger than N
|
|
199
|
+
|
|
200
|
+
p = sk['p']
|
|
201
|
+
q = sk['q']
|
|
202
|
+
yp = sk['yp']
|
|
203
|
+
yq = sk['yq']
|
|
204
|
+
|
|
205
|
+
mp = (m ** ((p+1)/4)) % p
|
|
206
|
+
mq = (m ** ((q+1)/4)) % q
|
|
207
|
+
|
|
208
|
+
r1 = ((int(yp)*int(p)*int(mq)) + ((int(yq)*int(q)*int(mp)))) % int(sk['N'])
|
|
209
|
+
r2 = int(sk['N']) - int(r1)
|
|
210
|
+
|
|
211
|
+
s1 = (int(yp)*int(p)*int(mq) - int(yq)*int(q)*int(mp)) % int(sk['N'])
|
|
212
|
+
s2 = int(sk['N']) - int(s1)
|
|
213
|
+
|
|
214
|
+
if(((int((integer(r1) ** 2) % sk['N'] - m)) == 0) or ((int((integer(r2) ** 2) % sk['N'] - m)) == 0) or ((int((integer(s1) ** 2) % sk['N'] - m)) == 0) or ((int((integer(s2) ** 2) % sk['N'] - m)) == 0)):
|
|
215
|
+
break
|
|
216
|
+
|
|
217
|
+
S = { 's1':r1, 's2':r2, 's3':s1, 's4':s2 }
|
|
218
|
+
|
|
219
|
+
if debug:
|
|
220
|
+
print("Signing")
|
|
221
|
+
print("m =>", m)
|
|
222
|
+
print("em =>", em)
|
|
223
|
+
print("S =>", S)
|
|
224
|
+
|
|
225
|
+
return S
|
|
226
|
+
|
|
227
|
+
def verify(self, pk, M, S, salt=None):
|
|
228
|
+
#M = b'This is a malicious message'
|
|
229
|
+
|
|
230
|
+
octetlen = int(ceil(int(pk['N']).bit_length() / 8.0))
|
|
231
|
+
|
|
232
|
+
sig_mess = (integer(S['s1']) ** 2) % pk['N']
|
|
233
|
+
sig_mess = Conversion.IP2OS(int(sig_mess), octetlen)
|
|
234
|
+
if debug: print("OS1 =>", sig_mess)
|
|
235
|
+
dec_mess = self.paddingscheme.decode(sig_mess)
|
|
236
|
+
|
|
237
|
+
if debug:
|
|
238
|
+
print("Verifying")
|
|
239
|
+
print("sig_mess =>", sig_mess)
|
|
240
|
+
print("dec_mess =>", dec_mess)
|
|
241
|
+
print("S =>", S)
|
|
242
|
+
|
|
243
|
+
return (dec_mess == M)
|
|
244
|
+
|
|
245
|
+
def main():
|
|
246
|
+
rabin = Rabin_Enc()
|
|
247
|
+
(public_key, secret_key) = rabin.keygen(128, 1024)
|
|
248
|
+
msg = b'This is a test'
|
|
249
|
+
cipher_text = rabin.encrypt(public_key, msg)
|
|
250
|
+
decrypted_msg = rabin.decrypt(public_key, secret_key, cipher_text)
|
|
251
|
+
print(decrypted_msg == msg)
|
|
252
|
+
|
|
253
|
+
if __name__ == "__main__":
|
|
254
|
+
main()
|