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