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,423 @@
1
+ '''A collection of encryption and signature padding schemes'''
2
+ from charm.toolbox.bitstring import Bytes,py3
3
+ from charm.toolbox.securerandom import SecureRandomFactory
4
+ import charm.core.crypto.cryptobase
5
+ import hashlib
6
+ import math
7
+ import struct
8
+ import sys
9
+
10
+ debug = False
11
+
12
+
13
+ class OAEPEncryptionPadding:
14
+ '''
15
+ :Authors: Gary Belvin
16
+
17
+ OAEPEncryptionPadding
18
+
19
+ Implements the OAEP padding scheme. Appropriate for RSA-OAEP encryption.
20
+ Implemented according to PKCS#1 v2.1 Section 7 ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
21
+ '''
22
+ def __init__(self, _hash_type ='sha1'):
23
+ self.name = "OAEPEncryptionPadding"
24
+ self.hashFn = hashFunc(_hash_type)
25
+ self.hashFnOutputBytes = len(hashlib.new(_hash_type).digest())
26
+
27
+ # outputBytes - the length in octets of the RSA modulus used
28
+ # - the intended length of the encoded message
29
+ # emLen = the length of the rsa modulus in bits
30
+ def encode(self, message, emLen, label="", seed=None):
31
+ ''':Return: a Bytes object'''
32
+ # Skipped: label input length checking. (L must be less than 2^61 octets for SHA1)
33
+ # First, make sure the message isn't too long. emLen
34
+ hLen = self.hashFnOutputBytes
35
+ if (len(message) > (emLen - (2 * hLen) - 2)):
36
+ assert False, "message too long"
37
+
38
+ if py3: lHash = self.hashFn(Bytes(label, 'utf8'))
39
+ else: lHash = self.hashFn(Bytes(label))
40
+
41
+ # Let PS be a string of length (emLen - mLen - 2hLen - 2) containing only zero octets.
42
+ # Compute DB = lHash || PS || 0x01 || M.
43
+ PS = Bytes.fill(b'\x00', emLen - len(message) - (2 * hLen) - 2)
44
+ DB = lHash + PS + b'\x01' + bytes(message)
45
+
46
+ # Generate a random octet string seed of length hLen and compute
47
+ # maskedDB = MGF1(seed, emLen - self.hashFnOutputBytes - 1)
48
+ if (seed is None):
49
+ rand = SecureRandomFactory.getInstance()
50
+ seed = rand.getRandomBytes(hLen)
51
+
52
+ dbMask = MGF1(seed, len(DB), self.hashFn, hLen)
53
+
54
+ maskedDB = DB ^ dbMask
55
+
56
+ # Let seedMask = MGF(maskedDB, self.hashFnOutputBytes) and
57
+ # maskedSeed = seedMask XOR seed
58
+ seedMask = MGF1(maskedDB, len(seed), self.hashFn, hLen)
59
+ maskedSeed = seedMask ^ seed
60
+ if(debug):
61
+ print("Encoding")
62
+ print("label =>", label)
63
+ print("lhash =>", lHash)
64
+ print("seed =>", seed)
65
+ print("db =>", DB)
66
+ print("db len =>", len(DB))
67
+ print("db mask =>", dbMask)
68
+ print("maskedDB =>", maskedDB)
69
+ print("seedMask =>", seedMask)
70
+ print("maskedSed=>", maskedSeed)
71
+
72
+ return Bytes(b'\x00') + maskedSeed + maskedDB
73
+
74
+ def decode(self, encMessage, label=""):
75
+ hLen = self.hashFnOutputBytes
76
+ # Make sure the encoded string is at least L bytes long
77
+ if len(encMessage) < (2 * hLen + 2):
78
+ assert False, "encoded string not long enough."
79
+ if py3: lHash = self.hashFn(Bytes(label, 'utf-8'))
80
+ else: lHash = self.hashFn(Bytes(label))
81
+ # Parse the encoded string as (0x00 || maskedSeed || maskedDB)
82
+ #Y = encMessage[0]
83
+ maskedSeed = Bytes(encMessage[1:(1+hLen)])
84
+ maskedDB = Bytes(encMessage[(1+hLen):])
85
+
86
+ # Set seedMask = MGF1(maskedDB, hashFnOutputSize)
87
+ seedMask = MGF1(maskedDB, len(maskedSeed), self.hashFn, hLen)
88
+ seed = maskedSeed ^ seedMask
89
+
90
+ # Set dbMask = MGF(seed, k - hLen - 1) and
91
+ # DB = maskedDB \xor dbMask.
92
+ dbMask = MGF1(seed, len(maskedDB), self.hashFn, hLen)
93
+ DB = dbMask ^ maskedDB
94
+ if(debug):
95
+ print("decoding:")
96
+ print("MaskedSeed => ", maskedSeed)
97
+ print("maskedDB => ", maskedDB)
98
+ print("r seed =>", seed)
99
+ print("r DB =>", DB)
100
+
101
+ # Parse DB as:
102
+ # DB = lHash' || PS || 0x01 || M.
103
+ # Check that lHash' == lHash, Y == 0x00 and there is an 0x01 after PS
104
+ lHashPrime = DB[0 : hLen]
105
+ M = DB[DB.find(b'\x01')+1 : ]
106
+ return M
107
+
108
+ #def MGF1(seed:Bytes, maskBytes:int, hashFn, hLen:int):
109
+ def MGF1(seed, maskBytes, hashFn, hLen):
110
+ ''' MGF1 Mask Generation Function
111
+
112
+ Implemented according to PKCS #1 specification, see appendix B.2.1:
113
+
114
+ :Parameters:
115
+ - ``hLen``: is the output length of the hash function
116
+ - ``maskBytes``: the number of mask bytes to return
117
+ '''
118
+ debug = False
119
+ # Skipped output size checking. Must be less than 2^32 * hLen
120
+ ran = range(int(math.ceil(maskBytes / float(hLen))))
121
+ if debug:
122
+ print("calc =>", math.ceil(maskBytes / float(hLen)))
123
+ print("Range =>", ran)
124
+ test = [hashFn(struct.pack(">%dsI" % (len(seed)), seed, i)) for i in ran]
125
+ if debug:
126
+ print("test =>", test)
127
+ result = b''.join(test)
128
+ return Bytes(result[0:maskBytes])
129
+
130
+ class hashFunc:
131
+ def __init__(self, _hash_type=None):
132
+ if _hash_type == None:
133
+ self.hashObj = hashlib.new('sha1') # nosec B324 - SHA1 default for historical compatibility
134
+ else:
135
+ self.hashObj = hashlib.new(_hash_type)
136
+
137
+ #message must be a binary string
138
+ def __call__(self, message):
139
+ h = self.hashObj.copy()
140
+ if type(message) == str:
141
+ h.update(bytes(message))
142
+ elif type(message) in [bytes, Bytes]:
143
+ h.update(bytes(message)) # bytes or custom Bytes
144
+ return Bytes(h.digest())
145
+
146
+ class PSSPadding:
147
+ '''
148
+ :Authors: Gary Belvin
149
+
150
+ PSSSignaturePadding
151
+
152
+ Implements the PSS signature padding scheme. Appropriate for RSA-PSS signing.
153
+ Implemented according to section 8 of ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf.
154
+ '''
155
+ def __init__(self, _hash_type ='sha1'):
156
+ self.hashFn = hashFunc(_hash_type)
157
+ self.hLen = len(hashlib.new(_hash_type).digest())
158
+ self.sLen = self.hLen # The length of the default salt
159
+
160
+ def encode(self, M, emBits=None, salt=None):
161
+ '''Encodes a message with PSS padding
162
+ emLen will be set to the minimum allowed length if not explicitly set
163
+ '''
164
+ # assert len(M) < (2^61 -1), Message too long
165
+
166
+ #Let H' = Hash (M'), an octet string of length hLen.
167
+ #Max length of output message
168
+ if emBits is None:
169
+ emBits = 8*self.hLen + 8 * self.sLen + 9
170
+ #Round to the next byte
171
+ emBits = int(math.ceil(emBits / 8.0)) * 8
172
+ assert emBits >= 8*self.hLen + 8 * self.sLen + 9, "Not enough emBits"
173
+
174
+ #Make sure the the message is long enough to be valid
175
+ emLen = int(math.ceil(emBits / 8.0))
176
+ assert emLen >= self.hLen + self.sLen + 2, "emLen too small"
177
+
178
+ if salt is None:
179
+ if self.sLen > 0:
180
+ salt = SecureRandomFactory.getInstance().getRandomBytes(self.sLen)
181
+ else:
182
+ salt = b''
183
+ assert len(salt) == self.sLen, "Salt wrong size"
184
+
185
+ #Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
186
+ eightzerobytes = Bytes.fill(b'\x00', 8)
187
+ mHash = self.hashFn(M)
188
+ Mprime = eightzerobytes + mHash + salt
189
+
190
+ #Let H = Hash (M'), an octet string of length hLen.
191
+ H = self.hashFn(Mprime)
192
+
193
+ #Generate an octet string PS consisting of emLen - sLen - hLen - 2 zero octets.
194
+ #The length of PS may be 0.
195
+ pslen = emLen - self.sLen - self.hLen - 2
196
+ ps = Bytes.fill(b'\x00', pslen)
197
+
198
+ #Let DB = PS || 0x01 || salt; DB is an octet string of length emLen - hLen - 1.
199
+ DB = ps + Bytes(b'\x01') + salt
200
+
201
+ #Let dbMask = MGF (H, emLen - hLen - 1).
202
+ masklen = emLen - self.hLen - 1
203
+ dbMask = MGF1(H, masklen, self.hashFn, self.hLen)
204
+ #Let maskedDB = DB ^ dbMask.
205
+ maskedDB = DB ^ dbMask
206
+
207
+ #Set the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB to zero
208
+ numzeros = 8 * emLen - emBits
209
+ bitmask = int('0'*numzeros + '1'*(8-numzeros), 2)
210
+ ba = bytearray(maskedDB)
211
+ ba[0] &= bitmask
212
+ maskedDB = Bytes(ba)
213
+
214
+ EM = maskedDB + H + Bytes(b'\xbc')
215
+
216
+ if debug:
217
+ print("PSS Encoding:")
218
+ print("M =>", M)
219
+ print("mHash =>", mHash)
220
+ print("salt =>", salt)
221
+ print("M' =>", Mprime)
222
+ print("H =>", H)
223
+ print("DB =>", DB)
224
+ print("dbmask=>", dbMask)
225
+ print("masked=>", maskedDB)
226
+ print("EM =>", EM)
227
+ return EM
228
+
229
+ def verify(self, M, EM, emBits=None):
230
+ '''
231
+ Verifies that EM is a correct encoding for M
232
+
233
+ :Parameters:
234
+ - M - the message to verify
235
+ - EM - the encoded message
236
+ :Return: true for 'consistent' or false for 'inconsistent'
237
+ '''
238
+ if debug: print("PSS Decoding:")
239
+
240
+ #Preconditions
241
+ if emBits == None:
242
+ emBits = 8 * len(EM)
243
+ assert emBits >= 8* self.hLen + 8* self.sLen + 9, "Not enough emBits"
244
+
245
+ emLen = int(math.ceil(emBits / 8.0))
246
+ assert len(EM) == emLen, "EM length not equivalent to bits provided"
247
+
248
+ # assert len(M) < (2^61 -1), Message too long
249
+
250
+ #Let mHash = Hash (M), an octet string of length hLen
251
+ mHash = self.hashFn(M)
252
+
253
+ #if emLen < hLen + sLen + 2, output 'inconsistent' and stop.
254
+ if emLen < self.hLen + self.sLen + 2:
255
+ if debug: print("emLen too short")
256
+ return False
257
+
258
+ #If the rightmost octet of EM does not have hexadecimal value 0xbc, output
259
+ #'inconsistent' and stop.
260
+ if EM[len(EM)-1:] != b'\xbc':
261
+ if debug: print("0xbc not found")
262
+ return False
263
+
264
+ #Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and let H be the
265
+ #next hLen octets.
266
+ maskeDBlen = emLen - self.hLen - 1
267
+ maskedDB = Bytes(EM[:maskeDBlen])
268
+ H = EM[maskeDBlen:maskeDBlen+self.hLen]
269
+
270
+ #If the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB are not all
271
+ #equal to zero, output 'inconsistent' and stop.
272
+ numzeros = 8 * emLen - emBits
273
+ bitmask = int('1'*numzeros + '0'*(8-numzeros), 2)
274
+ _mask_check = maskedDB[0]
275
+ if not py3: _mask_check = ord(_mask_check)
276
+ if (_mask_check & bitmask != 0):
277
+ if debug: print("right % bits of masked db not zero, found %" % (numzeros, bin(maskedDB[0])))
278
+ return False
279
+
280
+ #Let dbMask = MGF (H, emLen - hLen - 1).
281
+ masklen = emLen - self.hLen - 1
282
+ dbMask = MGF1(H, masklen, self.hashFn, self.hLen)
283
+ #Let DB = maskedDB ^ dbMask.
284
+ DB = maskedDB ^ dbMask
285
+
286
+ #Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero.
287
+ numzeros = 8 * emLen - emBits
288
+ bitmask = int('0'*numzeros + '1'*(8-numzeros), 2)
289
+ ba = bytearray(DB)
290
+ ba[0] &= bitmask
291
+ DB = Bytes(ba)
292
+
293
+ #If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
294
+ zerolen = emLen - self.hLen - self.sLen - 2
295
+ if DB[:zerolen] != Bytes.fill(b'\x00', zerolen):
296
+ if debug: print("DB did not start with % zero octets" % zerolen)
297
+ return False
298
+
299
+ #or if the octet at position emLen - hLen - sLen - 1 (the leftmost position is 'position 1') does not
300
+ #have hexadecimal value 0x01, output 'inconsistent' and stop.
301
+ _db_check = DB[zerolen]
302
+ if not py3: _db_check = ord(_db_check)
303
+ if _db_check != 0x01:
304
+ if debug: print("DB did not have 0x01 at %s, found %s instead" % (zerolen,DB[zerolen]))
305
+ return False
306
+
307
+ #Let salt be the last sLen octets of DB.
308
+ salt = DB[len(DB)-self.sLen:]
309
+ #Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
310
+ mPrime = Bytes.fill(b'\x00', 8) + mHash + salt
311
+
312
+ #Let H' = Hash (M'), an octet string of length hLen.
313
+ HPrime = self.hashFn(mPrime)
314
+
315
+ if debug:
316
+ print("M =>", M)
317
+ print("mHash =>", mHash)
318
+ print("salt =>", salt)
319
+ print("M' =>", mPrime)
320
+ print("H =>", H)
321
+ print("DB =>", DB)
322
+ print("dbmask=>", dbMask)
323
+ print("masked=>", maskedDB)
324
+ print("EM =>", EM)
325
+
326
+ #If H = H', output 'consistent'. Otherwise, output 'inconsistent'.
327
+ return H == HPrime
328
+
329
+ class SAEPEncryptionPadding:
330
+ '''
331
+ :Authors: Christina Garman
332
+
333
+ SAEPEncryptionPadding
334
+ '''
335
+ def __init__(self, _hash_type ='sha384'):
336
+ self.name = "SAEPEncryptionPadding"
337
+ self.hashFn = hashFunc(_hash_type)
338
+ self.hashFnOutputBytes = len(hashlib.new(_hash_type).digest())
339
+
340
+ def encode(self, message, n, s0):
341
+ #n = m + s0 + s1
342
+ m = int(n/4) #usually 256 bits
343
+
344
+ if(len(message) > (m/8)):
345
+ assert False, "message too long"
346
+
347
+ if(len(message) != m):
348
+ message_ext = bytes(message) + Bytes.fill(b'\x80', 1)
349
+ if(len(message_ext) != m):
350
+ message_ext = bytes(message_ext) + Bytes.fill(b'\x00', ((m/8)-2)-len(message))
351
+ message_ext = bytes(message_ext) + Bytes.fill(b'\x80', 1)
352
+
353
+ s1 = n - m - s0
354
+ t = Bytes.fill(b'\x00', s0/8)
355
+
356
+ rand = SecureRandomFactory.getInstance()
357
+ r = rand.getRandomBytes(int(s1/8))
358
+
359
+ v = Bytes(bytes(message_ext) + t)
360
+
361
+ x = v ^ self.hashFn(r)
362
+
363
+ y = x + r
364
+
365
+ if(debug):
366
+ print("Encoding")
367
+ print("m =>", m)
368
+ print("s0 =>", s0)
369
+ print("s1 =>", s1)
370
+ print("t =>", t, len(t))
371
+ print("r =>", r, len(r))
372
+ print("v =>", v, len(v))
373
+ print("x =>", x)
374
+ print("y =>", y, len(y))
375
+
376
+ return y
377
+
378
+ def decode(self, encMessage, n, s0):
379
+ m = int(n/4)
380
+
381
+ x = encMessage[:int((m+s0)/8)]
382
+ r = encMessage[int((m+s0)/8):int(n-m-s0)]
383
+
384
+ v = Bytes(x) ^ self.hashFn(r)
385
+
386
+ M = v[:int(m/8)]
387
+ t = v[int(m/8):int(m+s0/8)]
388
+
389
+ if(M[-1] == 128 and (M[-2] == 0 or M[-2] == 128)):
390
+ index = M[:(len(M)-1)].rindex(b'\x80')
391
+ M = M[:index]
392
+ else:
393
+ M = M[:len(M)-1]
394
+
395
+ if(debug):
396
+ print("decoding:")
397
+ print("x => ", x)
398
+ print("r => ", r)
399
+ print("v => ", v)
400
+ print("M => ", M)
401
+ print("t => ", t)
402
+ print("r =>" , r)
403
+
404
+ return (M, t)
405
+
406
+ class PKCS7Padding(object):
407
+ def __init__(self,block_size = 16):
408
+ self.block_size = block_size
409
+
410
+ def encode(self,_bytes,block_size = 16):
411
+ pad = self._padlength(_bytes)
412
+ return _bytes.ljust(pad+len(_bytes),bytes([pad]))
413
+
414
+ def decode(self,_bytes):
415
+ return _bytes[:-(_bytes[-1])]
416
+
417
+
418
+ def _padlength(self,_bytes):
419
+ ln=len(_bytes)
420
+ pad_bytes_needed = self.block_size - (ln % self.block_size)
421
+ if pad_bytes_needed == 0:
422
+ pad_bytes_needed = self.block_size
423
+ return pad_bytes_needed
@@ -0,0 +1,238 @@
1
+ '''
2
+ :Date: Jun 17, 2011
3
+ :Authors: Gary Belvin
4
+ '''
5
+ import unittest
6
+ from charm.toolbox.paddingschemes import OAEPEncryptionPadding, MGF1, hashFunc, PSSPadding, PKCS7Padding
7
+ from binascii import a2b_hex
8
+
9
+ debug = False
10
+ class Test(unittest.TestCase):
11
+
12
+ def testOEAPVector1(self):
13
+ # OAEP Test vector taken from Appendix C
14
+ #ftp://ftp.rsa.com/pub/rsalabs/rsa_algorithm/rsa-oaep_spec.pdf
15
+
16
+ # --------------------------------------------------------------------------------
17
+ # Message:
18
+ m = a2b_hex(bytes('d4 36 e9 95 69 fd 32 a7 c8 a0 5b bc 90 d3 2c 49'.replace(' ',''),'utf-8'))
19
+ label = ""
20
+ lhash = a2b_hex(bytes("da 39 a3 ee 5e 6b 4b 0d 32 55 bf ef 95 60 18 90 af d8 07 09".replace(' ',""),'utf-8'))
21
+ DB = a2b_hex(bytes("da 39 a3 ee 5e 6b 4b 0d 32 55 bf ef 95 60 18 90 af d8 07 09 00 00 00 00\
22
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\
23
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\
24
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 d4 36 e9 95 69\
25
+ fd 32 a7 c8 a0 5b bc 90 d3 2c 49".replace(" ", ""),'utf-8'))
26
+
27
+ seed = a2b_hex(bytes("aa fd 12 f6 59 ca e6 34 89 b4 79 e5 07 6d de c2 f0 6c b5 8f".replace(' ' ,''),'utf-8'))
28
+ #dbmask = dbMask = MGF (seed , 107):
29
+ dbmask= a2b_hex(bytes("06 e1 de b2 36 9a a5 a5 c7 07 d8 2c 8e 4e 93 24 8a c7 83 de e0 b2 c0 46\
30
+ 26 f5 af f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db 4c dc fe 4f f4\
31
+ 77 28 b4 a1 b7 c1 36 2b aa d2 9a b4 8d 28 69 d5 02 41 21 43 58 11 59 1b\
32
+ e3 92 f9 82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4e af f4 9c 8c 3b\
33
+ 7c fc 95 1a 51 ec d1 dd e6 12 64".replace(" ",""),'utf-8'))
34
+ #maskedDB
35
+ #seedMask = M GF (maskedDB, 20):
36
+ seedMask = a2b_hex(bytes("41 87 0b 5a b0 29 e6 57 d9 57 50 b5 4c 28 3c 08 72 5d be a9".replace(' ',''),'utf-8'))
37
+ maskedSeed= a2b_hex(bytes("eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2 ca 82 31 0b 26".replace(' ',''),'utf-8'))
38
+
39
+ #EM = maskedSeed maskedDB
40
+ EM = a2b_hex(bytes("00 eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2 ca 82 31 0b 26 dc d8 7d 5c\
41
+ 68 f1 ee a8 f5 52 67 c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af f9\
42
+ 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db 4c dc fe 4f f4 77 28 b4 a1\
43
+ b7 c1 36 2b aa d2 9a b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9 82\
44
+ fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f 7b c2 75 19 52 81 ce 32 d2\
45
+ f1 b7 6d 4d 35 3e 2d".replace(" ",''),'utf-8'))
46
+
47
+ if debug:
48
+ print("Test Vector 1:")
49
+ print("mesg =>", m)
50
+ print("label =>", label)
51
+ print("lhash =>", lhash) #Correct
52
+ print("DB =>", DB) #Correct
53
+ print("DBMask=>", dbmask) #Correct
54
+ print("seedMask=>", seedMask) #Correct
55
+ print("maskedseed=>", maskedSeed)
56
+
57
+ c = OAEPEncryptionPadding()
58
+ E = c.encode(m, 128,"",seed)
59
+ self.assertEqual(EM, E)
60
+
61
+ def testOAEPRoundTripEquiv(self):
62
+ oaep = OAEPEncryptionPadding()
63
+ m = b'This is a test message'
64
+ ct = oaep.encode(m, 64)
65
+ pt = oaep.decode(ct)
66
+ self.assertEqual(m, pt, 'Decoded message is not equal to encoded message\n'\
67
+ 'ct: %s\nm: %s\npt: %s' % (ct, m, pt))
68
+
69
+ @unittest.skip("Unnecessary length test")
70
+ def testMFGLength(self):
71
+ seed = ""
72
+ hashFn = OAEPEncryptionPadding().hashFn
73
+ hLen = OAEPEncryptionPadding().hashFnOutputBytes
74
+
75
+ for mbytes in range(100):
76
+ a = MGF1(seed, mbytes, hashFn, hLen)
77
+ self.assertEqual(len(a), mbytes, 'MFG output wrong size')
78
+
79
+ def testMFGvector(self):
80
+ hashFn = OAEPEncryptionPadding().hashFn
81
+ hLen = OAEPEncryptionPadding().hashFnOutputBytes
82
+ seed = a2b_hex(bytes("aa fd 12 f6 59 ca e6 34 89 b4 79 e5 07 6d de c2 f0 6c b5 8f".replace(' ' ,''),'utf-8'))
83
+ #dbmask = dbMask = MGF (seed , 107):
84
+ dbmask= a2b_hex(bytes("06 e1 de b2 36 9a a5 a5 c7 07 d8 2c 8e 4e 93 24 8a c7 83 de e0 b2 c0 46\
85
+ 26 f5 af f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db 4c dc fe 4f f4\
86
+ 77 28 b4 a1 b7 c1 36 2b aa d2 9a b4 8d 28 69 d5 02 41 21 43 58 11 59 1b\
87
+ e3 92 f9 82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4e af f4 9c 8c 3b\
88
+ 7c fc 95 1a 51 ec d1 dd e6 12 64".replace(" ",""),'utf-8'))
89
+ a = MGF1(seed, 107, hashFn, hLen)
90
+ self.assertEqual(dbmask, a)
91
+
92
+ def testSHA1Vector(self):
93
+ hashFn = hashFunc('sha1')
94
+ V0 = (b"", a2b_hex(bytes("da39a3ee5e6b4b0d3255bfef95601890afd80709",'utf-8')))
95
+ V1 = (bytes("The quick brown fox jumps over the lazy dog", 'utf-8'), a2b_hex(bytes("2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",'utf-8'))) #ASCII encoding
96
+ V2 = (b'The quick brown fox jumps over the lazy dog', a2b_hex(bytes("2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",'utf-8'))) #binary data
97
+ #print("str => ", V2[0])
98
+ #print("H(s)=> ", hashFn(V2[0]))
99
+ #print("stnd=> ", V2[1])
100
+
101
+ self.assertEqual(hashFn(V0[0]), V0[1], 'empty string')
102
+ self.assertEqual(hashFn(V1[0]), V1[1], 'quick fox')
103
+ self.assertEqual(hashFn(V2[0]), V2[1])
104
+
105
+
106
+ def testPSSRountTripEquiv(self):
107
+ pss = PSSPadding()
108
+ m = b'This is a test message'
109
+ em = pss.encode(m)
110
+ self.assertTrue(pss.verify(m, em))
111
+
112
+ def testPSSTestVector(self):
113
+ # Test vector taken from http://www.rsa.com/rsalabs/node.asp?id=2125
114
+ # ---------------------------------
115
+ # Step-by-step RSASSA-PSS Signature
116
+ # ---------------------------------
117
+
118
+ # Message M to be signed:
119
+ m = a2b_hex(bytes('85 9e ef 2f d7 8a ca 00 30 8b dc 47 11 93 bf 55\
120
+ bf 9d 78 db 8f 8a 67 2b 48 46 34 f3 c9 c2 6e 64\
121
+ 78 ae 10 26 0f e0 dd 8c 08 2e 53 a5 29 3a f2 17\
122
+ 3c d5 0c 6d 5d 35 4f eb f7 8b 26 02 1c 25 c0 27\
123
+ 12 e7 8c d4 69 4c 9f 46 97 77 e4 51 e7 f8 e9 e0\
124
+ 4c d3 73 9c 6b bf ed ae 48 7f b5 56 44 e9 ca 74\
125
+ ff 77 a5 3c b7 29 80 2f 6e d4 a5 ff a8 ba 15 98\
126
+ 90 fc'.replace(" ", ""),'utf-8'))
127
+
128
+ # mHash = Hash(M)
129
+ # salt = random string of octets
130
+ # M' = Padding || mHash || salt
131
+ # H = Hash(M')
132
+ # DB = Padding || salt
133
+ # dbMask = MGF(H, length(DB))
134
+ # maskedDB = DB xor dbMask (leftmost bit set to
135
+ # zero)
136
+ # EM = maskedDB || H || 0xbc
137
+
138
+ # mHash:
139
+ mHash = a2b_hex(bytes('37 b6 6a e0 44 58 43 35 3d 47 ec b0 b4 fd 14 c1\
140
+ 10 e6 2d 6a'.replace(" ", ""),'utf-8'))
141
+
142
+ # salt:
143
+ salt = a2b_hex(bytes('e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8\
144
+ 3b ce 7e 61'.replace(" ", ""),'utf-8'))
145
+
146
+ # M':
147
+ mPrime = a2b_hex(bytes('00 00 00 00 00 00 00 00 37 b6 6a e0 44 58 43 35\
148
+ 3d 47 ec b0 b4 fd 14 c1 10 e6 2d 6a e3 b5 d5 d0\
149
+ 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8 3b ce 7e 61'.replace(" ", ""),'utf-8'))
150
+
151
+ # H:
152
+ H = a2b_hex(bytes('df 1a 89 6f 9d 8b c8 16 d9 7c d7 a2 c4 3b ad 54\
153
+ 6f be 8c fe'.replace(" ", ""),'utf-8'))
154
+
155
+ # DB:
156
+ DB = a2b_hex(bytes('00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\
157
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\
158
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\
159
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\
160
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\
161
+ 00 00 00 00 00 00 01 e3 b5 d5 d0 02 c1 bc e5 0c\
162
+ 2b 65 ef 88 a1 88 d8 3b ce 7e 61'.replace(" ", ""),'utf-8'))
163
+
164
+ # dbMask:
165
+ dbMask = a2b_hex(bytes('66 e4 67 2e 83 6a d1 21 ba 24 4b ed 65 76 b8 67\
166
+ d9 a4 47 c2 8a 6e 66 a5 b8 7d ee 7f bc 7e 65 af\
167
+ 50 57 f8 6f ae 89 84 d9 ba 7f 96 9a d6 fe 02 a4\
168
+ d7 5f 74 45 fe fd d8 5b 6d 3a 47 7c 28 d2 4b a1\
169
+ e3 75 6f 79 2d d1 dc e8 ca 94 44 0e cb 52 79 ec\
170
+ d3 18 3a 31 1f c8 97 39 a9 66 43 13 6e 8b 0f 46\
171
+ 5e 87 a4 53 5c d4 c5 9b 10 02 8d'.replace(" ", ""),'utf-8'))
172
+
173
+ # maskedDB:
174
+ maskedDB = a2b_hex(bytes('66 e4 67 2e 83 6a d1 21 ba 24 4b ed 65 76 b8 67\
175
+ d9 a4 47 c2 8a 6e 66 a5 b8 7d ee 7f bc 7e 65 af\
176
+ 50 57 f8 6f ae 89 84 d9 ba 7f 96 9a d6 fe 02 a4\
177
+ d7 5f 74 45 fe fd d8 5b 6d 3a 47 7c 28 d2 4b a1\
178
+ e3 75 6f 79 2d d1 dc e8 ca 94 44 0e cb 52 79 ec\
179
+ d3 18 3a 31 1f c8 96 da 1c b3 93 11 af 37 ea 4a\
180
+ 75 e2 4b db fd 5c 1d a0 de 7c ec'.replace(" ", ""),'utf-8'))
181
+
182
+ # Encoded message EM:
183
+ EM = a2b_hex(bytes('66 e4 67 2e 83 6a d1 21 ba 24 4b ed 65 76 b8 67\
184
+ d9 a4 47 c2 8a 6e 66 a5 b8 7d ee 7f bc 7e 65 af\
185
+ 50 57 f8 6f ae 89 84 d9 ba 7f 96 9a d6 fe 02 a4\
186
+ d7 5f 74 45 fe fd d8 5b 6d 3a 47 7c 28 d2 4b a1\
187
+ e3 75 6f 79 2d d1 dc e8 ca 94 44 0e cb 52 79 ec\
188
+ d3 18 3a 31 1f c8 96 da 1c b3 93 11 af 37 ea 4a\
189
+ 75 e2 4b db fd 5c 1d a0 de 7c ec df 1a 89 6f 9d\
190
+ 8b c8 16 d9 7c d7 a2 c4 3b ad 54 6f be 8c fe bc'.replace(" ", ""),'utf-8'))
191
+
192
+ if debug:
193
+ print("PSS Test Vector:")
194
+ print("M =>", m)
195
+ print("Mlen =>", len(m))
196
+ print("mHash =>", mHash)
197
+ print("salt =>", salt)
198
+ print("M' =>", mPrime)
199
+ print("H =>", H)
200
+ print("DB =>", DB)
201
+ print("dbmask=>", dbMask)
202
+ print("masked=>", maskedDB)
203
+ print("EM =>", EM)
204
+ print("EMLen =>", len(EM))
205
+
206
+ pss = PSSPadding()
207
+ realEM = pss.encode(m,len(EM)*8,salt)
208
+ self.assertEqual(EM, realEM)
209
+
210
+
211
+ @classmethod
212
+ def suite(self):
213
+ suite = unittest.TestLoader().loadTestsFromTestCase(Test)
214
+ return suite
215
+
216
+ class TestPkcs7Padding(unittest.TestCase):
217
+ def setUp(self):
218
+ self.padder = PKCS7Padding()
219
+ def encodecode(self,text):
220
+ _bytes = bytes(text,'utf-8')
221
+ padded = self.padder.encode(_bytes)
222
+ assert _bytes == self.padder.decode(padded), 'o: =>%s\nm: =>%s' % (_bytes,padded)
223
+ assert len(padded) % 16 == 0 , 'invalid padding length: %s' % (len(padded))
224
+ assert len(padded) > 0, 'invalid padding length: %s' % (len(padded))
225
+ assert len(padded) > len(_bytes), 'message must allways have padding'
226
+
227
+ def testBasic(self):
228
+ self.encodecode("asd")
229
+ def testEmpty(self):
230
+ self.encodecode("")
231
+ def testFull(self):
232
+ self.encodecode("sixteen byte msg")
233
+ def testLarge(self):
234
+ self.encodecode("sixteen byte msg +3")
235
+
236
+ if __name__ == "__main__":
237
+ #import sys;sys.argv = ['', 'Test.testName']
238
+ unittest.main()