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,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()