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,229 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* strxor.c: string XOR functions
|
|
3
|
+
*
|
|
4
|
+
* Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
|
5
|
+
*
|
|
6
|
+
* ===================================================================
|
|
7
|
+
* The contents of this file are dedicated to the public domain. To
|
|
8
|
+
* the extent that dedication to the public domain is not available,
|
|
9
|
+
* everyone is granted a worldwide, perpetual, royalty-free,
|
|
10
|
+
* non-exclusive license to exercise all rights associated with the
|
|
11
|
+
* contents of this file for any purpose whatsoever.
|
|
12
|
+
* No rights are reserved.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
18
|
+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
19
|
+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
* ===================================================================
|
|
23
|
+
*/
|
|
24
|
+
#include "Python.h"
|
|
25
|
+
#include <stddef.h>
|
|
26
|
+
#include <assert.h>
|
|
27
|
+
#include <string.h>
|
|
28
|
+
|
|
29
|
+
#include "pycrypto_compat.h"
|
|
30
|
+
|
|
31
|
+
static const char rcsid[] = "$Id$";
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* xor_strings - XOR two strings together to produce a third string
|
|
35
|
+
*
|
|
36
|
+
* dest[0..n-1] := src_a[0..n-1] ^ src_b[0..n-1]
|
|
37
|
+
*
|
|
38
|
+
*/
|
|
39
|
+
static void
|
|
40
|
+
xor_strings(char *dest, const char *src_a, const char *src_b, size_t n)
|
|
41
|
+
{
|
|
42
|
+
size_t i;
|
|
43
|
+
|
|
44
|
+
/* assert no pointer overflow */
|
|
45
|
+
assert(src_a + n > src_a);
|
|
46
|
+
assert(src_b + n > src_b);
|
|
47
|
+
assert(dest + n > dest);
|
|
48
|
+
|
|
49
|
+
for (i = 0; i < n; i++) {
|
|
50
|
+
dest[i] = src_a[i] ^ src_b[i];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/*
|
|
55
|
+
* xor_string_with_char - XOR a string with a char to produce another string
|
|
56
|
+
*
|
|
57
|
+
* dest[0..n-1] := src[0..n-1] ^ c
|
|
58
|
+
*
|
|
59
|
+
*/
|
|
60
|
+
static void
|
|
61
|
+
xor_string_with_char(char *dest, const char *src, char c, size_t n)
|
|
62
|
+
{
|
|
63
|
+
size_t i;
|
|
64
|
+
|
|
65
|
+
/* assert no pointer overflow */
|
|
66
|
+
assert(src + n > src);
|
|
67
|
+
assert(dest + n > dest);
|
|
68
|
+
|
|
69
|
+
for (i = 0; i < n; i++) {
|
|
70
|
+
dest[i] = src[i] ^ c;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/*
|
|
75
|
+
* "Import assertions"
|
|
76
|
+
*
|
|
77
|
+
* These runtime checks are performed when this module is first initialized
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
#define IMP_ASSERT(exp) do {\
|
|
82
|
+
if (!(exp)) {\
|
|
83
|
+
PyErr_Format(PyExc_AssertionError, "%s:%d: assertion failure: '%s'", __FILE__, __LINE__, #exp);\
|
|
84
|
+
return;\
|
|
85
|
+
}\
|
|
86
|
+
} while(0)
|
|
87
|
+
|
|
88
|
+
static void
|
|
89
|
+
runtime_test(void)
|
|
90
|
+
{
|
|
91
|
+
/* size_t should be able to represent the length of any size buffer */
|
|
92
|
+
IMP_ASSERT(sizeof(size_t) == sizeof(void *));
|
|
93
|
+
|
|
94
|
+
/* we must be able to perform the assignment (Py_ssize_t) -> (size_t)
|
|
95
|
+
* as long as the value is non-negative. */
|
|
96
|
+
IMP_ASSERT(sizeof(size_t) >= sizeof(Py_ssize_t));
|
|
97
|
+
|
|
98
|
+
/* char must be one octet */
|
|
99
|
+
IMP_ASSERT(sizeof(char) == 1);
|
|
100
|
+
|
|
101
|
+
/* Perform a basic test of the xor_strings function, including a test for
|
|
102
|
+
* an off-by-one bug. */
|
|
103
|
+
{
|
|
104
|
+
char x[7] = "\x00hello"; /* NUL + "hello" + NUL */
|
|
105
|
+
char y[7] = "\xffworld"; /* 0xff + "world" + NUL */
|
|
106
|
+
char z[9] = "[ABCDEFG]"; /* "[ABCDEFG]" + NUL */
|
|
107
|
+
|
|
108
|
+
xor_strings(z+1, x, y, 7);
|
|
109
|
+
IMP_ASSERT(!memcmp(z, "[\xff\x1f\x0a\x1e\x00\x0b\x00]", 9));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Perform a basic test of the xor_string_with_char function, including a test for
|
|
113
|
+
* an off-by-one bug. */
|
|
114
|
+
{
|
|
115
|
+
char x[7] = "\x00hello"; /* NUL + "hello" + NUL */
|
|
116
|
+
char y = 170; /* 0xaa */
|
|
117
|
+
char z[9] = "[ABCDEFG]"; /* "[ABCDEFG]" + NUL */
|
|
118
|
+
|
|
119
|
+
xor_string_with_char(z+1, x, y, 7);
|
|
120
|
+
IMP_ASSERT(!memcmp(z, "[\xaa\xc2\xcf\xc6\xc6\xc5\xaa]", 9));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/*
|
|
125
|
+
* The strxor Python function
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
static char strxor__doc__[] =
|
|
129
|
+
"strxor(a:str, b:str) -> str\n"
|
|
130
|
+
"\n"
|
|
131
|
+
"Return a XOR b. Both a and b must have the same length.\n";
|
|
132
|
+
|
|
133
|
+
static PyObject *
|
|
134
|
+
strxor_function(PyObject *self, PyObject *args)
|
|
135
|
+
{
|
|
136
|
+
PyObject *a, *b, *retval;
|
|
137
|
+
Py_ssize_t len_a, len_b;
|
|
138
|
+
|
|
139
|
+
if (!PyArg_ParseTuple(args, "SS", &a, &b))
|
|
140
|
+
return NULL;
|
|
141
|
+
|
|
142
|
+
len_a = PyString_GET_SIZE(a);
|
|
143
|
+
len_b = PyString_GET_SIZE(b);
|
|
144
|
+
|
|
145
|
+
assert(len_a >= 0);
|
|
146
|
+
assert(len_b >= 0);
|
|
147
|
+
|
|
148
|
+
if (len_a != len_b) {
|
|
149
|
+
PyErr_SetString(PyExc_ValueError, "length of both strings must be equal");
|
|
150
|
+
return NULL;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* Create return string */
|
|
154
|
+
retval = PyString_FromStringAndSize(NULL, len_a);
|
|
155
|
+
if (!retval) {
|
|
156
|
+
return NULL;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* retval := a ^ b */
|
|
160
|
+
xor_strings(PyString_AS_STRING(retval), PyString_AS_STRING(a), PyString_AS_STRING(b), len_a);
|
|
161
|
+
|
|
162
|
+
return retval;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
* The strxor_c Python function
|
|
167
|
+
*/
|
|
168
|
+
|
|
169
|
+
static char strxor_c__doc__[] =
|
|
170
|
+
"strxor_c(s:str, c:int) -> str\n"
|
|
171
|
+
"\n"
|
|
172
|
+
"Return s XOR chr(c). c must be in range(256).\n";
|
|
173
|
+
|
|
174
|
+
static PyObject *
|
|
175
|
+
strxor_c_function(PyObject *self, PyObject *args)
|
|
176
|
+
{
|
|
177
|
+
PyObject *s, *retval;
|
|
178
|
+
int c;
|
|
179
|
+
Py_ssize_t length;
|
|
180
|
+
|
|
181
|
+
if (!PyArg_ParseTuple(args, "Si", &s, &c))
|
|
182
|
+
return NULL;
|
|
183
|
+
|
|
184
|
+
if ((c < 0) || (c > 255)) {
|
|
185
|
+
PyErr_SetString(PyExc_ValueError, "c must be in range(256)");
|
|
186
|
+
return NULL;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
length = PyString_GET_SIZE(s);
|
|
190
|
+
assert(length >= 0);
|
|
191
|
+
|
|
192
|
+
/* Create return string */
|
|
193
|
+
retval = PyString_FromStringAndSize(NULL, length);
|
|
194
|
+
if (!retval) {
|
|
195
|
+
return NULL;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* retval := a ^ chr(c)*length */
|
|
199
|
+
xor_string_with_char(PyString_AS_STRING(retval), PyString_AS_STRING(s), (char) c, length);
|
|
200
|
+
|
|
201
|
+
return retval;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/*
|
|
205
|
+
* Module-level method table and module initialization function
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
static PyMethodDef strxor_methods[] = {
|
|
209
|
+
{"strxor", strxor_function, METH_VARARGS, strxor__doc__},
|
|
210
|
+
{"strxor_c", strxor_c_function, METH_VARARGS, strxor_c__doc__},
|
|
211
|
+
|
|
212
|
+
{NULL, NULL, 0, NULL} /* end-of-list sentinel value */
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
PyMODINIT_FUNC
|
|
216
|
+
initstrxor(void)
|
|
217
|
+
{
|
|
218
|
+
PyObject *m;
|
|
219
|
+
|
|
220
|
+
/* Initialize the module */
|
|
221
|
+
m = Py_InitModule("strxor", strxor_methods);
|
|
222
|
+
if (m == NULL)
|
|
223
|
+
return;
|
|
224
|
+
|
|
225
|
+
/* Perform runtime tests */
|
|
226
|
+
runtime_test();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* vim:set ts=4 sw=4 sts=4 expandtab: */
|
|
Binary file
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# TODO: provide a transition checker that prevents a feedback loop, inconsistent state.
|
|
2
|
+
# in user db that way user can eliminate store step on the receive side.
|
|
3
|
+
|
|
4
|
+
from charm.core.engine.util import *
|
|
5
|
+
from charm.toolbox.enum import Enum
|
|
6
|
+
from math import log, ceil
|
|
7
|
+
|
|
8
|
+
debug = False
|
|
9
|
+
# standardize responses between client and server
|
|
10
|
+
# code = Enum('Success', 'Fail', 'Repeat', 'StartSubprotocol', 'EndSubprotocol')
|
|
11
|
+
class Protocol:
|
|
12
|
+
def __init__(self, error_states, max_size=2048): # any init information?
|
|
13
|
+
global error
|
|
14
|
+
self.p_ID = 0
|
|
15
|
+
self.p_ctr = 0
|
|
16
|
+
error = error_states
|
|
17
|
+
# dictionary of party types (each type gets an identifier)
|
|
18
|
+
self.partyTypes = {}
|
|
19
|
+
self.party = {}
|
|
20
|
+
self._serialize = False
|
|
21
|
+
self.db = {} # initialize the database
|
|
22
|
+
self.max_size = max_size
|
|
23
|
+
self.prefix_size = ceil(log(max_size, 256))
|
|
24
|
+
|
|
25
|
+
def setup(self, *args):
|
|
26
|
+
# handles the hookup between parties involved
|
|
27
|
+
Error = True
|
|
28
|
+
for arg in args:
|
|
29
|
+
if isinstance(arg, dict):
|
|
30
|
+
print("Setup of: ", arg['name'])
|
|
31
|
+
if not self.addInstance(arg): Error = False
|
|
32
|
+
else:
|
|
33
|
+
print(type(arg))
|
|
34
|
+
return Error
|
|
35
|
+
|
|
36
|
+
def addInstance(self, obj):
|
|
37
|
+
p_ctr = self.p_ctr
|
|
38
|
+
for i in self.partyTypes.keys():
|
|
39
|
+
if i == obj['type']: # we find the party type
|
|
40
|
+
self.party[p_ctr] = {}
|
|
41
|
+
self.party[p_ctr]['name'], self.party[p_ctr]['socket'] = obj['name'], obj['socket']
|
|
42
|
+
self.party[p_ctr]['type'], self.party[p_ctr]['states'] = obj['type'], self.partyTypes[i]['states']
|
|
43
|
+
self.party[p_ctr]['init'] = self.partyTypes[i]['init']
|
|
44
|
+
self.p_ctr += 1
|
|
45
|
+
print("Adding party instance w/ id: ", p_ctr)
|
|
46
|
+
return True
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
def addPartyType(self, type, state_map, trans_map, init_state=False):
|
|
50
|
+
ExistingTypeFound = False
|
|
51
|
+
# see if type already exists. break and return if so
|
|
52
|
+
for i in self.partyTypes.keys():
|
|
53
|
+
if self.partyTypes[i]['type'] == type:
|
|
54
|
+
ExistingTypeFound = True
|
|
55
|
+
break
|
|
56
|
+
# means we are adding a new type
|
|
57
|
+
if not ExistingTypeFound:
|
|
58
|
+
p_ID = self.p_ID
|
|
59
|
+
party = {'type':type, 'id':p_ID }
|
|
60
|
+
if(isinstance(state_map, dict)):
|
|
61
|
+
party['states'] = state_map # function pointers for state functions...
|
|
62
|
+
if(isinstance(trans_map, dict)):
|
|
63
|
+
party['transitions'] = trans_map
|
|
64
|
+
party['init'] = init_state # which state initializes the protocol
|
|
65
|
+
self.partyTypes[type] = party # makes sure
|
|
66
|
+
self.p_ID += 1
|
|
67
|
+
return True
|
|
68
|
+
return False
|
|
69
|
+
#
|
|
70
|
+
# def addValidTransitions(self, trans_map):
|
|
71
|
+
# if isinstance(trans_map, dict):
|
|
72
|
+
# self.trans_map = trans_map
|
|
73
|
+
|
|
74
|
+
def listStates(self, partyID):
|
|
75
|
+
# check if a member parameter is defined
|
|
76
|
+
if partyID < self.p_ctr:
|
|
77
|
+
return self.party[partyID]['states']
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
def listParties(self):
|
|
81
|
+
return list(self.party.keys())
|
|
82
|
+
|
|
83
|
+
def listParyTypes(self):
|
|
84
|
+
return list(self.partyTypes.keys())
|
|
85
|
+
|
|
86
|
+
def getInitState(self, _type):
|
|
87
|
+
for i in self.listParties():
|
|
88
|
+
if self.party[i]['type'] == _type:
|
|
89
|
+
self._socket = self.party[i]['socket']
|
|
90
|
+
if self.party[i]['init']:
|
|
91
|
+
# set current trans starting point
|
|
92
|
+
self.cur_state = 1
|
|
93
|
+
return (True, self.listStates(i)[1])
|
|
94
|
+
else:
|
|
95
|
+
self.cur_state = 2
|
|
96
|
+
return (False, self.listStates(i)[2])
|
|
97
|
+
print("Returning junk!")
|
|
98
|
+
return (False, None)
|
|
99
|
+
|
|
100
|
+
def setState(self, state_num):
|
|
101
|
+
# find the corresponding call back based on current party id
|
|
102
|
+
self.nextCall = None
|
|
103
|
+
if state_num == None: return None
|
|
104
|
+
nextPossibleState = self._cur_trans.get(self.cur_state)
|
|
105
|
+
if type(nextPossibleState) == list and not state_num in nextPossibleState:
|
|
106
|
+
print("Invalid State Transition! Error!")
|
|
107
|
+
print("\tCurrent state: ", self.cur_state)
|
|
108
|
+
print("\tNext state: ", state_num)
|
|
109
|
+
print("Allowed states: ", nextPossibleState)
|
|
110
|
+
elif type(nextPossibleState) != list and nextPossibleState != state_num:
|
|
111
|
+
print("Invalid State Transition! Error!")
|
|
112
|
+
print("\tCurrent state: ", self.cur_state)
|
|
113
|
+
print("\tNext state not allowed: ", state_num)
|
|
114
|
+
# do not make the transition
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
for i in self.listParties():
|
|
118
|
+
states = self.listStates(i)
|
|
119
|
+
if states.get(state_num) != None:
|
|
120
|
+
self.nextCall = states.get(state_num)
|
|
121
|
+
# preparing for state transition here.
|
|
122
|
+
self.cur_state = state_num
|
|
123
|
+
break
|
|
124
|
+
return None
|
|
125
|
+
|
|
126
|
+
def send_msg(self, object):
|
|
127
|
+
# use socket to send message (check if serializaton is required)
|
|
128
|
+
if self._socket != None:
|
|
129
|
+
if self._serialize:
|
|
130
|
+
result = self._user_serialize(object)
|
|
131
|
+
else:
|
|
132
|
+
result = self.serialize(object)
|
|
133
|
+
#print("DEBUG: send_msg : result =>", result)
|
|
134
|
+
if len(result) > self.max_size:
|
|
135
|
+
print("Message too long! max_size="+str(self.max_size))
|
|
136
|
+
return None
|
|
137
|
+
result = len(result).to_bytes(length=self.prefix_size, byteorder='big') + result
|
|
138
|
+
self._socket.send(result)
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
# receives exactly n bytes
|
|
142
|
+
def recv_all(self, n):
|
|
143
|
+
recvd = 0
|
|
144
|
+
res = b''
|
|
145
|
+
while recvd < n:
|
|
146
|
+
res = res + self._socket.recv(n-recvd)
|
|
147
|
+
recvd = len(res)
|
|
148
|
+
return res
|
|
149
|
+
|
|
150
|
+
def recv_msg(self):
|
|
151
|
+
# read the socket and return the received message (check if deserialization)
|
|
152
|
+
# is necessary
|
|
153
|
+
if self._socket != None:
|
|
154
|
+
# block until data is available or remote host closes connection
|
|
155
|
+
msglen = int.from_bytes(self.recv_all(self.prefix_size), byteorder='big')
|
|
156
|
+
result = self.recv_all(msglen)
|
|
157
|
+
|
|
158
|
+
if result == '': return None
|
|
159
|
+
else:
|
|
160
|
+
if self._serialize:
|
|
161
|
+
return self._user_deserialize(result)
|
|
162
|
+
else: # default serialize call
|
|
163
|
+
return self.deserialize(result)
|
|
164
|
+
return None
|
|
165
|
+
|
|
166
|
+
# # serialize an object
|
|
167
|
+
# def serialize(self, object):
|
|
168
|
+
# if type(object) == str:
|
|
169
|
+
# return bytes(object, 'utf8')
|
|
170
|
+
# return object
|
|
171
|
+
#
|
|
172
|
+
# def deserialize(self, object):
|
|
173
|
+
# if type(object) == bytes:
|
|
174
|
+
# return object.decode('utf8')
|
|
175
|
+
# return object
|
|
176
|
+
def setSubclassVars(self, group, state=None):
|
|
177
|
+
if hasattr(group, 'serialize') and hasattr(group, 'deserialize'):
|
|
178
|
+
self.group = group
|
|
179
|
+
if state != None:
|
|
180
|
+
if type(state) == dict:
|
|
181
|
+
self.db = state
|
|
182
|
+
|
|
183
|
+
def get(self, keys, _type=tuple):
|
|
184
|
+
if not type(keys) == list: return
|
|
185
|
+
if _type == tuple:
|
|
186
|
+
ret = []
|
|
187
|
+
else: ret = {}
|
|
188
|
+
# get the data
|
|
189
|
+
for i in keys:
|
|
190
|
+
if _type == tuple:
|
|
191
|
+
ret.append(self.db[i])
|
|
192
|
+
else: # dict
|
|
193
|
+
ret[ i ] = self.db[i]
|
|
194
|
+
# return data
|
|
195
|
+
if _type == tuple:
|
|
196
|
+
return tuple(ret)
|
|
197
|
+
return ret
|
|
198
|
+
|
|
199
|
+
def store(self, *args):
|
|
200
|
+
for i in args:
|
|
201
|
+
if isinstance(i, tuple):
|
|
202
|
+
self.db[ i[0] ] = i[1]
|
|
203
|
+
return None
|
|
204
|
+
|
|
205
|
+
def serialize(self, object):
|
|
206
|
+
# print("input object... => ", object)
|
|
207
|
+
if type(object) == dict:
|
|
208
|
+
bytes_object = serializeDict(object, self.group)
|
|
209
|
+
return pickleObject(bytes_object)
|
|
210
|
+
elif type(object) == str:
|
|
211
|
+
return pickleObject(object)
|
|
212
|
+
else:
|
|
213
|
+
# print("serialize: just =>", object)
|
|
214
|
+
return object
|
|
215
|
+
|
|
216
|
+
def deserialize(self, bytes_object):
|
|
217
|
+
# print("deserialize input =>", bytes_object)
|
|
218
|
+
if type(bytes_object) == bytes:
|
|
219
|
+
object = unpickleObject(bytes_object)
|
|
220
|
+
if isinstance(object, dict):
|
|
221
|
+
return deserializeDict(object, self.group)
|
|
222
|
+
|
|
223
|
+
return object
|
|
224
|
+
# OPTIONAL
|
|
225
|
+
# derived class must call this function in order to
|
|
226
|
+
def setSerializers(self, serial, deserial):
|
|
227
|
+
self._serialize = True
|
|
228
|
+
self._user_serialize = serial
|
|
229
|
+
self._user_deserialize = deserial
|
|
230
|
+
return None
|
|
231
|
+
|
|
232
|
+
# records the final state of a protocol execution
|
|
233
|
+
def setErrorCode(self, value):
|
|
234
|
+
self.result = value
|
|
235
|
+
|
|
236
|
+
# executes state machine from the 'party_type' perspective
|
|
237
|
+
def execute(self, party_type, close_sock=True):
|
|
238
|
+
print("Party Descriptions:")
|
|
239
|
+
print(self.listParyTypes(), "\n")
|
|
240
|
+
# print("Executing protocol engine...")
|
|
241
|
+
# assume there are two parties: support more in the future.
|
|
242
|
+
# if len(self.listParties()) == 2:
|
|
243
|
+
# p1, p2 = self.listParties()
|
|
244
|
+
# print(self.listParties())
|
|
245
|
+
|
|
246
|
+
# main loop
|
|
247
|
+
# Timeout = False
|
|
248
|
+
(start, func) = self.getInitState(party_type)
|
|
249
|
+
self._cur_trans = self.partyTypes[party_type]['transitions']
|
|
250
|
+
#print("Possible transitions: ", self._cur_trans)
|
|
251
|
+
print("Starting Point => ", func.__name__)
|
|
252
|
+
if start == True:
|
|
253
|
+
# call the first state for party1, then send msg
|
|
254
|
+
output = func.__call__()
|
|
255
|
+
if type(output) == dict: self.db.update(output)
|
|
256
|
+
self.send_msg(output)
|
|
257
|
+
else:
|
|
258
|
+
# first receive message, call state function
|
|
259
|
+
# then send call response
|
|
260
|
+
input = self.recv_msg()
|
|
261
|
+
if type(input) == dict:
|
|
262
|
+
# print("input db :=>", input)
|
|
263
|
+
self.db.update(input)
|
|
264
|
+
output = func.__call__(input)
|
|
265
|
+
if isinstance(output, dict):
|
|
266
|
+
# print("output db :=>", output)
|
|
267
|
+
self.db.update(output)
|
|
268
|
+
self.send_msg(output)
|
|
269
|
+
# take output and send back to other party via socket
|
|
270
|
+
|
|
271
|
+
while self.nextCall != None:
|
|
272
|
+
input = self.recv_msg()
|
|
273
|
+
if isinstance(input, dict): self.db.update(input)
|
|
274
|
+
output = self.nextCall.__call__(input)
|
|
275
|
+
if output != None:
|
|
276
|
+
if isinstance(output, dict): self.db.update(output)
|
|
277
|
+
self.send_msg(output)
|
|
278
|
+
if close_sock:
|
|
279
|
+
self.clean()
|
|
280
|
+
return output
|
|
281
|
+
|
|
282
|
+
def check(self):
|
|
283
|
+
# cycle through parties, make sure they are differntly typed?
|
|
284
|
+
# p_ID must be at least 2
|
|
285
|
+
# ...
|
|
286
|
+
pass
|
|
287
|
+
|
|
288
|
+
def clean(self):
|
|
289
|
+
if debug: print("Cleaning database...")
|
|
290
|
+
self._socket.close()
|
|
291
|
+
self.db.clear()
|
|
292
|
+
print("PROTOCOL COMPLETE!")
|
|
293
|
+
return None
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The serialization API supports the following datatypes: dict, list, str, bytes, int, float, and whatever is supported by group.serialize and group.deserialize
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import print_function
|
|
7
|
+
import io, pickle
|
|
8
|
+
import json, zlib
|
|
9
|
+
from base64 import *
|
|
10
|
+
from charm.toolbox.bitstring import *
|
|
11
|
+
|
|
12
|
+
def serializeDict(Object, group):
|
|
13
|
+
return {
|
|
14
|
+
k: serializeObject(o, group)
|
|
15
|
+
for k, o in Object.items()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def serializeList(Object, group):
|
|
19
|
+
return [
|
|
20
|
+
serializeObject(o, group)
|
|
21
|
+
for o in Object
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
serializers = {
|
|
25
|
+
dict: serializeDict,
|
|
26
|
+
list: serializeList,
|
|
27
|
+
tuple: serializeList,
|
|
28
|
+
str: lambda obj, g: 'str:' + obj,
|
|
29
|
+
bytes: lambda obj, g: 'bytes:' + obj.decode('UTF-8'),
|
|
30
|
+
int: lambda obj, g: obj,
|
|
31
|
+
float: lambda obj, g: obj,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def serializeObject(Objects, group):
|
|
35
|
+
assert hasattr(group, 'serialize'), "group does not have serialize method"
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
serializer = serializers[type(Objects)]
|
|
39
|
+
except KeyError:
|
|
40
|
+
return group.serialize(Objects)
|
|
41
|
+
|
|
42
|
+
return serializer(Objects, group)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def deserializeDict(Object, group):
|
|
46
|
+
return {
|
|
47
|
+
k: deserializeObject(o, group)
|
|
48
|
+
for k, o in Object.items()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def deserializeList(Object, group):
|
|
53
|
+
return [
|
|
54
|
+
deserializeObject(o, group)
|
|
55
|
+
for o in Object
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def deserializeTuple(Object, group):
|
|
60
|
+
return tuple(deserializeList(Object, group))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def deserializeStr(object, group):
|
|
64
|
+
typ, obj = object.split(':', 1)
|
|
65
|
+
|
|
66
|
+
if typ == 'str':
|
|
67
|
+
return str(obj)
|
|
68
|
+
elif typ == 'bytes':
|
|
69
|
+
return getBytes(obj)
|
|
70
|
+
|
|
71
|
+
deserializers = {
|
|
72
|
+
dict: deserializeDict,
|
|
73
|
+
list: deserializeList,
|
|
74
|
+
tuple: deserializeTuple,
|
|
75
|
+
str: deserializeStr,
|
|
76
|
+
bytes: lambda obj, group: group.deserialize(obj)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
def deserializeObject(Objects, group):
|
|
80
|
+
assert hasattr(group, 'deserialize'), "group does not have deserialize method"
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
deserializer = deserializers[type(Objects)]
|
|
84
|
+
except KeyError:
|
|
85
|
+
return Objects
|
|
86
|
+
|
|
87
|
+
return deserializer(Objects, group)
|
|
88
|
+
|
|
89
|
+
def pickleObject(Object):
|
|
90
|
+
valid_types = [bytes, dict, list, str, int]
|
|
91
|
+
file = io.BytesIO()
|
|
92
|
+
# check that dictionary is all bytes (if not, return None)
|
|
93
|
+
if isinstance(Object, dict):
|
|
94
|
+
for k in Object.keys():
|
|
95
|
+
_type = type(Object[k])
|
|
96
|
+
if not _type in valid_types:
|
|
97
|
+
print("DEBUG: pickleObject Error!!! only bytes or dictionaries of bytes accepted."); print("invalid type =>", type(Object[k]))
|
|
98
|
+
return None
|
|
99
|
+
pickle.dump(Object, file, pickle.HIGHEST_PROTOCOL)
|
|
100
|
+
result = file.getvalue()
|
|
101
|
+
encoded = b64encode(result)
|
|
102
|
+
file.close()
|
|
103
|
+
return encoded
|
|
104
|
+
|
|
105
|
+
def unpickleObject(Object):
|
|
106
|
+
"""Unpickle a base64-encoded object.
|
|
107
|
+
|
|
108
|
+
WARNING: This function uses pickle.loads() which can execute arbitrary code
|
|
109
|
+
when deserializing untrusted data. Only use this with trusted input.
|
|
110
|
+
This is kept for backward compatibility with existing serialized data.
|
|
111
|
+
"""
|
|
112
|
+
if type(Object) == str or type(Object) == bytes:
|
|
113
|
+
byte_object = Object
|
|
114
|
+
else:
|
|
115
|
+
return None
|
|
116
|
+
decoded = b64decode(byte_object)
|
|
117
|
+
if type(decoded) == bytes and len(decoded) > 0:
|
|
118
|
+
return pickle.loads(decoded) # nosec B301 - intentional use for trusted data
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
# JSON does not support 'bytes' objects, so these from/to_json
|
|
122
|
+
# functions handle protecting the
|
|
123
|
+
def to_json(object):
|
|
124
|
+
if isinstance(object, bytes):
|
|
125
|
+
return {'__class__': 'bytes', '__value__': list(object) }
|
|
126
|
+
elif isinstance(object, tuple):
|
|
127
|
+
return {'__class__': 'tuple', '__value__': list(object) }
|
|
128
|
+
return TypeError(repr(object) + " is not JSON serializable")
|
|
129
|
+
|
|
130
|
+
def from_json(json_object):
|
|
131
|
+
if '__class__' in json_object:
|
|
132
|
+
if json_object['__class__'] == 'bytes':
|
|
133
|
+
return bytes(json_object['__value__'])
|
|
134
|
+
elif json_object['__class__'] == 'tuple':
|
|
135
|
+
return tuple(json_object['__value__'])
|
|
136
|
+
return json_object
|
|
137
|
+
|
|
138
|
+
# Two new API calls to simplify serializing to a blob of bytes
|
|
139
|
+
# objectToBytes() and bytesToObject()
|
|
140
|
+
def objectToBytes(object, group):
|
|
141
|
+
object_ser = serializeObject(object, group)
|
|
142
|
+
#result = pickleObject(object_ser)
|
|
143
|
+
result = getBytes(json.dumps(object_ser, default=to_json))
|
|
144
|
+
return b64encode(zlib.compress(result))
|
|
145
|
+
|
|
146
|
+
def bytesToObject(byteobject, group):
|
|
147
|
+
#unwrap_object = unpickleObject(byteobject)
|
|
148
|
+
decoded = bytes.decode(zlib.decompress(b64decode(byteobject)))
|
|
149
|
+
unwrap_object = json.loads(decoded, object_hook=from_json)
|
|
150
|
+
return deserializeObject(unwrap_object, group)
|
|
151
|
+
|
|
152
|
+
# Note: included for backwards compatibility with older versions.
|
|
153
|
+
# Will be removed completely in future versions.
|
|
154
|
+
def objectToBytesWithPickle(Object, group):
|
|
155
|
+
object_ser = serializeObject(Object, group)
|
|
156
|
+
return pickleObject(object_ser)
|
|
157
|
+
|
|
158
|
+
def bytesToObjectWithPickle(byteobject, group):
|
|
159
|
+
print("SecurityWarning: do not unpickle data received from an untrusted source. Bad things WILL happen!")
|
|
160
|
+
unwrap_object = unpickleObject(byteobject)
|
|
161
|
+
return deserializeObject(unwrap_object, group)
|
|
162
|
+
|
|
163
|
+
"""
|
|
164
|
+
Using serialization tools with our cryptographic schemes
|
|
165
|
+
requires that the group object is initialized
|
|
166
|
+
|
|
167
|
+
data = { 'test1':b"hello", 'test2':b"world", }
|
|
168
|
+
|
|
169
|
+
dataBytes = objectToBytes(data, group)
|
|
170
|
+
|
|
171
|
+
dataRec = bytesToObject(dataBytes, group)
|
|
172
|
+
|
|
173
|
+
assert data == dataRec, 'Error during deserialization.'
|
|
174
|
+
"""
|
|
File without changes
|