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