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,2094 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Charm-Crypto is a framework for rapidly prototyping cryptosystems.
|
|
3
|
+
*
|
|
4
|
+
* Charm-Crypto is free software; you can redistribute it and/or
|
|
5
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
6
|
+
* License as published by the Free Software Foundation; either
|
|
7
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* Charm-Crypto is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
* Lesser General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Lesser General Public License
|
|
15
|
+
* along with Charm-Crypto. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Please contact the charm-crypto dev team at support@charm-crypto.com
|
|
18
|
+
* for any questions.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* @file pairingmodule2.c
|
|
23
|
+
*
|
|
24
|
+
* @brief charm interface over MIRACL's pairing-based operations
|
|
25
|
+
*
|
|
26
|
+
* @author jakinye3@jhu.edu
|
|
27
|
+
* @remark this version of the pairing module uses the MIRACL library (www.shamus.ie).
|
|
28
|
+
* At the moment, only useful for academic purposes and should be treated as such.
|
|
29
|
+
* To build into Charm, you'll need to acquire the MIRACL source and compile with the
|
|
30
|
+
* build script located in the miracl dir. See the online documentation at charm-crypto.com
|
|
31
|
+
* for how to install.
|
|
32
|
+
*
|
|
33
|
+
************************************************************************/
|
|
34
|
+
|
|
35
|
+
#include "pairingmodule2.h"
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* Python 3.13+ made Py_IsFinalizing() public and removed _Py_IsFinalizing().
|
|
39
|
+
* For older versions, we need to use the private _Py_IsFinalizing().
|
|
40
|
+
*/
|
|
41
|
+
#if PY_MINOR_VERSION >= 13
|
|
42
|
+
#define CHARM_PY_IS_FINALIZING() Py_IsFinalizing()
|
|
43
|
+
#else
|
|
44
|
+
#define CHARM_PY_IS_FINALIZING() _Py_IsFinalizing()
|
|
45
|
+
#endif
|
|
46
|
+
|
|
47
|
+
int exp_rule(Group_t lhs, Group_t rhs)
|
|
48
|
+
{
|
|
49
|
+
if(lhs == pyZR_t && rhs == pyZR_t) return TRUE;
|
|
50
|
+
if(lhs == pyG1_t && rhs == pyZR_t) return TRUE;
|
|
51
|
+
if(lhs == pyG2_t && rhs == pyZR_t) return TRUE;
|
|
52
|
+
if(lhs == pyGT_t && rhs == pyZR_t) return TRUE;
|
|
53
|
+
return FALSE; /* Fail all other cases */
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
int mul_rule(Group_t lhs, Group_t rhs)
|
|
57
|
+
{
|
|
58
|
+
if(lhs == rhs) return TRUE;
|
|
59
|
+
if(lhs == pyZR_t || rhs == pyZR_t) return TRUE;
|
|
60
|
+
return FALSE; /* Fail all other cases */
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
int add_rule(Group_t lhs, Group_t rhs)
|
|
64
|
+
{
|
|
65
|
+
if(lhs == rhs && lhs != pyGT_t) return TRUE;
|
|
66
|
+
return FALSE; /* Fail all other cases */
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
int sub_rule(Group_t lhs, Group_t rhs)
|
|
70
|
+
{
|
|
71
|
+
if(lhs == rhs && lhs != pyGT_t) return TRUE;
|
|
72
|
+
return FALSE; /* Fail all other cases */
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
int div_rule(Group_t lhs, Group_t rhs)
|
|
76
|
+
{
|
|
77
|
+
if(lhs == rhs) return TRUE;
|
|
78
|
+
return FALSE; /* Fail all other cases */
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
int pair_rule(Group_t lhs, Group_t rhs)
|
|
82
|
+
{
|
|
83
|
+
if(lhs == pyG1_t && rhs == pyG2_t) return TRUE;
|
|
84
|
+
else if(lhs == pyG2_t && rhs == pyG1_t) return TRUE;
|
|
85
|
+
return FALSE; /* Fall all other cases : assume MNT? */
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
int check_type(Group_t type) {
|
|
89
|
+
if(type == pyZR_t || type == pyG1_t || type == pyG2_t || type == pyGT_t) return TRUE;
|
|
90
|
+
return FALSE;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#define ERROR_TYPE(operand, ...) "unsupported "#operand" operand types: "#__VA_ARGS__
|
|
94
|
+
|
|
95
|
+
#define UNARY(f, m, n) \
|
|
96
|
+
static PyObject *f(PyObject *v) { \
|
|
97
|
+
if(PyElement_Check(v)) { \
|
|
98
|
+
Element *obj1 = (Element *) v; \
|
|
99
|
+
return (n)(obj1); \
|
|
100
|
+
} return NULL; \
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#define BINARY(f, m, n) \
|
|
104
|
+
static PyObject *f(PyObject *v, PyObject *w) { \
|
|
105
|
+
Element *obj1 = NULL, *obj2 = NULL; \
|
|
106
|
+
int obj1_long = FALSE, obj2_long = FALSE; \
|
|
107
|
+
debug("Performing the '%s' operation.\n", __func__); \
|
|
108
|
+
if(PyElement_Check(v)) { \
|
|
109
|
+
obj1 = (Element *) v; } \
|
|
110
|
+
else if(PyNumber_Check(v)) { obj1 = convertToZR(v, w); obj1_long = TRUE; } \
|
|
111
|
+
else { PyErr_SetString(ElementError, ERROR_TYPE(left, int,bytes,str)); \
|
|
112
|
+
return NULL; } \
|
|
113
|
+
if(PyElement_Check(w)) { \
|
|
114
|
+
obj2 = (Element *) w; } \
|
|
115
|
+
else if(PyNumber_Check(w)) { obj2 = convertToZR(w, v); obj2_long = TRUE; } \
|
|
116
|
+
else { PyErr_SetString(ElementError, ERROR_TYPE(right, int,bytes,str)); \
|
|
117
|
+
return NULL; } \
|
|
118
|
+
if(Check_Types(obj1->element_type, obj2->element_type, m)) \
|
|
119
|
+
return (n)(obj1, obj2); \
|
|
120
|
+
return NULL; \
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
PyObject *mpzToLongObj(mpz_t m) {
|
|
124
|
+
/* borrowed from gmpy - then modified */
|
|
125
|
+
int size = (mpz_sizeinbase(m, 2) + PyLong_SHIFT - 1) / PyLong_SHIFT;
|
|
126
|
+
int i, isNeg = (mpz_sgn(m) < 0) ? TRUE : FALSE;
|
|
127
|
+
mpz_t temp;
|
|
128
|
+
PyLongObject *l = _PyLong_New(size);
|
|
129
|
+
if (!l)
|
|
130
|
+
return NULL;
|
|
131
|
+
mpz_init_set(temp, m);
|
|
132
|
+
for (i = 0; i < size; i++) {
|
|
133
|
+
l->ob_digit[i] = (digit)(mpz_get_ui(temp) & PyLong_MASK);
|
|
134
|
+
mpz_fdiv_q_2exp(temp, temp, PyLong_SHIFT);
|
|
135
|
+
}
|
|
136
|
+
i = size;
|
|
137
|
+
while ((i > 0) && (l->ob_digit[i - 1] == 0))
|
|
138
|
+
i--;
|
|
139
|
+
if(isNeg) {
|
|
140
|
+
Py_SIZE(l) = -i;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
Py_SIZE(l) = i;
|
|
144
|
+
}
|
|
145
|
+
mpz_clear(temp);
|
|
146
|
+
return (PyObject *) l;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
void longObjToMPZ (mpz_t m, PyLongObject * p)
|
|
150
|
+
{
|
|
151
|
+
int size, i, tmp = Py_SIZE(p);
|
|
152
|
+
int isNeg = FALSE;
|
|
153
|
+
mpz_t temp, temp2;
|
|
154
|
+
mpz_init (temp);
|
|
155
|
+
mpz_init (temp2);
|
|
156
|
+
if (tmp > 0)
|
|
157
|
+
size = tmp;
|
|
158
|
+
else {
|
|
159
|
+
size = -tmp;
|
|
160
|
+
isNeg = TRUE;
|
|
161
|
+
}
|
|
162
|
+
mpz_set_ui (m, 0);
|
|
163
|
+
for (i = 0; i < size; i++)
|
|
164
|
+
{
|
|
165
|
+
mpz_set_ui (temp, p->ob_digit[i]);
|
|
166
|
+
mpz_mul_2exp (temp2, temp, PyLong_SHIFT * i);
|
|
167
|
+
mpz_add (m, m, temp2);
|
|
168
|
+
}
|
|
169
|
+
mpz_clear (temp);
|
|
170
|
+
mpz_clear (temp2);
|
|
171
|
+
if(isNeg) mpz_neg(m, m);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
char *convert_buffer_to_hex(uint8_t * data, size_t len)
|
|
175
|
+
{
|
|
176
|
+
size_t i;
|
|
177
|
+
char tmp1[3];
|
|
178
|
+
char *tmp = (char *) malloc(len * 3);
|
|
179
|
+
memset(tmp, 0, len*3 - 1);
|
|
180
|
+
|
|
181
|
+
for (i = 0; i < len; i++) {
|
|
182
|
+
snprintf(tmp1, 3, "%02X ", data[i]);
|
|
183
|
+
strcat(tmp, tmp1);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return tmp;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
void printf_buffer_as_hex(uint8_t * data, size_t len)
|
|
190
|
+
{
|
|
191
|
+
#ifdef DEBUG
|
|
192
|
+
size_t i;
|
|
193
|
+
|
|
194
|
+
for (i = 0; i < len; i++) {
|
|
195
|
+
printf("%02x ", data[i]);
|
|
196
|
+
}
|
|
197
|
+
printf("\n");
|
|
198
|
+
#endif
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// simply checks that the elements satisfy the properties for the given
|
|
202
|
+
// binary operation. Whitelist approach: only return TRUE for valid cases, otherwise FALSE
|
|
203
|
+
int Check_Types(Group_t l_type, Group_t r_type, char op)
|
|
204
|
+
{
|
|
205
|
+
switch (op) {
|
|
206
|
+
// Rules: elements must be of the same type, multiplicative operations should be only used for
|
|
207
|
+
// elements in field GT
|
|
208
|
+
case 'a':
|
|
209
|
+
if(l_type == pyGT_t || r_type == pyGT_t) { return FALSE; }
|
|
210
|
+
break;
|
|
211
|
+
case 's':
|
|
212
|
+
if(l_type == pyGT_t || r_type == pyGT_t) { return FALSE; }
|
|
213
|
+
break;
|
|
214
|
+
case 'e':
|
|
215
|
+
if(l_type != pyG1_t && r_type != pyG2_t) { return FALSE; }
|
|
216
|
+
break;
|
|
217
|
+
case 'p':
|
|
218
|
+
// rule for exponentiation for types
|
|
219
|
+
if(l_type != pyG1_t && l_type != pyG2_t && l_type != pyGT_t && l_type != pyZR_t) { return FALSE; }
|
|
220
|
+
// && r_type != ZR)
|
|
221
|
+
// else {
|
|
222
|
+
// PyErr_SetString(ElementError, "Only fields => [G1_t,G2,GT,Zr] ** Zr");
|
|
223
|
+
// return FALSE;
|
|
224
|
+
//}
|
|
225
|
+
break;
|
|
226
|
+
default:
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return TRUE;
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// assumes that pairing structure has been initialized
|
|
235
|
+
static Element *createNewElement(Group_t element_type, Pairing *pairing) {
|
|
236
|
+
debug("Create an object of type Element\n");
|
|
237
|
+
Element *retObject = PyObject_New(Element, &ElementType);
|
|
238
|
+
if(element_type == pyZR_t) {
|
|
239
|
+
retObject->e = element_init_ZR(0);
|
|
240
|
+
retObject->element_type = pyZR_t;
|
|
241
|
+
}
|
|
242
|
+
else if(element_type == pyG1_t) {
|
|
243
|
+
retObject->e = element_init_G1();
|
|
244
|
+
retObject->element_type = pyG1_t;
|
|
245
|
+
}
|
|
246
|
+
else if(element_type == pyG2_t) {
|
|
247
|
+
retObject->e = element_init_G2();
|
|
248
|
+
retObject->element_type = pyG2_t;
|
|
249
|
+
}
|
|
250
|
+
else if(element_type == pyGT_t) {
|
|
251
|
+
retObject->e = element_init_GT(pairing);
|
|
252
|
+
retObject->element_type = pyGT_t;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// init without a type -- caller must set e and element_type
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
retObject->elem_initialized = TRUE;
|
|
259
|
+
retObject->elem_initPP = FALSE;
|
|
260
|
+
retObject->pairing = pairing;
|
|
261
|
+
Py_INCREF(retObject->pairing);
|
|
262
|
+
return retObject;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
Element *convertToZR(PyObject *longObj, PyObject *elemObj) {
|
|
266
|
+
Element *self = (Element *) elemObj;
|
|
267
|
+
Element *new = createNewElement(pyZR_t, self->pairing);
|
|
268
|
+
|
|
269
|
+
mpz_t x;
|
|
270
|
+
mpz_init(x);
|
|
271
|
+
#if PY_MAJOR_VERSION < 3
|
|
272
|
+
PyObject *longObj2 = PyNumber_Long(longObj);
|
|
273
|
+
longObjToMPZ(x, (PyLongObject *) longObj2);
|
|
274
|
+
Py_DECREF(longObj2);
|
|
275
|
+
#else
|
|
276
|
+
longObjToMPZ(x, (PyLongObject *) longObj);
|
|
277
|
+
#endif
|
|
278
|
+
element_set_mpz(new, x);
|
|
279
|
+
mpz_clear(x);
|
|
280
|
+
return new;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
void Pairing_dealloc(Pairing *self)
|
|
284
|
+
{
|
|
285
|
+
if(self->group_init) {
|
|
286
|
+
element_delete(pyZR_t, self->order);
|
|
287
|
+
pairing_clear(self->pair_obj);
|
|
288
|
+
self->pair_obj = NULL;
|
|
289
|
+
self->order = NULL;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
#ifdef BENCHMARK_ENABLED
|
|
293
|
+
if(self->dBench != NULL) {
|
|
294
|
+
// PrintPyRef("releasing benchmark object", self->dBench);
|
|
295
|
+
Py_CLEAR(self->dBench);
|
|
296
|
+
if(self->gBench != NULL) {
|
|
297
|
+
// PrintPyRef("releasing operations object", self->gBench);
|
|
298
|
+
Py_CLEAR(self->gBench);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
#endif
|
|
302
|
+
Py_TYPE(self)->tp_free((PyObject *) self);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
void Element_dealloc(Element* self)
|
|
306
|
+
{
|
|
307
|
+
// add reference count to objects
|
|
308
|
+
if(self->elem_initialized) {
|
|
309
|
+
element_delete(self->element_type, self->e);
|
|
310
|
+
// Defensive: Use Py_XDECREF instead of Py_DECREF to handle NULL safely
|
|
311
|
+
// and check if pairing object is valid before decrementing
|
|
312
|
+
// This prevents crashes with immortal objects in Python 3.12+ (PEP 683)
|
|
313
|
+
if(self->pairing != NULL) {
|
|
314
|
+
Py_XDECREF(self->pairing);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/*!
|
|
322
|
+
* Hash a null-terminated string to a byte array.
|
|
323
|
+
*
|
|
324
|
+
* @param input_buf The input buffer.
|
|
325
|
+
* @param input_len The input buffer length (in bytes).
|
|
326
|
+
* @param output_buf A pre-allocated output buffer of size hash_len.
|
|
327
|
+
* @param hash_len Length of the output hash (in bytes). Should be approximately bit size of curve group order.
|
|
328
|
+
* @param hash_prefix prefix for hash function.
|
|
329
|
+
*/
|
|
330
|
+
int hash_to_bytes(uint8_t *input_buf, int input_len, uint8_t *output_buf, int hash_len, uint8_t hash_prefix)
|
|
331
|
+
{
|
|
332
|
+
EVP_MD_CTX *ctx;
|
|
333
|
+
unsigned int md_len;
|
|
334
|
+
int i, new_input_len = input_len + 2; // extra byte for prefix
|
|
335
|
+
uint8_t first_block = 0;
|
|
336
|
+
uint8_t new_input[new_input_len+1];
|
|
337
|
+
// printf("orig input => \n");
|
|
338
|
+
// printf_buffer_as_hex(input_buf, input_len);
|
|
339
|
+
|
|
340
|
+
memset(new_input, 0, new_input_len+1);
|
|
341
|
+
new_input[0] = first_block; // block number (always 0 by default)
|
|
342
|
+
new_input[1] = hash_prefix; // set hash prefix
|
|
343
|
+
memcpy((uint8_t *)(new_input+2), input_buf, input_len); // copy input bytes
|
|
344
|
+
|
|
345
|
+
// printf("new input => \n");
|
|
346
|
+
// printf_buffer_as_hex(new_input, new_input_len);
|
|
347
|
+
// prepare output buf
|
|
348
|
+
memset(output_buf, 0, hash_len);
|
|
349
|
+
|
|
350
|
+
ctx = EVP_MD_CTX_new();
|
|
351
|
+
if (ctx == NULL) return FALSE;
|
|
352
|
+
|
|
353
|
+
if (hash_len <= HASH_LEN) {
|
|
354
|
+
EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
|
|
355
|
+
EVP_DigestUpdate(ctx, new_input, new_input_len);
|
|
356
|
+
uint8_t md[HASH_LEN+1];
|
|
357
|
+
EVP_DigestFinal_ex(ctx, md, &md_len);
|
|
358
|
+
memcpy(output_buf, md, hash_len);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
// apply variable-size hash technique to get desired size
|
|
362
|
+
// determine block count.
|
|
363
|
+
int blocks = (int) ceil(((double) hash_len) / HASH_LEN);
|
|
364
|
+
debug("Num blocks needed: %d\n", blocks);
|
|
365
|
+
uint8_t md[HASH_LEN+1];
|
|
366
|
+
uint8_t md2[(blocks * HASH_LEN)+1];
|
|
367
|
+
uint8_t *target_buf = md2;
|
|
368
|
+
for(i = 0; i < blocks; i++) {
|
|
369
|
+
/* compute digest = SHA-2( i || prefix || input_buf ) || ... || SHA-2( n-1 || prefix || input_buf ) */
|
|
370
|
+
target_buf += (i * HASH_LEN);
|
|
371
|
+
new_input[0] = (uint8_t) i;
|
|
372
|
+
EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
|
|
373
|
+
debug("input %d => ", i);
|
|
374
|
+
printf_buffer_as_hex(new_input, new_input_len);
|
|
375
|
+
EVP_DigestUpdate(ctx, new_input, new_input_len);
|
|
376
|
+
EVP_DigestFinal_ex(ctx, md, &md_len);
|
|
377
|
+
memcpy(target_buf, md, hash_len);
|
|
378
|
+
debug("block %d => ", i);
|
|
379
|
+
printf_buffer_as_hex(md, HASH_LEN);
|
|
380
|
+
memset(md, 0, HASH_LEN);
|
|
381
|
+
}
|
|
382
|
+
// copy back to caller
|
|
383
|
+
memcpy(output_buf, md2, hash_len);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
EVP_MD_CTX_free(ctx);
|
|
387
|
+
return TRUE;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/*!
|
|
391
|
+
* Hash a group element to a byte array. This calls hash_to_bytes().
|
|
392
|
+
*
|
|
393
|
+
* @param element The input element.
|
|
394
|
+
* @param hash_len Length of the output hash (in bytes).
|
|
395
|
+
* @param output_buf A pre-allocated output buffer.
|
|
396
|
+
* @param hash_num Index number of the hash function to use (changes the output).
|
|
397
|
+
* @return FENC_ERROR_NONE or an error code.
|
|
398
|
+
*/
|
|
399
|
+
int hash_element_to_bytes(Element *element, int hash_size, uint8_t* output_buf, int prefix)
|
|
400
|
+
{
|
|
401
|
+
int result = TRUE;
|
|
402
|
+
unsigned int buf_len;
|
|
403
|
+
|
|
404
|
+
buf_len = element_length_in_bytes(element);
|
|
405
|
+
uint8_t *temp_buf = (uint8_t *)malloc(buf_len+1);
|
|
406
|
+
if (temp_buf == NULL) {
|
|
407
|
+
return FALSE;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
element_to_bytes(temp_buf, element);
|
|
411
|
+
result = hash_to_bytes(temp_buf, buf_len, output_buf, hash_size, prefix);
|
|
412
|
+
free(temp_buf);
|
|
413
|
+
|
|
414
|
+
return TRUE;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
PyObject *Element_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
418
|
+
{
|
|
419
|
+
Element *self;
|
|
420
|
+
|
|
421
|
+
self = (Element *)type->tp_alloc(type, 0);
|
|
422
|
+
if (self != NULL) {
|
|
423
|
+
self->elem_initialized = FALSE;
|
|
424
|
+
self->pairing = NULL;
|
|
425
|
+
self->element_type = NONE_G;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return (PyObject *)self;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
PyObject *Pairing_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
432
|
+
{
|
|
433
|
+
Pairing *self = (Pairing *) type->tp_alloc(type, 0);
|
|
434
|
+
if(self != NULL) {
|
|
435
|
+
self->group_init = FALSE;
|
|
436
|
+
self->curve = -1;
|
|
437
|
+
#ifdef BENCHMARK_ENABLED
|
|
438
|
+
memset(self->bench_id, 0, ID_LEN);
|
|
439
|
+
self->dBench = NULL;
|
|
440
|
+
self->gBench = NULL;
|
|
441
|
+
#endif
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return (PyObject *) self;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
int Element_init(Element *self, PyObject *args, PyObject *kwds)
|
|
448
|
+
{
|
|
449
|
+
return -1;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
int Pairing_init(Pairing *self, PyObject *args, PyObject *kwds)
|
|
454
|
+
{
|
|
455
|
+
char *params = NULL, *param_string = NULL;
|
|
456
|
+
Py_ssize_t b_len = 0;
|
|
457
|
+
int aes_sec = -1;
|
|
458
|
+
static char *kwlist[] = {"aes_sec", "params", "param_string", NULL};
|
|
459
|
+
|
|
460
|
+
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|iss#", kwlist,
|
|
461
|
+
&aes_sec, ¶ms, ¶m_string, &b_len)) {
|
|
462
|
+
PyErr_SetString(ElementError, "invalid arguments");
|
|
463
|
+
return -1;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if(aes_sec != -1) {
|
|
467
|
+
if(aes_sec == MNT160) {
|
|
468
|
+
self->pair_obj = pairing_init(aes_sec);
|
|
469
|
+
self->order = order(self->pair_obj);
|
|
470
|
+
self->curve = MNT; // only supported at this point
|
|
471
|
+
pairing_init_finished = FALSE;
|
|
472
|
+
}
|
|
473
|
+
else if(aes_sec == BN256) {
|
|
474
|
+
self->pair_obj = pairing_init(aes_sec);
|
|
475
|
+
self->order = order(self->pair_obj);
|
|
476
|
+
self->curve = BN; // only supported at this point
|
|
477
|
+
pairing_init_finished = FALSE;
|
|
478
|
+
}
|
|
479
|
+
else if(aes_sec == SS512) {
|
|
480
|
+
self->pair_obj = pairing_init(aes_sec);
|
|
481
|
+
self->order = order(self->pair_obj);
|
|
482
|
+
self->curve = SS; // only supported at this point
|
|
483
|
+
pairing_init_finished = FALSE;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
self->group_init = TRUE;
|
|
488
|
+
return 0;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/*
|
|
492
|
+
PyObject *Element_call(Element *elem, PyObject *args, PyObject *kwds)
|
|
493
|
+
{
|
|
494
|
+
PyObject *object;
|
|
495
|
+
Element *newObject;
|
|
496
|
+
|
|
497
|
+
if(!PyArg_ParseTuple(args, "O:ref", &object)) {
|
|
498
|
+
printf("Could not retrieve object.\n");
|
|
499
|
+
return NULL;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
newObject = (Element *) object;
|
|
503
|
+
print("Elment->e => \n", newObject->element_type, newObject->e);
|
|
504
|
+
debug("Element->type => '%d'\n", newObject->element_type);
|
|
505
|
+
|
|
506
|
+
return NULL;
|
|
507
|
+
}
|
|
508
|
+
*/
|
|
509
|
+
|
|
510
|
+
static PyObject *Element_elem(Element* self, PyObject* args)
|
|
511
|
+
{
|
|
512
|
+
Element *retObject, *group = NULL;
|
|
513
|
+
int type;
|
|
514
|
+
PyObject *long_obj = NULL;
|
|
515
|
+
|
|
516
|
+
if(!PyArg_ParseTuple(args, "Oi|O", &group, &type, &long_obj)) {
|
|
517
|
+
PyErr_SetString(ElementError, "invalid arguments.\n");
|
|
518
|
+
return NULL;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
debug("init an element.\n");
|
|
522
|
+
|
|
523
|
+
if(type >= pyZR_t && type <= pyGT_t) {
|
|
524
|
+
retObject = createNewElement(type, group->pairing);
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
PyErr_SetString(ElementError, "unrecognized group type.");
|
|
528
|
+
return NULL;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if(long_obj != NULL && _PyLong_Check(long_obj)) {
|
|
532
|
+
mpz_t m;
|
|
533
|
+
mpz_init(m);
|
|
534
|
+
#if PY_MAJOR_VERSION < 3
|
|
535
|
+
PyObject *longObj2 = PyNumber_Long(long_obj);
|
|
536
|
+
longObjToMPZ(m, (PyLongObject *) longObj2);
|
|
537
|
+
Py_DECREF(longObj2);
|
|
538
|
+
#else
|
|
539
|
+
longObjToMPZ(m, (PyLongObject *) long_obj);
|
|
540
|
+
#endif
|
|
541
|
+
element_set_mpz(retObject, m);
|
|
542
|
+
mpz_clear(m);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/* return Element object */
|
|
546
|
+
return (PyObject *) retObject;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
PyObject *Pairing_print(Element* self)
|
|
550
|
+
{
|
|
551
|
+
return PyUnicode_FromString("");
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// TODO: use element_vnprintf to copy the result into element type
|
|
555
|
+
PyObject *Element_print(Element* self)
|
|
556
|
+
{
|
|
557
|
+
PyObject *strObj;
|
|
558
|
+
debug("Contents of element object\n");
|
|
559
|
+
|
|
560
|
+
if(check_type(self->element_type) && self->elem_initialized) {
|
|
561
|
+
int len = element_length_to_str(self);
|
|
562
|
+
unsigned char *tmp = (unsigned char *) malloc(len + 1);
|
|
563
|
+
memset(tmp, 0, len);
|
|
564
|
+
element_to_str(&tmp, self);
|
|
565
|
+
tmp[len] = '\0';
|
|
566
|
+
|
|
567
|
+
strObj = PyUnicode_FromString((const char *) tmp);
|
|
568
|
+
free(tmp);
|
|
569
|
+
return strObj;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return PyUnicode_FromString("");
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
static PyObject *Element_random(Element* self, PyObject* args)
|
|
576
|
+
{
|
|
577
|
+
Element *retObject;
|
|
578
|
+
Pairing *group = NULL;
|
|
579
|
+
int arg1;
|
|
580
|
+
int seed = -1;
|
|
581
|
+
|
|
582
|
+
/* create a new object */
|
|
583
|
+
if(!PyArg_ParseTuple(args, "Oi|i", &group, &arg1, &seed))
|
|
584
|
+
return NULL;
|
|
585
|
+
|
|
586
|
+
VERIFY_GROUP(group);
|
|
587
|
+
retObject = PyObject_New(Element, &ElementType);
|
|
588
|
+
debug("init random element in '%d'\n", arg1);
|
|
589
|
+
if(arg1 == pyZR_t) {
|
|
590
|
+
retObject->e = element_init_ZR(0);
|
|
591
|
+
retObject->element_type = pyZR_t;
|
|
592
|
+
}
|
|
593
|
+
else if(arg1 == pyG1_t) {
|
|
594
|
+
retObject->e = element_init_G1();
|
|
595
|
+
retObject->element_type = pyG1_t;
|
|
596
|
+
}
|
|
597
|
+
else if(arg1 == pyG2_t) {
|
|
598
|
+
retObject->e = element_init_G2();
|
|
599
|
+
retObject->element_type = pyG2_t;
|
|
600
|
+
}
|
|
601
|
+
else if(arg1 == pyGT_t) {
|
|
602
|
+
PyErr_SetString(ElementError, "cannot generate random element in GT directly.");
|
|
603
|
+
return NULL;
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
PyErr_SetString(ElementError, "unrecognized group type.");
|
|
607
|
+
return NULL;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if(seed > -1) {
|
|
611
|
+
// pbc_random_set_deterministic((uint32_t) seed);
|
|
612
|
+
}
|
|
613
|
+
/* create new Element object */
|
|
614
|
+
element_random(retObject->element_type, group->pair_obj, retObject->e);
|
|
615
|
+
|
|
616
|
+
retObject->elem_initialized = TRUE;
|
|
617
|
+
retObject->elem_initPP = FALSE;
|
|
618
|
+
retObject->pairing = group;
|
|
619
|
+
Py_INCREF(retObject->pairing);
|
|
620
|
+
return (PyObject *) retObject;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
static PyObject *Element_add(Element *self, Element *other)
|
|
624
|
+
{
|
|
625
|
+
Element *newObject = NULL;
|
|
626
|
+
|
|
627
|
+
debug("Starting '%s'\n", __func__);
|
|
628
|
+
#ifdef DEBUG
|
|
629
|
+
if(self->e) {
|
|
630
|
+
// element_printf("Left: e => '%B'\n", self->e);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
if(other->e) {
|
|
634
|
+
// element_printf("Right: e => '%B'\n", other->e);
|
|
635
|
+
}
|
|
636
|
+
#endif
|
|
637
|
+
|
|
638
|
+
if( add_rule(self->element_type, other->element_type) == FALSE) {
|
|
639
|
+
PyErr_SetString(ElementError, "invalid add operation");
|
|
640
|
+
return NULL;
|
|
641
|
+
}
|
|
642
|
+
// start micro benchmark
|
|
643
|
+
|
|
644
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
645
|
+
element_add(newObject, self, other);
|
|
646
|
+
#ifdef BENCHMARK_ENABLED
|
|
647
|
+
UPDATE_BENCH(ADDITION, newObject->element_type, newObject->pairing);
|
|
648
|
+
#endif
|
|
649
|
+
return (PyObject *) newObject;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
static PyObject *Element_sub(Element *self, Element *other)
|
|
653
|
+
{
|
|
654
|
+
Element *newObject = NULL;
|
|
655
|
+
|
|
656
|
+
debug("Starting '%s'\n", __func__);
|
|
657
|
+
#ifdef DEBUG
|
|
658
|
+
if(self->e) {
|
|
659
|
+
// element_printf("Left: e => '%B'\n", self->e);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
if(other->e) {
|
|
663
|
+
// element_printf("Right: e => '%B'\n", other->e);
|
|
664
|
+
}
|
|
665
|
+
#endif
|
|
666
|
+
if( sub_rule(self->element_type, other->element_type) == FALSE) {
|
|
667
|
+
PyErr_SetString(ElementError, "invalid sub operation");
|
|
668
|
+
return NULL;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
673
|
+
element_sub(newObject, self, other);
|
|
674
|
+
#ifdef BENCHMARK_ENABLED
|
|
675
|
+
UPDATE_BENCH(SUBTRACTION, newObject->element_type, newObject->pairing);
|
|
676
|
+
#endif
|
|
677
|
+
return (PyObject *) newObject;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
static PyObject *Element_mul(PyObject *lhs, PyObject *rhs)
|
|
682
|
+
{
|
|
683
|
+
Element *self = NULL, *other = NULL, *newObject = NULL;
|
|
684
|
+
signed long int z;
|
|
685
|
+
int found_int = FALSE;
|
|
686
|
+
|
|
687
|
+
// lhs or rhs must be an element type
|
|
688
|
+
if(PyElement_Check(lhs)) {
|
|
689
|
+
self = (Element *) lhs;
|
|
690
|
+
}
|
|
691
|
+
else if(PyNumber_Check(lhs)) {
|
|
692
|
+
if(PyArg_Parse(lhs, "l", &z)) {
|
|
693
|
+
debug("Integer lhs: '%li'\n", z);
|
|
694
|
+
}
|
|
695
|
+
found_int = TRUE;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if(PyElement_Check(rhs)) {
|
|
699
|
+
other = (Element *) rhs;
|
|
700
|
+
}
|
|
701
|
+
else if(PyNumber_Check(rhs)) {
|
|
702
|
+
if(PyArg_Parse(rhs, "l", &z)) {
|
|
703
|
+
debug("Integer rhs: '%li'\n", z);
|
|
704
|
+
}
|
|
705
|
+
found_int = TRUE;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
debug("Starting '%s'\n", __func__);
|
|
709
|
+
if(PyElement_Check(lhs) && found_int) {
|
|
710
|
+
// lhs is the element type
|
|
711
|
+
//
|
|
712
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
713
|
+
element_mul_si(newObject, self, z);
|
|
714
|
+
//
|
|
715
|
+
}
|
|
716
|
+
else if(PyElement_Check(rhs) && found_int) {
|
|
717
|
+
// rhs is the element type
|
|
718
|
+
//
|
|
719
|
+
newObject = createNewElement(other->element_type, other->pairing);
|
|
720
|
+
element_mul_si(newObject, other, z);
|
|
721
|
+
//
|
|
722
|
+
}
|
|
723
|
+
else if(PyElement_Check(lhs) && PyElement_Check(rhs)) {
|
|
724
|
+
// both are element types
|
|
725
|
+
if( mul_rule(self->element_type, other->element_type) == FALSE) {
|
|
726
|
+
PyErr_SetString(ElementError, "invalid mul operation");
|
|
727
|
+
return NULL;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
if(self->element_type != pyZR_t && other->element_type == pyZR_t) {
|
|
731
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
732
|
+
element_mul_zn(newObject, self, other);
|
|
733
|
+
}
|
|
734
|
+
else if(other->element_type != pyZR_t && self->element_type == pyZR_t) {
|
|
735
|
+
newObject = createNewElement(other->element_type, self->pairing);
|
|
736
|
+
element_mul_zn(newObject, other, self);
|
|
737
|
+
}
|
|
738
|
+
else { // all other cases
|
|
739
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
740
|
+
element_mul(newObject, self, other);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
PyErr_SetString(ElementError, "invalid types");
|
|
745
|
+
return NULL;
|
|
746
|
+
}
|
|
747
|
+
#ifdef BENCHMARK_ENABLED
|
|
748
|
+
UPDATE_BENCH(MULTIPLICATION, newObject->element_type, newObject->pairing);
|
|
749
|
+
#endif
|
|
750
|
+
return (PyObject *) newObject;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
static PyObject *Element_div(PyObject *lhs, PyObject *rhs)
|
|
754
|
+
{
|
|
755
|
+
Element *self = NULL, *other = NULL, *newObject = NULL;
|
|
756
|
+
signed long int z;
|
|
757
|
+
int found_int = FALSE;
|
|
758
|
+
|
|
759
|
+
// lhs or rhs must be an element type
|
|
760
|
+
if(PyElement_Check(lhs)) {
|
|
761
|
+
self = (Element *) lhs;
|
|
762
|
+
}
|
|
763
|
+
else if(PyNumber_Check(lhs)) {
|
|
764
|
+
if(PyArg_Parse(lhs, "l", &z)) {
|
|
765
|
+
debug("Integer lhs: '%li'\n", z);
|
|
766
|
+
}
|
|
767
|
+
found_int = TRUE;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if(PyElement_Check(rhs)) {
|
|
771
|
+
other = (Element *) rhs;
|
|
772
|
+
}
|
|
773
|
+
else if(PyNumber_Check(rhs)) {
|
|
774
|
+
if(PyArg_Parse(rhs, "l", &z)) {
|
|
775
|
+
debug("Integer rhs: '%li'\n", z);
|
|
776
|
+
}
|
|
777
|
+
found_int = TRUE;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
debug("Starting '%s'\n", __func__);
|
|
781
|
+
if(PyElement_Check(lhs) && found_int) {
|
|
782
|
+
// lhs is the element type
|
|
783
|
+
|
|
784
|
+
if(z != 0) {
|
|
785
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
786
|
+
other = createNewElement(self->element_type, self->pairing);
|
|
787
|
+
element_set_si(other, z);
|
|
788
|
+
element_div(newObject, self, other);
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
PyErr_SetString(ElementError, "divide by zero exception!");
|
|
792
|
+
goto divbyzero;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
}
|
|
796
|
+
else if(PyElement_Check(rhs) && found_int) {
|
|
797
|
+
// rhs is the element type
|
|
798
|
+
|
|
799
|
+
if(z > 1 || z <= 0) {
|
|
800
|
+
newObject = createNewElement(other->element_type, other->pairing);
|
|
801
|
+
self = createNewElement(other->element_type, other->pairing);
|
|
802
|
+
element_set_si(self, z);
|
|
803
|
+
element_div(newObject, self, other); // come back to this (not working)
|
|
804
|
+
}
|
|
805
|
+
else if(z == 1) {
|
|
806
|
+
newObject = createNewElement(other->element_type, other->pairing);
|
|
807
|
+
element_invert(newObject, other);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
}
|
|
811
|
+
else if(PyElement_Check(lhs) && PyElement_Check(rhs)) {
|
|
812
|
+
// both are element types
|
|
813
|
+
if( div_rule(self->element_type, other->element_type) == FALSE) {
|
|
814
|
+
PyErr_SetString(ElementError, "invalid div operation");
|
|
815
|
+
return NULL;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
820
|
+
element_div(newObject, self, other);
|
|
821
|
+
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
PyErr_SetString(ElementError, "invalid types");
|
|
825
|
+
return NULL;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
#ifdef BENCHMARK_ENABLED
|
|
829
|
+
UPDATE_BENCH(DIVISION, newObject->element_type, newObject->pairing);
|
|
830
|
+
#endif
|
|
831
|
+
|
|
832
|
+
divbyzero:
|
|
833
|
+
return (PyObject *) newObject;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
static PyObject *Element_invert(Element *self)
|
|
838
|
+
{
|
|
839
|
+
Element *newObject = NULL;
|
|
840
|
+
|
|
841
|
+
// debug("Starting '%s'\n", __func__);
|
|
842
|
+
//#ifdef DEBUG
|
|
843
|
+
// if(self->e) {
|
|
844
|
+
// element_printf("e => '%B'\n", self->e);
|
|
845
|
+
// }
|
|
846
|
+
//#endif
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
if(check_type(self->element_type)) {
|
|
850
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
851
|
+
element_invert(newObject, self);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
return (PyObject *) newObject;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
static PyObject *Element_negate(Element *self)
|
|
858
|
+
{
|
|
859
|
+
Element *newObject = NULL;
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
863
|
+
element_neg(newObject, self);
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
return (PyObject *) newObject;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
static PyObject *Element_pow(PyObject *o1, PyObject *o2, PyObject *o3)
|
|
870
|
+
{
|
|
871
|
+
Element *newObject = NULL, *lhs_o1 = NULL, *rhs_o2 = NULL;
|
|
872
|
+
int longFoundLHS = FALSE, longFoundRHS = FALSE;
|
|
873
|
+
mpz_t n;
|
|
874
|
+
|
|
875
|
+
Check_Types2(o1, o2, lhs_o1, rhs_o2, longFoundLHS, longFoundRHS);
|
|
876
|
+
|
|
877
|
+
if(longFoundLHS) {
|
|
878
|
+
// o1 is a long type and o2 is a element type
|
|
879
|
+
// o1 should be element and o2 should be mpz
|
|
880
|
+
printf("operation undefined: '%d' ^ <pairing element>\n", rhs_o2->element_type);
|
|
881
|
+
// if(rhs_o2->element_type == ZR) {
|
|
882
|
+
//
|
|
883
|
+
// mpz_init(n);
|
|
884
|
+
// element_to_mpz(n, rhs_o2);
|
|
885
|
+
//
|
|
886
|
+
// lhs_o1 = convertToZR(o1, o2);
|
|
887
|
+
// newObject = createNewElement(rhs_o2->element_type, rhs_o2->pairing);
|
|
888
|
+
// element_pow_zr(newObject, lhs_o1, n);
|
|
889
|
+
// mpz_clear(n);
|
|
890
|
+
// PyObject_Del(lhs_o1);
|
|
891
|
+
//
|
|
892
|
+
// }
|
|
893
|
+
}
|
|
894
|
+
else if(longFoundRHS) {
|
|
895
|
+
// o2 is a long type
|
|
896
|
+
// if(lhs_o1->element_type != pyZR_t) {
|
|
897
|
+
|
|
898
|
+
long rhs = PyLong_AsLong(o2);
|
|
899
|
+
if(PyErr_Occurred() || rhs >= 0) {
|
|
900
|
+
// clear error and continue
|
|
901
|
+
//PyErr_Print(); // for debug purposes
|
|
902
|
+
PyErr_Clear();
|
|
903
|
+
newObject = createNewElement(lhs_o1->element_type, lhs_o1->pairing);
|
|
904
|
+
rhs_o2 = createNewElement(pyZR_t, lhs_o1->pairing);
|
|
905
|
+
if(newObject->element_type != pyZR_t) {
|
|
906
|
+
mpz_init(n);
|
|
907
|
+
#if PY_MAJOR_VERSION < 3
|
|
908
|
+
PyObject *longObj2 = PyNumber_Long(o2);
|
|
909
|
+
longObjToMPZ(n, (PyLongObject *) longObj2);
|
|
910
|
+
Py_DECREF(longObj2);
|
|
911
|
+
#else
|
|
912
|
+
longObjToMPZ(n, (PyLongObject *) o2);
|
|
913
|
+
#endif
|
|
914
|
+
element_set_mpz(rhs_o2, n);
|
|
915
|
+
element_pow_zr(newObject, lhs_o1, rhs_o2);
|
|
916
|
+
mpz_clear(n);
|
|
917
|
+
}
|
|
918
|
+
else if(rhs >= 0 && rhs <= INT_MAX) {
|
|
919
|
+
// if less than int for given architecture
|
|
920
|
+
element_pow_int(newObject, lhs_o1, rhs);
|
|
921
|
+
}
|
|
922
|
+
else { // anything larger: convert to an MPZ type then raise to EXP value
|
|
923
|
+
mpz_init(n);
|
|
924
|
+
#if PY_MAJOR_VERSION < 3
|
|
925
|
+
PyObject *longObj2 = PyNumber_Long(o2);
|
|
926
|
+
longObjToMPZ(n, (PyLongObject *) longObj2);
|
|
927
|
+
Py_DECREF(longObj2);
|
|
928
|
+
#else
|
|
929
|
+
longObjToMPZ(n, (PyLongObject *) o2);
|
|
930
|
+
#endif
|
|
931
|
+
element_set_mpz(rhs_o2, n);
|
|
932
|
+
element_pow_zr(newObject, lhs_o1, rhs_o2);
|
|
933
|
+
mpz_clear(n);
|
|
934
|
+
}
|
|
935
|
+
Py_DECREF(rhs_o2);
|
|
936
|
+
|
|
937
|
+
}
|
|
938
|
+
else if(rhs == -1) {
|
|
939
|
+
newObject = createNewElement(lhs_o1->element_type, lhs_o1->pairing);
|
|
940
|
+
element_invert(newObject, lhs_o1);
|
|
941
|
+
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
EXIT_IF(TRUE, "unexpected error.");
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
else if(Check_Elements(o1, o2)) {
|
|
948
|
+
debug("Starting '%s'\n", __func__);
|
|
949
|
+
EXIT_IF(exp_rule(lhs_o1->element_type, rhs_o2->element_type) == FALSE, "invalid exp operation.");
|
|
950
|
+
|
|
951
|
+
if(rhs_o2->element_type == pyZR_t) {
|
|
952
|
+
|
|
953
|
+
newObject = createNewElement(NONE_G, lhs_o1->pairing);
|
|
954
|
+
element_pow_zr(newObject, lhs_o1, rhs_o2);
|
|
955
|
+
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
EXIT_IF(!PyElement_Check(o1), ERROR_TYPE(left, int, bytes, str));
|
|
960
|
+
EXIT_IF(!PyElement_Check(o2), ERROR_TYPE(right, int, bytes, str));
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
#ifdef BENCHMARK_ENABLED
|
|
964
|
+
UPDATE_BENCH(EXPONENTIATION, newObject->element_type, newObject->pairing);
|
|
965
|
+
#endif
|
|
966
|
+
return (PyObject *) newObject;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/* We assume the element has been initialized into a specific field (G1_t,G2,GT,or Zr), then
|
|
970
|
+
they have the opportunity to set the
|
|
971
|
+
|
|
972
|
+
*/
|
|
973
|
+
static PyObject *Element_set(Element *self, PyObject *args)
|
|
974
|
+
{
|
|
975
|
+
Element *object = NULL;
|
|
976
|
+
int errcode = TRUE;
|
|
977
|
+
long int value = -1;
|
|
978
|
+
|
|
979
|
+
if(self->elem_initialized == FALSE) {
|
|
980
|
+
PyErr_SetString(ElementError, "must initialize element to a field (G1_t,G2,GT, or Zr)");
|
|
981
|
+
errcode = FALSE;
|
|
982
|
+
return Py_BuildValue("i", errcode);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
debug("Creating a new element\n");
|
|
986
|
+
if(PyArg_ParseTuple(args, "|lO", &value, &object)) {
|
|
987
|
+
// convert into an int using PyArg_Parse(...)
|
|
988
|
+
// set the element
|
|
989
|
+
if(value == -1 && self->element_type == pyZR_t) {
|
|
990
|
+
debug("Setting element to '%li'\n", value);
|
|
991
|
+
|
|
992
|
+
debug("Value '%i'\n", (signed int) value);
|
|
993
|
+
element_set_si(self, (signed int) value);
|
|
994
|
+
|
|
995
|
+
}
|
|
996
|
+
else if(object != NULL) {
|
|
997
|
+
|
|
998
|
+
if(self->element_type == object->element_type) {
|
|
999
|
+
|
|
1000
|
+
element_set(self, object);
|
|
1001
|
+
|
|
1002
|
+
}
|
|
1003
|
+
else {
|
|
1004
|
+
PyErr_SetString(ElementError, "types are not the same!");
|
|
1005
|
+
errcode = FALSE;
|
|
1006
|
+
return Py_BuildValue("i", errcode);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
return Py_BuildValue("i", errcode);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
static PyObject *Element_setxy(Element *self, PyObject *args)
|
|
1015
|
+
{
|
|
1016
|
+
Element *object1 = NULL, *object2 = NULL;
|
|
1017
|
+
int errcode = TRUE;
|
|
1018
|
+
|
|
1019
|
+
if(self->elem_initialized == FALSE) {
|
|
1020
|
+
PyErr_SetString(ElementError, "must initialize element to a field (G1_t,G2,GT, or Zr)");
|
|
1021
|
+
return NULL;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
debug("Creating a new element\n");
|
|
1025
|
+
if(PyArg_ParseTuple(args, "|OO", &object1, &object2)) {
|
|
1026
|
+
// convert into an int using PyArg_Parse(...)
|
|
1027
|
+
// set the element
|
|
1028
|
+
if(self->element_type == pyG1_t) {
|
|
1029
|
+
if(object1->element_type == object2->element_type && object1->element_type == pyZR_t) {
|
|
1030
|
+
errcode = element_setG1(self, object1, object2);
|
|
1031
|
+
}
|
|
1032
|
+
else {
|
|
1033
|
+
PyErr_SetString(ElementError, "types are not the same!");
|
|
1034
|
+
return NULL;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
Py_RETURN_TRUE;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
static PyObject *Element_initPP(Element *self, PyObject *args)
|
|
1043
|
+
{
|
|
1044
|
+
EXITCODE_IF(self->elem_initPP == TRUE, "initialized the pre-processing function already", FALSE);
|
|
1045
|
+
EXITCODE_IF(self->elem_initialized == FALSE, "must initialize element to a field (G1,G2, or GT)", FALSE);
|
|
1046
|
+
|
|
1047
|
+
/* initialize and store preprocessing information in e_pp */
|
|
1048
|
+
if(self->element_type >= pyG1_t && self->element_type <= pyGT_t) {
|
|
1049
|
+
int result;
|
|
1050
|
+
element_pp_init(result, self);
|
|
1051
|
+
if(result == FALSE) { Py_RETURN_FALSE; }
|
|
1052
|
+
self->elem_initPP = TRUE;
|
|
1053
|
+
Py_RETURN_TRUE;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
Py_RETURN_FALSE;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
/* Takes a list of two objects in G1 & G2 respectively and computes the multi-pairing */
|
|
1061
|
+
PyObject *multi_pairing_asymmetric(Pairing *groupObj, PyObject *listG1, PyObject *listG2)
|
|
1062
|
+
{
|
|
1063
|
+
int length = PySequence_Length(listG1);
|
|
1064
|
+
|
|
1065
|
+
if(length != PySequence_Length(listG2)) {
|
|
1066
|
+
PyErr_SetString(ElementError, "unequal number of pairing elements.");
|
|
1067
|
+
return NULL;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
if(length > 0) {
|
|
1071
|
+
|
|
1072
|
+
element_t *g1[length];
|
|
1073
|
+
element_t *g2[length];
|
|
1074
|
+
int i, l = 0, r = 0;
|
|
1075
|
+
|
|
1076
|
+
for(i = 0; i < length; i++) {
|
|
1077
|
+
PyObject *tmpObject1 = PySequence_GetItem(listG1, i);
|
|
1078
|
+
PyObject *tmpObject2 = PySequence_GetItem(listG2, i);
|
|
1079
|
+
|
|
1080
|
+
if(PyElement_Check(tmpObject1) && PyElement_Check(tmpObject2)) {
|
|
1081
|
+
Element *tmp1 = (Element *) tmpObject1;
|
|
1082
|
+
Element *tmp2 = (Element *) tmpObject2;
|
|
1083
|
+
if(tmp1->element_type == pyG1_t) {
|
|
1084
|
+
g1[l] = element_init_G1();
|
|
1085
|
+
element_set_raw(groupObj, pyG1_t, g1[l], tmp1->e);
|
|
1086
|
+
l++;
|
|
1087
|
+
}
|
|
1088
|
+
if(tmp2->element_type == pyG2_t) {
|
|
1089
|
+
g2[r] = element_init_G2();
|
|
1090
|
+
element_set_raw(groupObj, pyG2_t, g2[r], tmp2->e);
|
|
1091
|
+
r++;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
Py_DECREF(tmpObject1);
|
|
1095
|
+
Py_DECREF(tmpObject2);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
Element *newObject = NULL;
|
|
1099
|
+
if(l == r) {
|
|
1100
|
+
newObject = createNewElement(pyGT_t, groupObj);
|
|
1101
|
+
element_prod_pairing(newObject, &g1, &g2, l); // pairing product calculation
|
|
1102
|
+
}
|
|
1103
|
+
else {
|
|
1104
|
+
PyErr_SetString(ElementError, "invalid pairing element types in list.");
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/* clean up */
|
|
1108
|
+
for(i = 0; i < l; i++) { element_delete(pyG1_t, g1[i]); }
|
|
1109
|
+
for(i = 0; i < r; i++) { element_delete(pyG2_t, g2[i]); }
|
|
1110
|
+
return (PyObject *) newObject;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
PyErr_SetString(ElementError, "list is empty.");
|
|
1114
|
+
return NULL;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/* this is a type method that is visible on the global or class level. Therefore,
|
|
1118
|
+
the function prototype needs the self (element class) and the args (tuple of Element objects).
|
|
1119
|
+
*/
|
|
1120
|
+
PyObject *Apply_pairing(Element *self, PyObject *args)
|
|
1121
|
+
{
|
|
1122
|
+
// lhs => G1_t and rhs => G2
|
|
1123
|
+
Element *newObject = NULL, *lhs, *rhs;
|
|
1124
|
+
Pairing *group = NULL;
|
|
1125
|
+
PyObject *lhs2, *rhs2;
|
|
1126
|
+
|
|
1127
|
+
debug("Applying pairing...\n");
|
|
1128
|
+
if(!PyArg_ParseTuple(args, "OO|O", &lhs2, &rhs2, &group)) {
|
|
1129
|
+
PyErr_SetString(ElementError, "missing element objects");
|
|
1130
|
+
return NULL;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
if(PySequence_Check(lhs2) && PySequence_Check(rhs2)) {
|
|
1134
|
+
VERIFY_GROUP(group); /* defined iff using as multi-pairing */
|
|
1135
|
+
return multi_pairing_asymmetric(group, lhs2, rhs2);
|
|
1136
|
+
}
|
|
1137
|
+
else if(PyElement_Check(lhs2) && PyElement_Check(rhs2)) {
|
|
1138
|
+
|
|
1139
|
+
lhs = (Element *) lhs2;
|
|
1140
|
+
rhs = (Element *) rhs2;
|
|
1141
|
+
|
|
1142
|
+
if(Check_Elements(lhs, rhs) && pair_rule(lhs->element_type, rhs->element_type) == TRUE) {
|
|
1143
|
+
newObject = createNewElement(NONE_G, lhs->pairing);
|
|
1144
|
+
if(lhs->element_type == pyG1_t) {
|
|
1145
|
+
pairing_apply(newObject, lhs, rhs);
|
|
1146
|
+
}
|
|
1147
|
+
else if(lhs->element_type == pyG2_t) {
|
|
1148
|
+
pairing_apply(newObject, rhs, lhs);
|
|
1149
|
+
}
|
|
1150
|
+
#ifdef BENCHMARK_ENABLED
|
|
1151
|
+
UPDATE_BENCHMARK(PAIRINGS, newObject->pairing->dBench);
|
|
1152
|
+
#endif
|
|
1153
|
+
return (PyObject *) newObject;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
PyErr_SetString(ElementError, "pairings only apply to elements of G1 x G2 --> GT");
|
|
1158
|
+
return NULL;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
PyObject *sha2_hash(Element *self, PyObject *args) {
|
|
1162
|
+
Element *object;
|
|
1163
|
+
PyObject *str;
|
|
1164
|
+
char *hash_hex = NULL;
|
|
1165
|
+
int label = 0;
|
|
1166
|
+
|
|
1167
|
+
debug("Hashing the element...\n");
|
|
1168
|
+
if(!PyArg_ParseTuple(args, "O|i", &object, &label)) {
|
|
1169
|
+
PyErr_SetString(ElementError, "missing element object");
|
|
1170
|
+
return NULL;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
if(!PyElement_Check(object)) {
|
|
1174
|
+
PyErr_SetString(ElementError, "not a valid element object.");
|
|
1175
|
+
return NULL;
|
|
1176
|
+
}
|
|
1177
|
+
if(!object->elem_initialized) {
|
|
1178
|
+
PyErr_SetString(ElementError, "null element object");
|
|
1179
|
+
return NULL;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
int hash_size = HASH_LEN;
|
|
1183
|
+
uint8_t hash_buf[hash_size + 1];
|
|
1184
|
+
memset(hash_buf, 0, hash_size);
|
|
1185
|
+
if(object->element_type == pyGT_t) {
|
|
1186
|
+
element_hash_to_key(object, hash_buf, hash_size);
|
|
1187
|
+
|
|
1188
|
+
hash_hex = convert_buffer_to_hex(hash_buf, hash_size);
|
|
1189
|
+
printf_buffer_as_hex(hash_buf, hash_size);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
str = PyBytes_FromStringAndSize((const char *) hash_hex, hash_size);
|
|
1193
|
+
free(hash_hex);
|
|
1194
|
+
|
|
1195
|
+
return str;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
// new version that uses same approach as Charm-C++
|
|
1199
|
+
static PyObject *Element_hash(Element *self, PyObject *args)
|
|
1200
|
+
{
|
|
1201
|
+
Element *newObject = NULL, *object = NULL;
|
|
1202
|
+
Pairing *group = NULL;
|
|
1203
|
+
PyObject *objList = NULL, *tmpObject = NULL;
|
|
1204
|
+
PyObject *tmp_obj = NULL;
|
|
1205
|
+
Group_t type = pyZR_t;
|
|
1206
|
+
int i;
|
|
1207
|
+
|
|
1208
|
+
char *tmp = NULL, *str;
|
|
1209
|
+
// make sure args have the right type -- check that args contain a "string" and "string"
|
|
1210
|
+
if(!PyArg_ParseTuple(args, "OO|i", &group, &objList, &type)) {
|
|
1211
|
+
tmp = "invalid object types";
|
|
1212
|
+
goto cleanup;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
VERIFY_GROUP(group);
|
|
1216
|
+
// first case: is a string and type may or may not be set
|
|
1217
|
+
if(PyBytes_CharmCheck(objList)) {
|
|
1218
|
+
str = NULL;
|
|
1219
|
+
if(type >= pyZR_t && type < pyGT_t) {
|
|
1220
|
+
PyBytes_ToString2(str, objList, tmp_obj);
|
|
1221
|
+
int len = strlen(str);
|
|
1222
|
+
debug("Hashing string '%s' to Zr...\n", str);
|
|
1223
|
+
// create an element of Zr
|
|
1224
|
+
// hash bytes using SHA1
|
|
1225
|
+
newObject = createNewElement(NONE_G, group);
|
|
1226
|
+
newObject->element_type = type;
|
|
1227
|
+
|
|
1228
|
+
element_init_hash(group);
|
|
1229
|
+
debug("Hashing string '%s' to Zr...: size=%d, newsize=%d\n", str, len, strlen(str));
|
|
1230
|
+
element_add_str_hash(group, str, len);
|
|
1231
|
+
element_finish_hash(newObject, type);
|
|
1232
|
+
if(tmp_obj != NULL) Py_DECREF(tmp_obj);
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
// not supported, right?
|
|
1236
|
+
tmp = "cannot hash a string to that field. Only Zr or G1_t.";
|
|
1237
|
+
goto cleanup;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
// second case: is a tuple of elements of which could be a string or group elements
|
|
1241
|
+
else if(PySequence_Check(objList)) {
|
|
1242
|
+
int size = PySequence_Length(objList);
|
|
1243
|
+
if(size > 0) {
|
|
1244
|
+
// its a tuple of Elements
|
|
1245
|
+
tmpObject = PySequence_GetItem(objList, 0);
|
|
1246
|
+
element_init_hash(group);
|
|
1247
|
+
if(PyElement_Check(tmpObject)) {
|
|
1248
|
+
object = (Element *) tmpObject;
|
|
1249
|
+
|
|
1250
|
+
element_add_to_hash(object);
|
|
1251
|
+
|
|
1252
|
+
}
|
|
1253
|
+
else if(PyBytes_CharmCheck(tmpObject)) {
|
|
1254
|
+
str = NULL;
|
|
1255
|
+
PyBytes_ToString2(str, tmpObject, tmp_obj);
|
|
1256
|
+
|
|
1257
|
+
element_add_str_hash(group, str, strlen(str));
|
|
1258
|
+
|
|
1259
|
+
}
|
|
1260
|
+
Py_DECREF(tmpObject);
|
|
1261
|
+
if(tmp_obj != NULL) Py_DECREF(tmp_obj);
|
|
1262
|
+
|
|
1263
|
+
// loop over the remaining elements in list
|
|
1264
|
+
for(i = 1; i < size; i++) {
|
|
1265
|
+
tmpObject = PySequence_GetItem(objList, i);
|
|
1266
|
+
if(PyElement_Check(tmpObject)) {
|
|
1267
|
+
object = (Element *) tmpObject;
|
|
1268
|
+
|
|
1269
|
+
element_add_to_hash(object);
|
|
1270
|
+
}
|
|
1271
|
+
else if(PyBytes_CharmCheck(tmpObject)) {
|
|
1272
|
+
str = NULL;
|
|
1273
|
+
PyBytes_ToString2(str, tmpObject, tmp_obj);
|
|
1274
|
+
|
|
1275
|
+
element_add_str_hash(group, str, strlen(str));
|
|
1276
|
+
|
|
1277
|
+
}
|
|
1278
|
+
Py_DECREF(tmpObject);
|
|
1279
|
+
if(tmp_obj != NULL) Py_DECREF(tmp_obj);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
if(type >= pyZR_t && type < pyGT_t) { newObject = createNewElement(NONE_G, group); }
|
|
1283
|
+
else {
|
|
1284
|
+
tmp = "invalid object type";
|
|
1285
|
+
goto cleanup;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
newObject->element_type = type;
|
|
1289
|
+
element_finish_hash(newObject, type);
|
|
1290
|
+
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
// third case: a tuple with one element and
|
|
1294
|
+
else if(PyElement_Check(objList)) {
|
|
1295
|
+
// one element
|
|
1296
|
+
object = (Element *) objList;
|
|
1297
|
+
if(object->elem_initialized == FALSE) {
|
|
1298
|
+
tmp = "element not initialized.";
|
|
1299
|
+
goto cleanup;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// Hash an element of Zr to an element of G1_t.
|
|
1303
|
+
if(type == pyG1_t) {
|
|
1304
|
+
|
|
1305
|
+
newObject = createNewElement(NONE_G, group);
|
|
1306
|
+
newObject->element_type = type;
|
|
1307
|
+
// hash the element to the G1_t field (uses sha1 as well)
|
|
1308
|
+
element_init_hash(group);
|
|
1309
|
+
element_add_to_hash(object);
|
|
1310
|
+
element_finish_hash(newObject, type);
|
|
1311
|
+
|
|
1312
|
+
}
|
|
1313
|
+
else {
|
|
1314
|
+
tmp = "can only hash an element of Zr to G1_t. Random Oracle.";
|
|
1315
|
+
goto cleanup;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
else {
|
|
1319
|
+
tmp = "invalid object types";
|
|
1320
|
+
goto cleanup;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
return (PyObject *) newObject;
|
|
1325
|
+
|
|
1326
|
+
cleanup:
|
|
1327
|
+
PyErr_SetString(ElementError, tmp);
|
|
1328
|
+
if(newObject != NULL) Py_DECREF(newObject);
|
|
1329
|
+
return NULL;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
static PyObject *Element_equals(PyObject *lhs, PyObject *rhs, int opid) {
|
|
1333
|
+
Element *self = NULL, *other = NULL;
|
|
1334
|
+
signed long int z;
|
|
1335
|
+
int found_int = FALSE, result = -1; // , value;
|
|
1336
|
+
|
|
1337
|
+
if(opid != Py_EQ && opid != Py_NE) {
|
|
1338
|
+
PyErr_SetString(ElementError, "only comparison supported is '==' or '!='");
|
|
1339
|
+
goto cleanup;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
// check type of lhs
|
|
1343
|
+
if(PyElement_Check(lhs)) {
|
|
1344
|
+
self = (Element *) lhs;
|
|
1345
|
+
}
|
|
1346
|
+
else if(PyNumber_Check(lhs)) {
|
|
1347
|
+
if(PyArg_Parse(lhs, "l", &z)) {
|
|
1348
|
+
debug("Integer lhs: '%li'\n", z);
|
|
1349
|
+
}
|
|
1350
|
+
found_int = (z == 0 || z == 1) ? TRUE : FALSE;
|
|
1351
|
+
}
|
|
1352
|
+
else {
|
|
1353
|
+
PyErr_SetString(ElementError, "types supported: element or int (0 or 1)");
|
|
1354
|
+
goto cleanup;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
// check type of rhs
|
|
1358
|
+
if(PyElement_Check(rhs)) {
|
|
1359
|
+
other = (Element *) rhs;
|
|
1360
|
+
}
|
|
1361
|
+
else if(PyNumber_Check(rhs)) {
|
|
1362
|
+
if(PyArg_Parse(lhs, "l", &z)) {
|
|
1363
|
+
debug("Integer rhs: '%li'\n", z);
|
|
1364
|
+
}
|
|
1365
|
+
found_int = (z == 0 || z == 1) ? TRUE : FALSE;
|
|
1366
|
+
}
|
|
1367
|
+
else {
|
|
1368
|
+
PyErr_SetString(ElementError, "types supported: element or int (0 or 1)");
|
|
1369
|
+
goto cleanup;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
debug("Starting '%s'\n", __func__);
|
|
1373
|
+
|
|
1374
|
+
if(PyElement_Check(lhs) && found_int) {
|
|
1375
|
+
// lhs is the element type
|
|
1376
|
+
if(self->element_type == pyZR_t)
|
|
1377
|
+
result = element_is(self, z);
|
|
1378
|
+
}
|
|
1379
|
+
else if(PyElement_Check(rhs) && found_int) {
|
|
1380
|
+
if(other->element_type == pyZR_t)
|
|
1381
|
+
result = element_is(other, z);
|
|
1382
|
+
}
|
|
1383
|
+
else if(PyElement_Check(lhs) && PyElement_Check(rhs)) {
|
|
1384
|
+
// lhs and rhs are both elements
|
|
1385
|
+
if(self->elem_initialized && other->elem_initialized) {
|
|
1386
|
+
if(self->element_type == other->element_type)
|
|
1387
|
+
result = element_cmp(self, other);
|
|
1388
|
+
}
|
|
1389
|
+
else {
|
|
1390
|
+
debug("One of the elements is not initialized.\n");
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
if(result == -1) {
|
|
1396
|
+
/* print error */
|
|
1397
|
+
PyErr_SetString(ElementError, "cannot compare different group types.\n");
|
|
1398
|
+
return NULL;
|
|
1399
|
+
}
|
|
1400
|
+
cleanup:
|
|
1401
|
+
// value = (result == 0) ? TRUE : FALSE;
|
|
1402
|
+
|
|
1403
|
+
if(opid == Py_EQ) {
|
|
1404
|
+
if(result == TRUE) {
|
|
1405
|
+
Py_RETURN_TRUE;
|
|
1406
|
+
}
|
|
1407
|
+
Py_RETURN_FALSE;
|
|
1408
|
+
}
|
|
1409
|
+
else { /* Py_NE */
|
|
1410
|
+
if(result == FALSE) {
|
|
1411
|
+
Py_RETURN_TRUE;
|
|
1412
|
+
}
|
|
1413
|
+
Py_RETURN_FALSE;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
static PyObject *Element_long(PyObject *o1) {
|
|
1418
|
+
if(PyElement_Check(o1)) {
|
|
1419
|
+
Element *value = (Element *) o1;
|
|
1420
|
+
/* can only handle elements in ZR */
|
|
1421
|
+
if(value->element_type == pyZR_t) {
|
|
1422
|
+
mpz_t val;
|
|
1423
|
+
mpz_init(val);
|
|
1424
|
+
element_to_mpz(value, val);
|
|
1425
|
+
PyObject *obj = mpzToLongObj(val);
|
|
1426
|
+
mpz_clear(val);
|
|
1427
|
+
return obj;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
PyErr_SetString(ElementError, "cannot cast pairing object to an integer.");
|
|
1431
|
+
return NULL;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
static long Element_index(Element *o1) {
|
|
1435
|
+
long result = -1;
|
|
1436
|
+
|
|
1437
|
+
if(PyElement_Check(o1)) {
|
|
1438
|
+
if(o1->element_type == pyZR_t) {
|
|
1439
|
+
mpz_t o;
|
|
1440
|
+
mpz_init(o);
|
|
1441
|
+
element_to_mpz(o1, o);
|
|
1442
|
+
PyObject *temp = mpzToLongObj(o);
|
|
1443
|
+
result = PyObject_Hash(temp);
|
|
1444
|
+
mpz_clear(o);
|
|
1445
|
+
Py_XDECREF(temp); //PyObject_Del(temp);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
return result;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
UNARY(instance_negate, 'i', Element_negate)
|
|
1453
|
+
UNARY(instance_invert, 'i', Element_invert)
|
|
1454
|
+
BINARY(instance_add, 'a', Element_add)
|
|
1455
|
+
BINARY(instance_sub, 's', Element_sub)
|
|
1456
|
+
|
|
1457
|
+
static PyObject *Serialize_cmp(Element *o1, PyObject *args) {
|
|
1458
|
+
|
|
1459
|
+
Element *self = NULL;
|
|
1460
|
+
if(!PyArg_ParseTuple(args, "O", &self)) {
|
|
1461
|
+
PyErr_SetString(ElementError, "invalid argument.");
|
|
1462
|
+
return NULL;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
if(!PyElement_Check(self)) {
|
|
1466
|
+
PyErr_SetString(ElementError, "not a valid element object.");
|
|
1467
|
+
return NULL;
|
|
1468
|
+
}
|
|
1469
|
+
if(self->elem_initialized == FALSE) {
|
|
1470
|
+
PyErr_SetString(ElementError, "element not initialized.");
|
|
1471
|
+
return NULL;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
int elem_len = 0;
|
|
1475
|
+
uint8_t *data_buf = NULL;
|
|
1476
|
+
size_t bytes_written;
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
// printf("element type => '%d'\n", self->element_type);
|
|
1480
|
+
// print("test output => ", self->element_type, self->e);
|
|
1481
|
+
if(check_type(self->element_type) == TRUE) {
|
|
1482
|
+
// determine size of buffer we need to allocate
|
|
1483
|
+
elem_len = element_length_in_bytes(self);
|
|
1484
|
+
data_buf = (uint8_t *) malloc(elem_len + 1);
|
|
1485
|
+
memset(data_buf, 0, elem_len);
|
|
1486
|
+
if(data_buf == NULL) {
|
|
1487
|
+
PyErr_SetString(ElementError, "out of memory.");
|
|
1488
|
+
return NULL;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
// write to char buffer
|
|
1492
|
+
bytes_written = element_to_bytes(data_buf, self);
|
|
1493
|
+
if(elem_len != bytes_written) {
|
|
1494
|
+
PyErr_SetString(ElementError, "serialization failed. try again.");
|
|
1495
|
+
free(data_buf);
|
|
1496
|
+
return NULL;
|
|
1497
|
+
}
|
|
1498
|
+
debug("result => ");
|
|
1499
|
+
printf_buffer_as_hex(data_buf, bytes_written);
|
|
1500
|
+
}
|
|
1501
|
+
else {
|
|
1502
|
+
PyErr_SetString(ElementError, "invalid type.\n");
|
|
1503
|
+
return NULL;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
PyObject *result = PyBytes_FromFormat("%d:%s", self->element_type, (const char *) data_buf);
|
|
1507
|
+
debug("enc => '%s'\n", data_buf);
|
|
1508
|
+
free(data_buf);
|
|
1509
|
+
|
|
1510
|
+
return result;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
static PyObject *Deserialize_cmp(Element *self, PyObject *args) {
|
|
1514
|
+
Element *origObject = NULL;
|
|
1515
|
+
Pairing *group = NULL;
|
|
1516
|
+
PyObject *object;
|
|
1517
|
+
|
|
1518
|
+
if(PyArg_ParseTuple(args, "OO", &group, &object)) {
|
|
1519
|
+
VERIFY_GROUP(group);
|
|
1520
|
+
if(PyBytes_Check(object)) {
|
|
1521
|
+
uint8_t *serial_buf = (uint8_t *) PyBytes_AsString(object);
|
|
1522
|
+
int type = atoi((const char *) &(serial_buf[0]));
|
|
1523
|
+
uint8_t *base64_buf = (uint8_t *)(serial_buf + 2);
|
|
1524
|
+
// printf("type => %d\n", type);
|
|
1525
|
+
// printf("base64 dec => '%s'\n", base64_buf);
|
|
1526
|
+
|
|
1527
|
+
if(check_type(type) == TRUE && strlen((char *) base64_buf) > 0) {
|
|
1528
|
+
// debug("result => ");
|
|
1529
|
+
// printf_buffer_as_hex(binary_buf, deserialized_len);
|
|
1530
|
+
origObject = createNewElement(NONE_G, group);
|
|
1531
|
+
origObject->element_type = type;
|
|
1532
|
+
element_from_bytes(origObject, base64_buf);
|
|
1533
|
+
|
|
1534
|
+
return (PyObject *) origObject;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
PyErr_SetString(ElementError, "string object malformed.");
|
|
1538
|
+
return NULL;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
PyErr_SetString(ElementError, "nothing to deserialize in element.");
|
|
1542
|
+
return NULL;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
static PyObject *Group_Check(Element *self, PyObject *args) {
|
|
1546
|
+
|
|
1547
|
+
Pairing *group = NULL;
|
|
1548
|
+
Element *object = NULL;
|
|
1549
|
+
if(PyArg_ParseTuple(args, "OO", &group, &object)) {
|
|
1550
|
+
VERIFY_GROUP(group);
|
|
1551
|
+
if(PyElement_Check(object)) {
|
|
1552
|
+
if(check_membership(object) == TRUE) {
|
|
1553
|
+
Py_INCREF(Py_True);
|
|
1554
|
+
return Py_True;
|
|
1555
|
+
}
|
|
1556
|
+
else {
|
|
1557
|
+
Py_INCREF(Py_False);
|
|
1558
|
+
return Py_False;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
PyErr_SetString(ElementError, "invalid object type.");
|
|
1564
|
+
return NULL;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
static PyObject *Get_Order(Element *self, PyObject *args) {
|
|
1568
|
+
|
|
1569
|
+
Pairing *group = NULL;
|
|
1570
|
+
if(!PyArg_ParseTuple(args, "O", &group)) {
|
|
1571
|
+
PyErr_SetString(ElementError, "invalid group object.");
|
|
1572
|
+
return NULL;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
VERIFY_GROUP(group);
|
|
1576
|
+
mpz_t d;
|
|
1577
|
+
mpz_init(d);
|
|
1578
|
+
object_to_mpz(group->order, d);
|
|
1579
|
+
PyObject *object = (PyObject *) mpzToLongObj(d);
|
|
1580
|
+
mpz_clear(d);
|
|
1581
|
+
return object; /* returns a PyInt */
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
/* TODO: move to cryptobase */
|
|
1585
|
+
PyObject *AES_Encrypt(Element *self, PyObject *args)
|
|
1586
|
+
{
|
|
1587
|
+
PyObject *keyObj = NULL, *tmp_obj = NULL; // string or bytes object
|
|
1588
|
+
char *messageStr;
|
|
1589
|
+
Py_ssize_t m_len = 0;
|
|
1590
|
+
|
|
1591
|
+
if(!PyArg_ParseTuple(args, "Os#", &keyObj, &messageStr, &m_len)) {
|
|
1592
|
+
PyErr_SetString(ElementError, "invalid arguments.");
|
|
1593
|
+
return NULL;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
if((m_len % aes_block_size) != 0) {
|
|
1597
|
+
PyErr_SetString(ElementError, "message not 16-byte block aligned. Add some padding.");
|
|
1598
|
+
return NULL;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
char *keyStr;
|
|
1602
|
+
if(PyBytes_CharmCheck(keyObj)) {
|
|
1603
|
+
PyBytes_ToString2(keyStr, keyObj, tmp_obj);
|
|
1604
|
+
//printf("key => '%s'\n", keyStr);
|
|
1605
|
+
//printf("message => '%s'\n", messageStr);
|
|
1606
|
+
// perform AES encryption using miracl
|
|
1607
|
+
char *cipher = NULL;
|
|
1608
|
+
|
|
1609
|
+
int c_len = aes_encrypt(keyStr, messageStr, (int) m_len, &cipher);
|
|
1610
|
+
|
|
1611
|
+
PyObject *str = PyBytes_FromStringAndSize((const char *) cipher, c_len);
|
|
1612
|
+
free(cipher);
|
|
1613
|
+
if(tmp_obj != NULL) Py_DECREF(tmp_obj);
|
|
1614
|
+
return str;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
PyErr_SetString(ElementError, "invalid objects.");
|
|
1618
|
+
return NULL;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
PyObject *AES_Decrypt(Element *self, PyObject *args)
|
|
1622
|
+
{
|
|
1623
|
+
PyObject *keyObj = NULL, *tmp_obj = NULL; // string or bytes object
|
|
1624
|
+
char *ciphertextStr;
|
|
1625
|
+
Py_ssize_t c_len = 0;
|
|
1626
|
+
|
|
1627
|
+
if(!PyArg_ParseTuple(args, "Os#", &keyObj, &ciphertextStr, &c_len)) {
|
|
1628
|
+
PyErr_SetString(ElementError, "invalid arguments.");
|
|
1629
|
+
return NULL;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
char *keyStr;
|
|
1633
|
+
if(PyBytes_CharmCheck(keyObj)) {
|
|
1634
|
+
PyBytes_ToString2(keyStr, keyObj, tmp_obj);
|
|
1635
|
+
// printf("key => '%s'\n", keyStr);
|
|
1636
|
+
// printf("message => '%s'\n", ciphertextStr);
|
|
1637
|
+
// perform AES encryption using miracl
|
|
1638
|
+
char *message = NULL;
|
|
1639
|
+
|
|
1640
|
+
int m_len = aes_decrypt(keyStr, ciphertextStr, (int) c_len, &message);
|
|
1641
|
+
|
|
1642
|
+
PyObject *str = PyBytes_FromStringAndSize((const char *) message, m_len);
|
|
1643
|
+
free(message);
|
|
1644
|
+
if(tmp_obj != NULL) Py_DECREF(tmp_obj);
|
|
1645
|
+
return str;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
PyErr_SetString(ElementError, "invalid objects.");
|
|
1649
|
+
return NULL;
|
|
1650
|
+
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
#ifdef BENCHMARK_ENABLED
|
|
1654
|
+
|
|
1655
|
+
#define BenchmarkIdentifier 1
|
|
1656
|
+
#define GET_RESULTS_FUNC GetResultsWithPair
|
|
1657
|
+
#define GROUP_OBJECT Pairing
|
|
1658
|
+
#define BENCH_ERROR ElementError
|
|
1659
|
+
/* helper function for granularBenchmar */
|
|
1660
|
+
PyObject *PyCreateList(Operations *gBench, MeasureType type)
|
|
1661
|
+
{
|
|
1662
|
+
int countZR = -1, countG1 = -1, countG2 = -1, countGT = -1;
|
|
1663
|
+
GetField(countZR, type, pyZR_t, gBench);
|
|
1664
|
+
GetField(countG1, type, pyG1_t, gBench);
|
|
1665
|
+
GetField(countG2, type, pyG2_t, gBench);
|
|
1666
|
+
GetField(countGT, type, pyGT_t, gBench);
|
|
1667
|
+
|
|
1668
|
+
PyObject *objList = Py_BuildValue("[iiii]", countZR, countG1, countG2, countGT);
|
|
1669
|
+
return objList;
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
#include "benchmark_util.c"
|
|
1673
|
+
|
|
1674
|
+
#endif
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1678
|
+
|
|
1679
|
+
PyTypeObject PairingType = {
|
|
1680
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
1681
|
+
"pairing.Pairing", /*tp_name*/
|
|
1682
|
+
sizeof(Pairing), /*tp_basicsize*/
|
|
1683
|
+
0, /*tp_itemsize*/
|
|
1684
|
+
(destructor)Pairing_dealloc, /*tp_dealloc*/
|
|
1685
|
+
0, /*tp_print*/
|
|
1686
|
+
0, /*tp_getattr*/
|
|
1687
|
+
0, /*tp_setattr*/
|
|
1688
|
+
0, /*tp_reserved*/
|
|
1689
|
+
(reprfunc)Pairing_print, /*tp_repr*/
|
|
1690
|
+
0, /*tp_as_number*/
|
|
1691
|
+
0, /*tp_as_sequence*/
|
|
1692
|
+
0, /*tp_as_mapping*/
|
|
1693
|
+
0, /*tp_hash */
|
|
1694
|
+
0, /*tp_call*/
|
|
1695
|
+
(reprfunc)Pairing_print, /*tp_str*/
|
|
1696
|
+
0, /*tp_getattro*/
|
|
1697
|
+
0, /*tp_setattro*/
|
|
1698
|
+
0, /*tp_as_buffer*/
|
|
1699
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
1700
|
+
"Pairing group parameters", /* tp_doc */
|
|
1701
|
+
0, /* tp_traverse */
|
|
1702
|
+
0, /* tp_clear */
|
|
1703
|
+
0, /* tp_richcompare */
|
|
1704
|
+
0, /* tp_weaklistoffset */
|
|
1705
|
+
0, /* tp_iter */
|
|
1706
|
+
0, /* tp_iternext */
|
|
1707
|
+
0, /* tp_methods */
|
|
1708
|
+
0, /* tp_members */
|
|
1709
|
+
0, /* tp_getset */
|
|
1710
|
+
0, /* tp_base */
|
|
1711
|
+
0, /* tp_dict */
|
|
1712
|
+
0, /* tp_descr_get */
|
|
1713
|
+
0, /* tp_descr_set */
|
|
1714
|
+
0, /* tp_dictoffset */
|
|
1715
|
+
(initproc)Pairing_init, /* tp_init */
|
|
1716
|
+
0, /* tp_alloc */
|
|
1717
|
+
Pairing_new, /* tp_new */
|
|
1718
|
+
};
|
|
1719
|
+
#else
|
|
1720
|
+
/* python 2.x series */
|
|
1721
|
+
PyTypeObject PairingType = {
|
|
1722
|
+
PyObject_HEAD_INIT(NULL)
|
|
1723
|
+
0, /*ob_size*/
|
|
1724
|
+
"pairing.Pairing", /*tp_name*/
|
|
1725
|
+
sizeof(Pairing), /*tp_basicsize*/
|
|
1726
|
+
0, /*tp_itemsize*/
|
|
1727
|
+
(destructor)Pairing_dealloc, /*tp_dealloc*/
|
|
1728
|
+
0, /*tp_print*/
|
|
1729
|
+
0, /*tp_getattr*/
|
|
1730
|
+
0, /*tp_setattr*/
|
|
1731
|
+
0, /*tp_compare*/
|
|
1732
|
+
(reprfunc)Pairing_print, /*tp_repr*/
|
|
1733
|
+
0, /*tp_as_number*/
|
|
1734
|
+
0, /*tp_as_sequence*/
|
|
1735
|
+
0, /*tp_as_mapping*/
|
|
1736
|
+
0, /*tp_hash */
|
|
1737
|
+
0, /*tp_call*/
|
|
1738
|
+
(reprfunc)Pairing_print, /*tp_str*/
|
|
1739
|
+
0, /*tp_getattro*/
|
|
1740
|
+
0, /*tp_setattro*/
|
|
1741
|
+
0, /*tp_as_buffer*/
|
|
1742
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
1743
|
+
"Pairing group parameters", /* tp_doc */
|
|
1744
|
+
0, /* tp_traverse */
|
|
1745
|
+
0, /* tp_clear */
|
|
1746
|
+
0, /* tp_richcompare */
|
|
1747
|
+
0, /* tp_weaklistoffset */
|
|
1748
|
+
0, /* tp_iter */
|
|
1749
|
+
0, /* tp_iternext */
|
|
1750
|
+
0, /* tp_methods */
|
|
1751
|
+
0, /* tp_members */
|
|
1752
|
+
0, /* tp_getset */
|
|
1753
|
+
0, /* tp_base */
|
|
1754
|
+
0, /* tp_dict */
|
|
1755
|
+
0, /* tp_descr_get */
|
|
1756
|
+
0, /* tp_descr_set */
|
|
1757
|
+
0, /* tp_dictoffset */
|
|
1758
|
+
(initproc) Pairing_init, /* tp_init */
|
|
1759
|
+
0, /* tp_alloc */
|
|
1760
|
+
Pairing_new, /* tp_new */
|
|
1761
|
+
};
|
|
1762
|
+
|
|
1763
|
+
#endif
|
|
1764
|
+
|
|
1765
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1766
|
+
PyNumberMethods element_number = {
|
|
1767
|
+
instance_add, /* nb_add */
|
|
1768
|
+
instance_sub, /* nb_subtract */
|
|
1769
|
+
Element_mul, /* nb_multiply */
|
|
1770
|
+
0, /* nb_remainder */
|
|
1771
|
+
0, /* nb_divmod */
|
|
1772
|
+
Element_pow, /* nb_power */
|
|
1773
|
+
instance_negate, /* nb_negative */
|
|
1774
|
+
0, /* nb_positive */
|
|
1775
|
+
0, /* nb_absolute */
|
|
1776
|
+
0, /* nb_bool */
|
|
1777
|
+
(unaryfunc)instance_invert, /* nb_invert */
|
|
1778
|
+
0, /* nb_lshift */
|
|
1779
|
+
0, /* nb_rshift */
|
|
1780
|
+
0, /* nb_and */
|
|
1781
|
+
0, /* nb_xor */
|
|
1782
|
+
0, /* nb_or */
|
|
1783
|
+
(unaryfunc)Element_long, /* nb_int */
|
|
1784
|
+
0, /* nb_reserved */
|
|
1785
|
+
0, /* nb_float */
|
|
1786
|
+
instance_add, /* nb_inplace_add */
|
|
1787
|
+
instance_sub, /* nb_inplace_subtract */
|
|
1788
|
+
Element_mul, /* nb_inplace_multiply */
|
|
1789
|
+
0, /* nb_inplace_remainder */
|
|
1790
|
+
Element_pow, /* nb_inplace_power */
|
|
1791
|
+
0, /* nb_inplace_lshift */
|
|
1792
|
+
0, /* nb_inplace_rshift */
|
|
1793
|
+
0, /* nb_inplace_and */
|
|
1794
|
+
0, /* nb_inplace_xor */
|
|
1795
|
+
0, /* nb_inplace_or */
|
|
1796
|
+
0, /* nb_floor_divide */
|
|
1797
|
+
Element_div, /* nb_true_divide */
|
|
1798
|
+
0, /* nb_inplace_floor_divide */
|
|
1799
|
+
Element_div, /* nb_inplace_true_divide */
|
|
1800
|
+
0, /* nb_index */
|
|
1801
|
+
};
|
|
1802
|
+
|
|
1803
|
+
PyTypeObject ElementType = {
|
|
1804
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
1805
|
+
"pairing.Element", /*tp_name*/
|
|
1806
|
+
sizeof(Element), /*tp_basicsize*/
|
|
1807
|
+
0, /*tp_itemsize*/
|
|
1808
|
+
(destructor)Element_dealloc, /*tp_dealloc*/
|
|
1809
|
+
0, /*tp_print*/
|
|
1810
|
+
0, /*tp_getattr*/
|
|
1811
|
+
0, /*tp_setattr*/
|
|
1812
|
+
0, /*tp_reserved*/
|
|
1813
|
+
(reprfunc)Element_print, /*tp_repr*/
|
|
1814
|
+
&element_number, /*tp_as_number*/
|
|
1815
|
+
0, /*tp_as_sequence*/
|
|
1816
|
+
0, /*tp_as_mapping*/
|
|
1817
|
+
(hashfunc)Element_index, /*tp_hash */
|
|
1818
|
+
0, /*tp_call*/
|
|
1819
|
+
0, /*tp_str*/
|
|
1820
|
+
0, /*tp_getattro*/
|
|
1821
|
+
0, /*tp_setattro*/
|
|
1822
|
+
0, /*tp_as_buffer*/
|
|
1823
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
1824
|
+
"Pairing objects", /* tp_doc */
|
|
1825
|
+
0, /* tp_traverse */
|
|
1826
|
+
0, /* tp_clear */
|
|
1827
|
+
Element_equals, /* tp_richcompare */
|
|
1828
|
+
0, /* tp_weaklistoffset */
|
|
1829
|
+
0, /* tp_iter */
|
|
1830
|
+
0, /* tp_iternext */
|
|
1831
|
+
Element_methods, /* tp_methods */
|
|
1832
|
+
Element_members, /* tp_members */
|
|
1833
|
+
0, /* tp_getset */
|
|
1834
|
+
0, /* tp_base */
|
|
1835
|
+
0, /* tp_dict */
|
|
1836
|
+
0, /* tp_descr_get */
|
|
1837
|
+
0, /* tp_descr_set */
|
|
1838
|
+
0, /* tp_dictoffset */
|
|
1839
|
+
(initproc)Element_init, /* tp_init */
|
|
1840
|
+
0, /* tp_alloc */
|
|
1841
|
+
Element_new, /* tp_new */
|
|
1842
|
+
};
|
|
1843
|
+
#else
|
|
1844
|
+
/* python 2.x series */
|
|
1845
|
+
PyNumberMethods element_number = {
|
|
1846
|
+
instance_add, /* nb_add */
|
|
1847
|
+
instance_sub, /* nb_subtract */
|
|
1848
|
+
Element_mul, /* nb_multiply */
|
|
1849
|
+
Element_div, /* nb_divide */
|
|
1850
|
+
0, /* nb_remainder */
|
|
1851
|
+
0, /* nb_divmod */
|
|
1852
|
+
Element_pow, /* nb_power */
|
|
1853
|
+
instance_negate, /* nb_negative */
|
|
1854
|
+
0, /* nb_positive */
|
|
1855
|
+
0, /* nb_absolute */
|
|
1856
|
+
0, /* nb_nonzero */
|
|
1857
|
+
(unaryfunc)instance_invert, /* nb_invert */
|
|
1858
|
+
0, /* nb_lshift */
|
|
1859
|
+
0, /* nb_rshift */
|
|
1860
|
+
0, /* nb_and */
|
|
1861
|
+
0, /* nb_xor */
|
|
1862
|
+
0, /* nb_or */
|
|
1863
|
+
0, /* nb_coerce */
|
|
1864
|
+
0, /* nb_int */
|
|
1865
|
+
(unaryfunc)Element_long, /* nb_long */
|
|
1866
|
+
0, /* nb_float */
|
|
1867
|
+
0, /* nb_oct */
|
|
1868
|
+
0, /* nb_hex */
|
|
1869
|
+
instance_add, /* nb_inplace_add */
|
|
1870
|
+
instance_sub, /* nb_inplace_subtract */
|
|
1871
|
+
Element_mul, /* nb_inplace_multiply */
|
|
1872
|
+
Element_div, /* nb_inplace_divide */
|
|
1873
|
+
0, /* nb_inplace_remainder */
|
|
1874
|
+
0, /* nb_inplace_power */
|
|
1875
|
+
0, /* nb_inplace_lshift */
|
|
1876
|
+
0, /* nb_inplace_rshift */
|
|
1877
|
+
0, /* nb_inplace_and */
|
|
1878
|
+
0, /* nb_inplace_xor */
|
|
1879
|
+
0, /* nb_inplace_or */
|
|
1880
|
+
0, /* nb_floor_divide */
|
|
1881
|
+
0, /* nb_true_divide */
|
|
1882
|
+
0, /* nb_inplace_floor_divide */
|
|
1883
|
+
0, /* nb_inplace_true_divide */
|
|
1884
|
+
0, /* nb_index */
|
|
1885
|
+
};
|
|
1886
|
+
|
|
1887
|
+
PyTypeObject ElementType = {
|
|
1888
|
+
PyObject_HEAD_INIT(NULL)
|
|
1889
|
+
0, /*ob_size*/
|
|
1890
|
+
"pairing.Element", /*tp_name*/
|
|
1891
|
+
sizeof(Element), /*tp_basicsize*/
|
|
1892
|
+
0, /*tp_itemsize*/
|
|
1893
|
+
(destructor)Element_dealloc, /*tp_dealloc*/
|
|
1894
|
+
0, /*tp_print*/
|
|
1895
|
+
0, /*tp_getattr*/
|
|
1896
|
+
0, /*tp_setattr*/
|
|
1897
|
+
0, /*tp_compare*/
|
|
1898
|
+
0, /*tp_repr*/
|
|
1899
|
+
&element_number, /*tp_as_number*/
|
|
1900
|
+
0, /*tp_as_sequence*/
|
|
1901
|
+
0, /*tp_as_mapping*/
|
|
1902
|
+
(hashfunc)Element_index, /*tp_hash */
|
|
1903
|
+
0, /*tp_call*/
|
|
1904
|
+
(reprfunc)Element_print, /*tp_str*/
|
|
1905
|
+
0, /*tp_getattro*/
|
|
1906
|
+
0, /*tp_setattro*/
|
|
1907
|
+
0, /*tp_as_buffer*/
|
|
1908
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
|
1909
|
+
"Pairing objects", /* tp_doc */
|
|
1910
|
+
0, /* tp_traverse */
|
|
1911
|
+
0, /* tp_clear */
|
|
1912
|
+
Element_equals, /* tp_richcompare */
|
|
1913
|
+
0, /* tp_weaklistoffset */
|
|
1914
|
+
0, /* tp_iter */
|
|
1915
|
+
0, /* tp_iternext */
|
|
1916
|
+
Element_methods, /* tp_methods */
|
|
1917
|
+
Element_members, /* tp_members */
|
|
1918
|
+
0, /* tp_getset */
|
|
1919
|
+
0, /* tp_base */
|
|
1920
|
+
0, /* tp_dict */
|
|
1921
|
+
0, /* tp_descr_get */
|
|
1922
|
+
0, /* tp_descr_set */
|
|
1923
|
+
0, /* tp_dictoffset */
|
|
1924
|
+
(initproc) Element_init, /* tp_init */
|
|
1925
|
+
0, /* tp_alloc */
|
|
1926
|
+
Element_new, /* tp_new */
|
|
1927
|
+
};
|
|
1928
|
+
|
|
1929
|
+
#endif
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
struct module_state {
|
|
1933
|
+
PyObject *error;
|
|
1934
|
+
#ifdef BENCHMARK_ENABLED
|
|
1935
|
+
Benchmark *dBench;
|
|
1936
|
+
#endif
|
|
1937
|
+
};
|
|
1938
|
+
|
|
1939
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1940
|
+
#define GETSTATE(m) ((struct module_state *) PyModule_GetState(m))
|
|
1941
|
+
#else
|
|
1942
|
+
#define GETSTATE(m) (&_state)
|
|
1943
|
+
static struct module_state _state;
|
|
1944
|
+
#endif
|
|
1945
|
+
|
|
1946
|
+
// end
|
|
1947
|
+
PyMemberDef Element_members[] = {
|
|
1948
|
+
{"type", T_INT, offsetof(Element, element_type), 0,
|
|
1949
|
+
"group type"},
|
|
1950
|
+
{"initialized", T_INT, offsetof(Element, elem_initialized), 0,
|
|
1951
|
+
"determine initialization status"},
|
|
1952
|
+
{NULL} /* Sentinel */
|
|
1953
|
+
};
|
|
1954
|
+
|
|
1955
|
+
PyMethodDef Element_methods[] = {
|
|
1956
|
+
{"initPP", (PyCFunction)Element_initPP, METH_NOARGS, "Initialize the pre-processing field of element."},
|
|
1957
|
+
{"set", (PyCFunction)Element_set, METH_VARARGS, "Set an element to a fixed value."},
|
|
1958
|
+
{"setPoint", (PyCFunction)Element_setxy, METH_VARARGS, "Set x and y coordinates of a G1 element object."},
|
|
1959
|
+
{NULL} /* Sentinel */
|
|
1960
|
+
};
|
|
1961
|
+
|
|
1962
|
+
PyMethodDef pairing_methods[] = {
|
|
1963
|
+
{"init", (PyCFunction)Element_elem, METH_VARARGS, "Create an element in a specific group: G1, G2, GT or Zr"},
|
|
1964
|
+
{"random", (PyCFunction)Element_random, METH_VARARGS, "Return a random element in a specific group: G1_t, G2, Zr"},
|
|
1965
|
+
{"H", (PyCFunction)Element_hash, METH_VARARGS, "Hash an element type to a specific field: Zr, G1_t, or G2"},
|
|
1966
|
+
{"serialize", (PyCFunction)Serialize_cmp, METH_VARARGS, "Serialize an element type into bytes."},
|
|
1967
|
+
{"deserialize", (PyCFunction)Deserialize_cmp, METH_VARARGS, "De-serialize an bytes object into an element object"},
|
|
1968
|
+
{"ismember", (PyCFunction) Group_Check, METH_VARARGS, "Group membership test for element objects."},
|
|
1969
|
+
{"order", (PyCFunction) Get_Order, METH_VARARGS, "Get the group order for a particular field."},
|
|
1970
|
+
|
|
1971
|
+
{"pair", (PyCFunction)Apply_pairing, METH_VARARGS, "Apply pairing between an element of G1_t and G2 and returns an element mapped to GT"},
|
|
1972
|
+
{"hashPair", (PyCFunction)sha2_hash, METH_VARARGS, "Compute a sha1 hash of an element type"},
|
|
1973
|
+
// {"SymEnc", (PyCFunction) AES_Encrypt, METH_VARARGS, "AES encryption args: key (bytes or str), message (str)"},
|
|
1974
|
+
// {"SymDec", (PyCFunction) AES_Decrypt, METH_VARARGS, "AES decryption args: key (bytes or str), ciphertext (str)"},
|
|
1975
|
+
#ifdef BENCHMARK_ENABLED
|
|
1976
|
+
{"InitBenchmark", (PyCFunction)InitBenchmark, METH_VARARGS, "Initialize a benchmark object"},
|
|
1977
|
+
{"StartBenchmark", (PyCFunction)StartBenchmark, METH_VARARGS, "Start a new benchmark with some options"},
|
|
1978
|
+
{"EndBenchmark", (PyCFunction)EndBenchmark, METH_VARARGS, "End a given benchmark"},
|
|
1979
|
+
{"GetBenchmark", (PyCFunction)GetBenchmark, METH_VARARGS, "Returns contents of a benchmark object"},
|
|
1980
|
+
{"GetGeneralBenchmarks", (PyCFunction)GetAllBenchmarks, METH_VARARGS, "Retrieve general benchmark info as a dictionary"},
|
|
1981
|
+
{"GetGranularBenchmarks", (PyCFunction) GranularBenchmark, METH_VARARGS, "Retrieve granular benchmarks as a dictionary"},
|
|
1982
|
+
#endif
|
|
1983
|
+
{NULL} /* Sentinel */
|
|
1984
|
+
};
|
|
1985
|
+
|
|
1986
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1987
|
+
static int pairings_traverse(PyObject *m, visitproc visit, void *arg) {
|
|
1988
|
+
Py_VISIT(GETSTATE(m)->error);
|
|
1989
|
+
return 0;
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
static int pairings_clear(PyObject *m) {
|
|
1993
|
+
Py_CLEAR(GETSTATE(m)->error);
|
|
1994
|
+
Py_XDECREF(ElementError);
|
|
1995
|
+
return 0;
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
static int pairings_free(PyObject *m) {
|
|
1999
|
+
// Defensive check: Only call miracl_clean if module state is valid
|
|
2000
|
+
// This prevents hangs during Python 3.12+ shutdown when module state
|
|
2001
|
+
// may be corrupted or already cleaned up
|
|
2002
|
+
if(m != NULL && pairing_init_finished == FALSE) {
|
|
2003
|
+
// Additional safety: Check if we're in a valid state to clean up
|
|
2004
|
+
// Avoid calling miracl_clean() if Python is shutting down abnormally
|
|
2005
|
+
if(!CHARM_PY_IS_FINALIZING()) {
|
|
2006
|
+
miracl_clean(); // mirsys was called
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
return 0;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
static struct PyModuleDef moduledef = {
|
|
2013
|
+
PyModuleDef_HEAD_INIT,
|
|
2014
|
+
"pairing",
|
|
2015
|
+
NULL,
|
|
2016
|
+
sizeof(struct module_state),
|
|
2017
|
+
pairing_methods,
|
|
2018
|
+
NULL,
|
|
2019
|
+
pairings_traverse,
|
|
2020
|
+
(inquiry) pairings_clear,
|
|
2021
|
+
(freefunc) pairings_free
|
|
2022
|
+
};
|
|
2023
|
+
|
|
2024
|
+
#define CLEAN_EXIT goto LEAVE;
|
|
2025
|
+
#define INITERROR return NULL
|
|
2026
|
+
PyMODINIT_FUNC
|
|
2027
|
+
PyInit_pairing(void) {
|
|
2028
|
+
#else
|
|
2029
|
+
#define CLEAN_EXIT goto LEAVE;
|
|
2030
|
+
#define INITERROR return
|
|
2031
|
+
void initpairing(void) {
|
|
2032
|
+
#endif
|
|
2033
|
+
PyObject* m;
|
|
2034
|
+
|
|
2035
|
+
#if PY_MAJOR_VERSION >= 3
|
|
2036
|
+
m = PyModule_Create(&moduledef);
|
|
2037
|
+
#else
|
|
2038
|
+
m = Py_InitModule("pairing", pairing_methods);
|
|
2039
|
+
#endif
|
|
2040
|
+
|
|
2041
|
+
if(PyType_Ready(&PairingType) < 0)
|
|
2042
|
+
CLEAN_EXIT;
|
|
2043
|
+
if(PyType_Ready(&ElementType) < 0)
|
|
2044
|
+
CLEAN_EXIT;
|
|
2045
|
+
#ifdef BENCHMARK_ENABLED
|
|
2046
|
+
if(import_benchmark() < 0)
|
|
2047
|
+
CLEAN_EXIT;
|
|
2048
|
+
if(PyType_Ready(&BenchmarkType) < 0)
|
|
2049
|
+
CLEAN_EXIT;
|
|
2050
|
+
if(PyType_Ready(&OperationsType) < 0)
|
|
2051
|
+
CLEAN_EXIT;
|
|
2052
|
+
#endif
|
|
2053
|
+
|
|
2054
|
+
struct module_state *st = GETSTATE(m);
|
|
2055
|
+
st->error = PyErr_NewException("pairing.Error", NULL, NULL);
|
|
2056
|
+
if(st->error == NULL)
|
|
2057
|
+
CLEAN_EXIT;
|
|
2058
|
+
ElementError = st->error;
|
|
2059
|
+
Py_INCREF(ElementError);
|
|
2060
|
+
|
|
2061
|
+
Py_INCREF(&ElementType);
|
|
2062
|
+
PyModule_AddObject(m, "pc_element", (PyObject *)&ElementType);
|
|
2063
|
+
Py_INCREF(&PairingType);
|
|
2064
|
+
PyModule_AddObject(m, "pairing", (PyObject *)&PairingType);
|
|
2065
|
+
|
|
2066
|
+
PyModule_AddIntConstant(m, "ZR", pyZR_t);
|
|
2067
|
+
PyModule_AddIntConstant(m, "G1", pyG1_t);
|
|
2068
|
+
PyModule_AddIntConstant(m, "G2", pyG2_t);
|
|
2069
|
+
PyModule_AddIntConstant(m, "GT", pyGT_t);
|
|
2070
|
+
|
|
2071
|
+
#ifdef BENCHMARK_ENABLED
|
|
2072
|
+
ADD_BENCHMARK_OPTIONS(m);
|
|
2073
|
+
PyModule_AddStringConstant(m, "Pair", _PAIR_OPT);
|
|
2074
|
+
PyModule_AddStringConstant(m, "Granular", _GRAN_OPT);
|
|
2075
|
+
#endif
|
|
2076
|
+
|
|
2077
|
+
// builtin curves
|
|
2078
|
+
PyModule_AddIntConstant(m, "MNT160", MNT160);
|
|
2079
|
+
PyModule_AddIntConstant(m, "BN256", BN256);
|
|
2080
|
+
PyModule_AddIntConstant(m, "SS512", SS512);
|
|
2081
|
+
PyModule_AddIntConstant(m, "SS1536", SS1536);
|
|
2082
|
+
|
|
2083
|
+
LEAVE:
|
|
2084
|
+
if (PyErr_Occurred()) {
|
|
2085
|
+
PyErr_Clear();
|
|
2086
|
+
Py_XDECREF(m);
|
|
2087
|
+
INITERROR;
|
|
2088
|
+
}
|
|
2089
|
+
pairing_init_finished = TRUE;
|
|
2090
|
+
|
|
2091
|
+
#if PY_MAJOR_VERSION >= 3
|
|
2092
|
+
return m;
|
|
2093
|
+
#endif
|
|
2094
|
+
}
|