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,1853 @@
|
|
|
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 pairingmodule3.c
|
|
23
|
+
*
|
|
24
|
+
* @brief charm interface over RELIC's pairing-based crypto module
|
|
25
|
+
*
|
|
26
|
+
* @author jakinye3@jhu.edu
|
|
27
|
+
*
|
|
28
|
+
************************************************************************/
|
|
29
|
+
|
|
30
|
+
#include "pairingmodule3.h"
|
|
31
|
+
|
|
32
|
+
int exp_rule(GroupType lhs, GroupType rhs)
|
|
33
|
+
{
|
|
34
|
+
if(lhs == ZR && rhs == ZR) return TRUE;
|
|
35
|
+
if(lhs == G1 && rhs == ZR) return TRUE;
|
|
36
|
+
if(lhs == G2 && rhs == ZR) return TRUE;
|
|
37
|
+
if(lhs == GT && rhs == ZR) return TRUE;
|
|
38
|
+
return FALSE; /* Fail all other cases */
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
int mul_rule(GroupType lhs, GroupType rhs)
|
|
42
|
+
{
|
|
43
|
+
if(lhs == rhs) return TRUE;
|
|
44
|
+
if(lhs == ZR || rhs == ZR) return TRUE;
|
|
45
|
+
return FALSE; /* Fail all other cases */
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
int add_rule(GroupType lhs, GroupType rhs)
|
|
49
|
+
{
|
|
50
|
+
if(lhs == rhs && lhs != GT) return TRUE;
|
|
51
|
+
return FALSE; /* Fail all other cases */
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
int sub_rule(GroupType lhs, GroupType rhs)
|
|
55
|
+
{
|
|
56
|
+
if(lhs == rhs && lhs != GT) return TRUE;
|
|
57
|
+
return FALSE; /* Fail all other cases */
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
int div_rule(GroupType lhs, GroupType rhs)
|
|
61
|
+
{
|
|
62
|
+
if(lhs == rhs) return TRUE;
|
|
63
|
+
return FALSE; /* Fail all other cases */
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
int pair_rule(GroupType lhs, GroupType rhs)
|
|
67
|
+
{
|
|
68
|
+
if(lhs == G1 && rhs == G2) return TRUE;
|
|
69
|
+
else if(lhs == G2 && rhs == G1) return TRUE;
|
|
70
|
+
return FALSE; /* Fall all other cases: only for MNT case */
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
int check_type(GroupType type) {
|
|
74
|
+
if(type == ZR || type == G1 || type == G2 || type == GT) return TRUE;
|
|
75
|
+
return FALSE;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#define ERROR_TYPE(operand, ...) "unsupported "#operand" operand types: "#__VA_ARGS__
|
|
79
|
+
|
|
80
|
+
#define UNARY(f, m, n) \
|
|
81
|
+
static PyObject *f(PyObject *v) { \
|
|
82
|
+
if(PyElement_Check(v)) { \
|
|
83
|
+
Element *obj1 = (Element *) v; \
|
|
84
|
+
return (n)(obj1); \
|
|
85
|
+
} return NULL; \
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#define BINARY(f, m, n) \
|
|
89
|
+
static PyObject *f(PyObject *v, PyObject *w) { \
|
|
90
|
+
Element *obj1 = NULL, *obj2 = NULL; \
|
|
91
|
+
int obj1_long = FALSE, obj2_long = FALSE; \
|
|
92
|
+
debug("Performing the '%s' operation.\n", __func__); \
|
|
93
|
+
if(PyElement_Check(v)) { \
|
|
94
|
+
obj1 = (Element *) v; } \
|
|
95
|
+
else if(PyNumber_Check(v)) { obj1 = convertToZR(v, w); obj1_long = TRUE; } \
|
|
96
|
+
else { PyErr_SetString(ElementError, ERROR_TYPE(left, int,bytes,str)); \
|
|
97
|
+
return NULL; } \
|
|
98
|
+
if(PyElement_Check(w)) { \
|
|
99
|
+
obj2 = (Element *) w; } \
|
|
100
|
+
else if(PyNumber_Check(w)) { obj2 = convertToZR(w, v); obj2_long = TRUE; } \
|
|
101
|
+
else { PyErr_SetString(ElementError, ERROR_TYPE(right, int,bytes,str)); \
|
|
102
|
+
return NULL; } \
|
|
103
|
+
if(Check_Types(obj1->element_type, obj2->element_type, m)) { \
|
|
104
|
+
PyObject *obj3 = (n)(obj1, obj2); \
|
|
105
|
+
if(obj1_long) Py_XDECREF(obj1); \
|
|
106
|
+
if(obj2_long) Py_XDECREF(obj2); \
|
|
107
|
+
return obj3; } \
|
|
108
|
+
return NULL; \
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
PyObject *intToLongObj(integer_t x)
|
|
112
|
+
{
|
|
113
|
+
/* borrowed from gmpy */
|
|
114
|
+
int size, isNeg = (bn_sign(x) == BN_NEG) ? TRUE : FALSE;
|
|
115
|
+
size = bn_size_str(x, 2);
|
|
116
|
+
size = (size + PyLong_SHIFT - 1) / PyLong_SHIFT;
|
|
117
|
+
int i;
|
|
118
|
+
integer_t m;
|
|
119
|
+
dig_t t;
|
|
120
|
+
bn_inits(m);
|
|
121
|
+
PyLongObject *l = _PyLong_New (size);
|
|
122
|
+
if (!l)
|
|
123
|
+
return NULL;
|
|
124
|
+
bn_copy(m, x);
|
|
125
|
+
#ifdef DEBUG
|
|
126
|
+
printf("%s: integer :=> ", __FUNCTION__);
|
|
127
|
+
bn_print(m);
|
|
128
|
+
#endif
|
|
129
|
+
for (i = 0; i < size; i++)
|
|
130
|
+
{
|
|
131
|
+
bn_get_dig(&t, m);
|
|
132
|
+
l->ob_digit[i] = (digit) (((uint32_t) t) & PyLong_MASK);
|
|
133
|
+
bn_rsh(m, m, PyLong_SHIFT);
|
|
134
|
+
#ifdef DEBUG
|
|
135
|
+
printf("%s: integer :=> ", __FUNCTION__);
|
|
136
|
+
bn_print(m);
|
|
137
|
+
#endif
|
|
138
|
+
}
|
|
139
|
+
i = size;
|
|
140
|
+
while ((i > 0) && (l->ob_digit[i - 1] == 0))
|
|
141
|
+
i--;
|
|
142
|
+
if(isNeg) {
|
|
143
|
+
Py_SIZE(l) = -i;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
Py_SIZE(l) = i;
|
|
147
|
+
}
|
|
148
|
+
bn_free(m);
|
|
149
|
+
return (PyObject *) l;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
int longObjToInt(integer_t m, PyLongObject * p)
|
|
153
|
+
{
|
|
154
|
+
int size, i, isNeg = FALSE, tmp = Py_SIZE(p);
|
|
155
|
+
if(m == NULL) return -1;
|
|
156
|
+
integer_t t, t2;
|
|
157
|
+
bn_inits(t);
|
|
158
|
+
bn_inits(t2);
|
|
159
|
+
|
|
160
|
+
if (tmp > 0)
|
|
161
|
+
size = tmp;
|
|
162
|
+
else {
|
|
163
|
+
size = -tmp; // negate size value
|
|
164
|
+
isNeg = TRUE;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
bn_zero(m);
|
|
168
|
+
for (i = 0; i < size; i++)
|
|
169
|
+
{
|
|
170
|
+
bn_set_dig(t, p->ob_digit[i]);
|
|
171
|
+
bn_lsh(t2, t, PyLong_SHIFT * i);
|
|
172
|
+
bn_add(m, m, t2);
|
|
173
|
+
}
|
|
174
|
+
if(isNeg == TRUE) bn_neg(m, m);
|
|
175
|
+
bn_free(t);
|
|
176
|
+
bn_free(t2);
|
|
177
|
+
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
char *convert_buffer_to_hex(uint8_t * data, size_t len)
|
|
183
|
+
{
|
|
184
|
+
size_t i;
|
|
185
|
+
char tmp1[3];
|
|
186
|
+
char *tmp = (char *) malloc(len * 3);
|
|
187
|
+
memset(tmp, 0, len*3 - 1);
|
|
188
|
+
|
|
189
|
+
for (i = 0; i < len; i++) {
|
|
190
|
+
snprintf(tmp1, 3, "%02X ", data[i]);
|
|
191
|
+
strcat(tmp, tmp1);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return tmp;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
void printf_buffer_as_hex(uint8_t * data, size_t len)
|
|
198
|
+
{
|
|
199
|
+
#ifdef DEBUG
|
|
200
|
+
size_t i;
|
|
201
|
+
|
|
202
|
+
for (i = 0; i < len; i++) {
|
|
203
|
+
printf("%02x ", data[i]);
|
|
204
|
+
}
|
|
205
|
+
printf("\n");
|
|
206
|
+
#endif
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
void printf_buffer_as_hex_debug(uint8_t * data, size_t len)
|
|
210
|
+
{
|
|
211
|
+
size_t i;
|
|
212
|
+
|
|
213
|
+
for (i = 0; i < len; i++) {
|
|
214
|
+
printf("%02x ", data[i]);
|
|
215
|
+
}
|
|
216
|
+
printf("\n");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
// simply checks that the elements satisfy the properties for the given
|
|
221
|
+
// binary operation. Whitelist approach: only return TRUE for valid cases, otherwise FALSE
|
|
222
|
+
int Check_Types(GroupType l_type, GroupType r_type, char op)
|
|
223
|
+
{
|
|
224
|
+
switch (op) {
|
|
225
|
+
// Rules: elements must be of the same type, multiplicative operations should be only used for
|
|
226
|
+
// elements in field GT
|
|
227
|
+
case 'a':
|
|
228
|
+
if(l_type == GT || r_type == GT) { return FALSE; }
|
|
229
|
+
break;
|
|
230
|
+
case 's':
|
|
231
|
+
if(l_type == GT || r_type == GT) { return FALSE; }
|
|
232
|
+
break;
|
|
233
|
+
case 'e':
|
|
234
|
+
if(l_type != G1 && r_type != G2) { return FALSE; }
|
|
235
|
+
break;
|
|
236
|
+
case 'p':
|
|
237
|
+
// rule for exponentiation for types
|
|
238
|
+
if(l_type != G1 && l_type != G2 && l_type != GT && l_type != ZR) { return FALSE; }
|
|
239
|
+
break;
|
|
240
|
+
default:
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return TRUE;
|
|
245
|
+
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// assumes that pairing structure has been initialized
|
|
249
|
+
static Element *createNewElement(GroupType element_type, Pairing *pairing) {
|
|
250
|
+
debug("Create an object of type Element\n");
|
|
251
|
+
Element *retObject = PyObject_New(Element, &ElementType);
|
|
252
|
+
// retObject->e = (element_ptr) malloc(sizeof(element_t));
|
|
253
|
+
if(element_type == ZR) {
|
|
254
|
+
element_init_Zr(retObject->e, 0); // , pairing->pair_obj);
|
|
255
|
+
retObject->element_type = ZR;
|
|
256
|
+
}
|
|
257
|
+
else if(element_type == G1) {
|
|
258
|
+
element_init_G1(retObject->e); // , pairing->pair_obj);
|
|
259
|
+
retObject->element_type = G1;
|
|
260
|
+
}
|
|
261
|
+
else if(element_type == G2) {
|
|
262
|
+
element_init_G2(retObject->e); // , pairing->pair_obj);
|
|
263
|
+
retObject->element_type = G2;
|
|
264
|
+
}
|
|
265
|
+
else if(element_type == GT) {
|
|
266
|
+
element_init_GT(retObject->e); // , pairing->pair_obj);
|
|
267
|
+
retObject->element_type = GT;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
retObject->elem_initialized = TRUE;
|
|
271
|
+
retObject->elem_initPP = FALSE;
|
|
272
|
+
retObject->pairing = pairing;
|
|
273
|
+
Py_INCREF(retObject->pairing);
|
|
274
|
+
return retObject;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
Element *convertToZR(PyObject *longObj, PyObject *elemObj) {
|
|
278
|
+
Element *self = (Element *) elemObj;
|
|
279
|
+
Element *new = createNewElement(ZR, self->pairing);
|
|
280
|
+
|
|
281
|
+
integer_t x;
|
|
282
|
+
bn_inits(x);
|
|
283
|
+
ConvertToInt2(x, longObj);
|
|
284
|
+
element_set_int(new->e, x);
|
|
285
|
+
bn_free(x);
|
|
286
|
+
return new;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
void Pairing_dealloc(Pairing *self)
|
|
290
|
+
{
|
|
291
|
+
if(self->group_init == TRUE) {
|
|
292
|
+
debug("Clear pairing => \n");
|
|
293
|
+
pairing_clear();
|
|
294
|
+
}
|
|
295
|
+
#ifdef BENCHMARK_ENABLED
|
|
296
|
+
if(self->dBench != NULL) {
|
|
297
|
+
// PrintPyRef("releasing benchmark object", self->dBench);
|
|
298
|
+
Py_CLEAR(self->dBench);
|
|
299
|
+
if(self->gBench != NULL) {
|
|
300
|
+
// PrintPyRef("releasing operations object", self->gBench);
|
|
301
|
+
Py_CLEAR(self->gBench);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
#endif
|
|
305
|
+
debug("Releasing pairing object!\n");
|
|
306
|
+
Py_TYPE(self)->tp_free((PyObject *) self);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
void Element_dealloc(Element* self)
|
|
310
|
+
{
|
|
311
|
+
if(self->elem_initialized && self->e) {
|
|
312
|
+
debug_e("Clear element_t => \n", self->e);
|
|
313
|
+
if(self->elem_initPP == TRUE) {
|
|
314
|
+
element_pp_clear(self->e_pp, self->element_type);
|
|
315
|
+
}
|
|
316
|
+
element_clear(self->e);
|
|
317
|
+
// Defensive: Use Py_XDECREF instead of Py_DECREF to handle NULL safely
|
|
318
|
+
// and check if pairing object is valid before decrementing
|
|
319
|
+
// This prevents crashes with immortal objects in Python 3.12+ (PEP 683)
|
|
320
|
+
if(self->pairing != NULL) {
|
|
321
|
+
Py_XDECREF(self->pairing);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// helper method
|
|
329
|
+
ssize_t read_file(FILE *f, char** out)
|
|
330
|
+
{
|
|
331
|
+
if(f != NULL) {
|
|
332
|
+
/* See how big the file is */
|
|
333
|
+
fseek(f, 0L, SEEK_END);
|
|
334
|
+
ssize_t out_len = ftell(f);
|
|
335
|
+
debug("out_len: %zd\n", out_len);
|
|
336
|
+
if(out_len <= MAX_LEN) {
|
|
337
|
+
/* allocate that amount of memory only */
|
|
338
|
+
if((*out = (char *) malloc(out_len+1)) != NULL) {
|
|
339
|
+
fseek(f, 0L, SEEK_SET);
|
|
340
|
+
if(fread(*out, sizeof(char), out_len, f) > 0)
|
|
341
|
+
return out_len;
|
|
342
|
+
else
|
|
343
|
+
return -1;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return 0;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// take a previous hash and concatenate with serialized bytes of element and hashes into output buf
|
|
352
|
+
int hash2_element_to_bytes(element_t *e, uint8_t* last_buf, int hash_size, uint8_t* output_buf) {
|
|
353
|
+
// assume last buf contains a hash
|
|
354
|
+
int last_buflen = hash_size;
|
|
355
|
+
int buf_len = SHA_LEN;
|
|
356
|
+
uint8_t temp_buf[SHA_LEN + 1];
|
|
357
|
+
memset(temp_buf, 0, SHA_LEN);
|
|
358
|
+
element_to_key(*e, temp_buf, SHA_LEN, HASH_FUNCTION_ELEMENTS);
|
|
359
|
+
int i;
|
|
360
|
+
|
|
361
|
+
uint8_t temp2_buf[last_buflen + buf_len + 1];
|
|
362
|
+
memset(temp2_buf, 0, (last_buflen + buf_len));
|
|
363
|
+
for(i = 0; i < last_buflen; i++)
|
|
364
|
+
temp2_buf[i] = last_buf[i];
|
|
365
|
+
|
|
366
|
+
int j = 0;
|
|
367
|
+
for(i = last_buflen; i < (last_buflen + buf_len); i++) {
|
|
368
|
+
temp2_buf[i] = temp_buf[j]; j++;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
debug("%s: input buf...\n", __FUNCTION__);
|
|
372
|
+
printf_buffer_as_hex(temp2_buf, last_buflen + buf_len);
|
|
373
|
+
|
|
374
|
+
// hash the temp2_buf to bytes
|
|
375
|
+
int result = hash_buffer_to_bytes(temp2_buf, (last_buflen + buf_len), output_buf, hash_size, HASH_FUNCTION_STRINGS);
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
int hash2_buffer_to_bytes(uint8_t *input_str, int input_len, uint8_t *last_hash, int hash_size, uint8_t *output_buf) {
|
|
380
|
+
|
|
381
|
+
// concatenate last_buf + input_str (to len), then hash to bytes into output_buf
|
|
382
|
+
int result;
|
|
383
|
+
// copy the last hash buffer into temp buf
|
|
384
|
+
// copy the current input string into buffer
|
|
385
|
+
PyObject *last = PyBytes_FromStringAndSize((const char *) last_hash, (Py_ssize_t) hash_size);
|
|
386
|
+
PyObject *input = PyBytes_FromStringAndSize((const char *) input_str, (Py_ssize_t) input_len);
|
|
387
|
+
|
|
388
|
+
PyBytes_ConcatAndDel(&last, input);
|
|
389
|
+
uint8_t *temp_buf = (uint8_t *) PyBytes_AsString(last);
|
|
390
|
+
|
|
391
|
+
// hash the contents of temp_buf
|
|
392
|
+
debug("last_hash => ");
|
|
393
|
+
printf_buffer_as_hex(last_hash, hash_size);
|
|
394
|
+
|
|
395
|
+
debug("input_str => ");
|
|
396
|
+
printf_buffer_as_hex(input_str, input_len);
|
|
397
|
+
|
|
398
|
+
debug("temp_buf => ");
|
|
399
|
+
printf_buffer_as_hex(temp_buf, input_len + hash_size);
|
|
400
|
+
|
|
401
|
+
result = hash_buffer_to_bytes(temp_buf, (input_len + hash_size), output_buf, hash_size, HASH_FUNCTION_STRINGS+1);
|
|
402
|
+
|
|
403
|
+
Py_XDECREF(last);
|
|
404
|
+
return result;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
PyObject *Element_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
408
|
+
{
|
|
409
|
+
Element *self;
|
|
410
|
+
|
|
411
|
+
self = (Element *)type->tp_alloc(type, 0);
|
|
412
|
+
if (self != NULL) {
|
|
413
|
+
self->elem_initialized = FALSE;
|
|
414
|
+
self->elem_initPP = FALSE;
|
|
415
|
+
self->pairing = NULL;
|
|
416
|
+
self->element_type = NONE_G;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return (PyObject *)self;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
PyObject *Pairing_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
423
|
+
{
|
|
424
|
+
Pairing *self = (Pairing *) type->tp_alloc(type, 0);
|
|
425
|
+
if(self != NULL) {
|
|
426
|
+
self->group_init = FALSE;
|
|
427
|
+
#ifdef BENCHMARK_ENABLED
|
|
428
|
+
memset(self->bench_id, 0, ID_LEN);
|
|
429
|
+
self->dBench = NULL;
|
|
430
|
+
self->gBench = NULL;
|
|
431
|
+
#endif
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return (PyObject *) self;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
int Element_init(Element *self, PyObject *args, PyObject *kwds)
|
|
438
|
+
{
|
|
439
|
+
return -1;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
int Pairing_init(Pairing *self, PyObject *args, PyObject *kwds)
|
|
444
|
+
{
|
|
445
|
+
int bits = 0;
|
|
446
|
+
Py_ssize_t string_len = 0;
|
|
447
|
+
int seed = -1;
|
|
448
|
+
char *string = NULL;
|
|
449
|
+
|
|
450
|
+
static char *kwlist[] = {"bits", "string", "seed", NULL};
|
|
451
|
+
|
|
452
|
+
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|is#i", kwlist,
|
|
453
|
+
&bits, &string, &string_len, &seed)) {
|
|
454
|
+
PyErr_SetString(ElementError, "invalid arguments");
|
|
455
|
+
return -1;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if(pairing_init() != ELEMENT_OK) {
|
|
459
|
+
// printf("%s: Using RELIC library...\n", __FUNCTION__);
|
|
460
|
+
PyErr_SetString(ElementError, "could not initialize pairing object.");
|
|
461
|
+
return -1;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
self->group_init = TRUE;
|
|
465
|
+
return 0;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
static PyObject *Element_elem(Element* self, PyObject* args)
|
|
469
|
+
{
|
|
470
|
+
Element *retObject;
|
|
471
|
+
Pairing *group = NULL;
|
|
472
|
+
int type;
|
|
473
|
+
PyObject *long_obj = NULL;
|
|
474
|
+
|
|
475
|
+
if(!PyArg_ParseTuple(args, "Oi|O", &group, &type, &long_obj)) {
|
|
476
|
+
EXIT_IF(TRUE, "invalid arguments.");
|
|
477
|
+
}
|
|
478
|
+
VERIFY_GROUP(group);
|
|
479
|
+
|
|
480
|
+
debug("init an element.\n");
|
|
481
|
+
if(type >= ZR && type <= GT) {
|
|
482
|
+
retObject = createNewElement(type, group);
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
EXIT_IF(TRUE, "unrecognized group type.");
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if(long_obj != NULL && _PyLong_Check(long_obj)) {
|
|
489
|
+
integer_t m;
|
|
490
|
+
bn_inits(m);
|
|
491
|
+
ConvertToInt2(m, long_obj);
|
|
492
|
+
element_set_int(retObject->e, m);
|
|
493
|
+
bn_free(m);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/* return Element object */
|
|
497
|
+
return (PyObject *) retObject;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
PyObject *Pairing_print(Pairing* self)
|
|
501
|
+
{
|
|
502
|
+
return PyUnicode_FromString("");
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
PyObject *Element_print(Element* self)
|
|
506
|
+
{
|
|
507
|
+
PyObject *strObj;
|
|
508
|
+
debug("Contents of element object\n");
|
|
509
|
+
|
|
510
|
+
if(self->elem_initialized) {
|
|
511
|
+
|
|
512
|
+
// element_printf("element_t :=> \n", self->e);
|
|
513
|
+
|
|
514
|
+
char str[MAX_BUF + 1];
|
|
515
|
+
memset(str, 0, MAX_BUF);
|
|
516
|
+
element_to_str(str, MAX_BUF, self->e);
|
|
517
|
+
int len = strlen(str);
|
|
518
|
+
strObj = PyUnicode_FromStringAndSize((const char *) str, len);
|
|
519
|
+
if(strObj != NULL)
|
|
520
|
+
return strObj;
|
|
521
|
+
else
|
|
522
|
+
return PyUnicode_FromString("");
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
return PyUnicode_FromString("");
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
static PyObject *Element_random(Element* self, PyObject* args)
|
|
529
|
+
{
|
|
530
|
+
Element *retObject;
|
|
531
|
+
Pairing *group = NULL;
|
|
532
|
+
int arg1;
|
|
533
|
+
int e_type = -1, seed = -1;
|
|
534
|
+
|
|
535
|
+
/* create a new object */
|
|
536
|
+
if(!PyArg_ParseTuple(args, "Oi|i", &group, &arg1, &seed))
|
|
537
|
+
return NULL;
|
|
538
|
+
|
|
539
|
+
VERIFY_GROUP(group);
|
|
540
|
+
retObject = PyObject_New(Element, &ElementType);
|
|
541
|
+
debug("init random element in '%d'\n", arg1);
|
|
542
|
+
if(arg1 == ZR) {
|
|
543
|
+
element_init_Zr(retObject->e, 0);
|
|
544
|
+
e_type = ZR;
|
|
545
|
+
}
|
|
546
|
+
else if(arg1 == G1) {
|
|
547
|
+
element_init_G1(retObject->e);
|
|
548
|
+
e_type = G1;
|
|
549
|
+
}
|
|
550
|
+
else if(arg1 == G2) {
|
|
551
|
+
element_init_G2(retObject->e);
|
|
552
|
+
e_type = G2;
|
|
553
|
+
}
|
|
554
|
+
else if(arg1 == GT) {
|
|
555
|
+
EXIT_IF(TRUE, "cannot generate random elements in GT.");
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
EXIT_IF(TRUE, "unrecognized group type.");
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/* create new Element object */
|
|
562
|
+
element_random(retObject->e);
|
|
563
|
+
|
|
564
|
+
retObject->elem_initialized = TRUE;
|
|
565
|
+
retObject->elem_initPP = FALSE;
|
|
566
|
+
retObject->pairing = group;
|
|
567
|
+
Py_INCREF(retObject->pairing);
|
|
568
|
+
retObject->element_type = e_type;
|
|
569
|
+
return (PyObject *) retObject;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
static PyObject *Element_add(Element *self, Element *other)
|
|
573
|
+
{
|
|
574
|
+
Element *newObject;
|
|
575
|
+
|
|
576
|
+
debug("Starting '%s'\n", __func__);
|
|
577
|
+
#ifdef DEBUG
|
|
578
|
+
if(self->e) {
|
|
579
|
+
element_printf("Left: e => \n", self->e);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if(other->e) {
|
|
583
|
+
element_printf("Right: e => \n", other->e);
|
|
584
|
+
}
|
|
585
|
+
#endif
|
|
586
|
+
IS_SAME_GROUP(self, other);
|
|
587
|
+
EXIT_IF(add_rule(self->element_type, other->element_type) == FALSE, "invalid add operation.");
|
|
588
|
+
// start micro benchmark
|
|
589
|
+
|
|
590
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
591
|
+
element_add(newObject->e, self->e, other->e);
|
|
592
|
+
|
|
593
|
+
#ifdef BENCHMARK_ENABLED
|
|
594
|
+
UPDATE_BENCH(ADDITION, newObject->element_type, newObject->pairing);
|
|
595
|
+
#endif
|
|
596
|
+
return (PyObject *) newObject;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
static PyObject *Element_sub(Element *self, Element *other)
|
|
600
|
+
{
|
|
601
|
+
Element *newObject;
|
|
602
|
+
|
|
603
|
+
debug("Starting '%s'\n", __func__);
|
|
604
|
+
#ifdef DEBUG
|
|
605
|
+
if(self->e) {
|
|
606
|
+
element_printf("Left: e => \n", self->e);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if(other->e) {
|
|
610
|
+
element_printf("Right: e => \n", other->e);
|
|
611
|
+
}
|
|
612
|
+
#endif
|
|
613
|
+
IS_SAME_GROUP(self, other);
|
|
614
|
+
EXIT_IF(sub_rule(self->element_type, other->element_type) == FALSE, "invalid sub operation.");
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
618
|
+
element_sub(newObject->e, self->e, other->e);
|
|
619
|
+
|
|
620
|
+
#ifdef BENCHMARK_ENABLED
|
|
621
|
+
UPDATE_BENCH(SUBTRACTION, newObject->element_type, newObject->pairing);
|
|
622
|
+
#endif
|
|
623
|
+
return (PyObject *) newObject;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
/* requires more care -- understand possibilities first */
|
|
628
|
+
static PyObject *Element_mul(PyObject *lhs, PyObject *rhs)
|
|
629
|
+
{
|
|
630
|
+
Element *self = NULL, *other = NULL, *newObject = NULL;
|
|
631
|
+
integer_t z;
|
|
632
|
+
int found_int = FALSE;
|
|
633
|
+
|
|
634
|
+
// lhs or rhs must be an element type
|
|
635
|
+
if(PyElement_Check(lhs)) {
|
|
636
|
+
self = (Element *) lhs;
|
|
637
|
+
}
|
|
638
|
+
else if(_PyLong_Check(lhs)) {
|
|
639
|
+
bn_inits(z);
|
|
640
|
+
ConvertToInt2(z, lhs);
|
|
641
|
+
found_int = TRUE;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if(PyElement_Check(rhs)) {
|
|
645
|
+
other = (Element *) rhs;
|
|
646
|
+
}
|
|
647
|
+
else if(_PyLong_Check(rhs)) {
|
|
648
|
+
bn_inits(z);
|
|
649
|
+
ConvertToInt2(z, rhs);
|
|
650
|
+
found_int = TRUE;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
debug("Starting '%s'\n", __func__);
|
|
654
|
+
if(PyElement_Check(lhs) && found_int) {
|
|
655
|
+
// lhs is the element type
|
|
656
|
+
|
|
657
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
658
|
+
// multiplication is commutative
|
|
659
|
+
element_mul_int(newObject->e, self->e, z);
|
|
660
|
+
bn_free(z);
|
|
661
|
+
|
|
662
|
+
}
|
|
663
|
+
else if(PyElement_Check(rhs) && found_int) {
|
|
664
|
+
// rhs is the element type
|
|
665
|
+
|
|
666
|
+
newObject = createNewElement(other->element_type, other->pairing);
|
|
667
|
+
// multiplication is commutative
|
|
668
|
+
element_mul_int(newObject->e, other->e, z);
|
|
669
|
+
bn_free(z);
|
|
670
|
+
|
|
671
|
+
}
|
|
672
|
+
else if(PyElement_Check(lhs) && PyElement_Check(rhs)) {
|
|
673
|
+
// both are element types
|
|
674
|
+
IS_SAME_GROUP(self, other);
|
|
675
|
+
EXIT_IF(mul_rule(self->element_type, other->element_type) == FALSE, "invalid mul operation.");
|
|
676
|
+
|
|
677
|
+
if(self->element_type != ZR && other->element_type == ZR) {
|
|
678
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
679
|
+
element_mul_zr(newObject->e, self->e, other->e);
|
|
680
|
+
|
|
681
|
+
}
|
|
682
|
+
else if(other->element_type != ZR && self->element_type == ZR) {
|
|
683
|
+
newObject = createNewElement(other->element_type, self->pairing);
|
|
684
|
+
element_mul_zr(newObject->e, other->e, self->e);
|
|
685
|
+
}
|
|
686
|
+
else { // all other cases
|
|
687
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
688
|
+
element_mul(newObject->e, self->e, other->e);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
else {
|
|
692
|
+
EXIT_IF(TRUE, "invalid types.");
|
|
693
|
+
}
|
|
694
|
+
#ifdef BENCHMARK_ENABLED
|
|
695
|
+
UPDATE_BENCH(MULTIPLICATION, newObject->element_type, newObject->pairing);
|
|
696
|
+
#endif
|
|
697
|
+
return (PyObject *) newObject;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
static PyObject *Element_div(PyObject *lhs, PyObject *rhs)
|
|
701
|
+
{
|
|
702
|
+
Element *self = NULL, *other = NULL, *newObject = NULL;
|
|
703
|
+
integer_t z;
|
|
704
|
+
int found_int = FALSE;
|
|
705
|
+
|
|
706
|
+
// lhs or rhs must be an element type
|
|
707
|
+
if(PyElement_Check(lhs)) {
|
|
708
|
+
self = (Element *) lhs;
|
|
709
|
+
}
|
|
710
|
+
else if(PyLong_Check(lhs)) {
|
|
711
|
+
bn_inits(z);
|
|
712
|
+
ConvertToInt2(z, lhs);
|
|
713
|
+
found_int = TRUE;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if(PyElement_Check(rhs)) {
|
|
717
|
+
other = (Element *) rhs;
|
|
718
|
+
}
|
|
719
|
+
else if(PyLong_Check(rhs)) {
|
|
720
|
+
bn_inits(z);
|
|
721
|
+
ConvertToInt2(z, rhs);
|
|
722
|
+
found_int = TRUE;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
debug("Starting '%s'\n", __func__);
|
|
726
|
+
if(PyElement_Check(lhs) && found_int) {
|
|
727
|
+
// lhs is the element type
|
|
728
|
+
|
|
729
|
+
// EXIT_IF(div_rule(self->element_type, ZR) == FALSE, "invalid div operation.");
|
|
730
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
731
|
+
other = createNewElement(self->element_type, self->pairing);
|
|
732
|
+
if(element_div_int(newObject->e, self->e, z) == ELEMENT_DIV_ZERO) {
|
|
733
|
+
Py_XDECREF(newObject);
|
|
734
|
+
//newObject = NULL;
|
|
735
|
+
bn_free(z);
|
|
736
|
+
EXIT_IF(TRUE, "divide by zero error!");
|
|
737
|
+
}
|
|
738
|
+
bn_free(z);
|
|
739
|
+
|
|
740
|
+
}
|
|
741
|
+
else if(PyElement_Check(rhs) && found_int) {
|
|
742
|
+
// rhs is the element type
|
|
743
|
+
|
|
744
|
+
// EXIT_IF(div_rule(ZR, other->element_type) == FALSE, "invalid div operation.");
|
|
745
|
+
newObject = createNewElement(other->element_type, other->pairing);
|
|
746
|
+
if(element_int_div(newObject->e, z, other->e) == ELEMENT_DIV_ZERO) {
|
|
747
|
+
Py_XDECREF(newObject);
|
|
748
|
+
// newObject = NULL;
|
|
749
|
+
bn_free(z);
|
|
750
|
+
EXIT_IF(TRUE, "divide by zero error!");
|
|
751
|
+
}
|
|
752
|
+
bn_free(z);
|
|
753
|
+
|
|
754
|
+
}
|
|
755
|
+
else if(PyElement_Check(lhs) && PyElement_Check(rhs)) {
|
|
756
|
+
// both are element types
|
|
757
|
+
IS_SAME_GROUP(self, other);
|
|
758
|
+
EXIT_IF(div_rule(self->element_type, other->element_type) == FALSE, "invalid div operation.");
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
762
|
+
if(element_div(newObject->e, self->e, other->e) == ELEMENT_DIV_ZERO) {
|
|
763
|
+
Py_XDECREF(newObject);
|
|
764
|
+
//newObject = NULL;
|
|
765
|
+
EXIT_IF(TRUE, "divide by zero error!");
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
EXIT_IF(TRUE, "invalid types.");
|
|
771
|
+
PyErr_SetString(ElementError, "invalid types");
|
|
772
|
+
return NULL;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
#ifdef BENCHMARK_ENABLED
|
|
776
|
+
UPDATE_BENCH(DIVISION, newObject->element_type, newObject->pairing);
|
|
777
|
+
#endif
|
|
778
|
+
return (PyObject *) newObject;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
static PyObject *Element_invert(Element *self)
|
|
782
|
+
{
|
|
783
|
+
Element *newObject = NULL;
|
|
784
|
+
|
|
785
|
+
debug("Starting '%s'\n", __func__);
|
|
786
|
+
#ifdef DEBUG
|
|
787
|
+
if(self->e) {
|
|
788
|
+
element_printf("e => \n", self->e);
|
|
789
|
+
}
|
|
790
|
+
#endif
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
794
|
+
element_invert(newObject->e, self->e);
|
|
795
|
+
|
|
796
|
+
return (PyObject *) newObject;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
static PyObject *Element_negate(Element *self)
|
|
800
|
+
{
|
|
801
|
+
Element *newObject = NULL;
|
|
802
|
+
|
|
803
|
+
debug("Starting '%s'\n", __func__);
|
|
804
|
+
#ifdef DEBUG
|
|
805
|
+
if(self->e) {
|
|
806
|
+
element_printf("e => \n", self->e);
|
|
807
|
+
}
|
|
808
|
+
#endif
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
newObject = createNewElement(self->element_type, self->pairing);
|
|
812
|
+
element_neg(newObject->e, self->e);
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
return (PyObject *) newObject;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
static PyObject *Element_pow(PyObject *o1, PyObject *o2, PyObject *o3)
|
|
819
|
+
{
|
|
820
|
+
Element *newObject = NULL, *lhs_o1 = NULL, *rhs_o2 = NULL;
|
|
821
|
+
int longFoundLHS = FALSE, longFoundRHS = FALSE;
|
|
822
|
+
integer_t n;
|
|
823
|
+
|
|
824
|
+
Check_Types2(o1, o2, lhs_o1, rhs_o2, longFoundLHS, longFoundRHS);
|
|
825
|
+
|
|
826
|
+
if(longFoundLHS) {
|
|
827
|
+
// o1 is a long type and o2 is a element type
|
|
828
|
+
// o1 should be element and o2 should be mpz
|
|
829
|
+
if(rhs_o2->element_type == ZR) {
|
|
830
|
+
// printf("%s: testing longFoundLHS\n", __FUNCTION__);
|
|
831
|
+
|
|
832
|
+
bn_inits(n);
|
|
833
|
+
ConvertToInt2(n, o1);
|
|
834
|
+
newObject = createNewElement(rhs_o2->element_type, rhs_o2->pairing);
|
|
835
|
+
element_set_int(newObject->e, n);
|
|
836
|
+
element_pow_zr(newObject->e, newObject->e, rhs_o2->e);
|
|
837
|
+
bn_free(n);
|
|
838
|
+
Py_DECREF(lhs_o1);
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
EXIT_IF(TRUE, "undefined exponentiation operation.");
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
else if(longFoundRHS) {
|
|
845
|
+
// o2 is a long type
|
|
846
|
+
|
|
847
|
+
long rhs = PyLong_AsLong(o2);
|
|
848
|
+
if(PyErr_Occurred() || rhs >= 0) {
|
|
849
|
+
// printf("%s: testing longFoundLHS\n", __FUNCTION__);
|
|
850
|
+
// clear error and continue
|
|
851
|
+
// PyErr_Print(); // for debug purposes
|
|
852
|
+
PyErr_Clear();
|
|
853
|
+
newObject = createNewElement(lhs_o1->element_type, lhs_o1->pairing);
|
|
854
|
+
bn_inits(n);
|
|
855
|
+
ConvertToInt2(n, o2);
|
|
856
|
+
if(lhs_o1->elem_initPP == TRUE) {
|
|
857
|
+
element_pp_pow_int(newObject->e, lhs_o1->e_pp, lhs_o1->element_type, n);
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
element_pow_int(newObject->e, lhs_o1->e, n);
|
|
861
|
+
}
|
|
862
|
+
bn_free(n);
|
|
863
|
+
}
|
|
864
|
+
else if(rhs == -1) {
|
|
865
|
+
// compute inverse
|
|
866
|
+
newObject = createNewElement(lhs_o1->element_type, lhs_o1->pairing);
|
|
867
|
+
element_invert(newObject->e, lhs_o1->e);
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
EXIT_IF(TRUE, "undefined exponentiation operation.");
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
}
|
|
874
|
+
else if(Check_Elements(o1, o2)) {
|
|
875
|
+
debug("Starting '%s'\n", __func__);
|
|
876
|
+
IS_SAME_GROUP(lhs_o1, rhs_o2);
|
|
877
|
+
EXIT_IF(exp_rule(lhs_o1->element_type, rhs_o2->element_type) == FALSE, "invalid exp operation");
|
|
878
|
+
if(rhs_o2->element_type == ZR) {
|
|
879
|
+
|
|
880
|
+
newObject = createNewElement(lhs_o1->element_type, lhs_o1->pairing);
|
|
881
|
+
if(lhs_o1->elem_initPP == TRUE) {
|
|
882
|
+
element_pp_pow(newObject->e, lhs_o1->e_pp, lhs_o1->element_type, rhs_o2->e);
|
|
883
|
+
}
|
|
884
|
+
else {
|
|
885
|
+
element_pow_zr(newObject->e, lhs_o1->e, rhs_o2->e);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
else {
|
|
889
|
+
// we have a problem
|
|
890
|
+
EXIT_IF(TRUE, "undefined exponentiation operation");
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
else {
|
|
894
|
+
EXIT_IF(!PyElement_Check(o1), ERROR_TYPE(left, int, bytes, str));
|
|
895
|
+
EXIT_IF(!PyElement_Check(o2), ERROR_TYPE(right, int, bytes, str));
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
#ifdef BENCHMARK_ENABLED
|
|
899
|
+
UPDATE_BENCH(EXPONENTIATION, newObject->element_type, newObject->pairing);
|
|
900
|
+
#endif
|
|
901
|
+
return (PyObject *) newObject;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
/* We assume the element has been initialized into a specific field (G1,G2,GT,or Zr), then
|
|
905
|
+
they have the opportunity to set the
|
|
906
|
+
|
|
907
|
+
*/
|
|
908
|
+
static PyObject *Element_set(Element *self, PyObject *args)
|
|
909
|
+
{
|
|
910
|
+
Element *object = NULL;
|
|
911
|
+
int errcode = TRUE;
|
|
912
|
+
unsigned int value;
|
|
913
|
+
|
|
914
|
+
EXITCODE_IF(self->elem_initialized == FALSE, "must initialize element to a field (G1,G2,GT, or Zr)", FALSE);
|
|
915
|
+
|
|
916
|
+
debug("Creating a new element\n");
|
|
917
|
+
if(PyArg_ParseTuple(args, "i", &value)) {
|
|
918
|
+
// convert into an int using PyArg_Parse(...)
|
|
919
|
+
// set the element
|
|
920
|
+
|
|
921
|
+
element_set_si(self->e, value);
|
|
922
|
+
|
|
923
|
+
}
|
|
924
|
+
else if(PyArg_ParseTuple(args, "O", &object)){
|
|
925
|
+
|
|
926
|
+
element_set(self->e, object->e);
|
|
927
|
+
|
|
928
|
+
}
|
|
929
|
+
else { //
|
|
930
|
+
EXITCODE_IF(TRUE, "type not supported: signed int or Element object", FALSE);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
return Py_BuildValue("i", errcode);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
static PyObject *Element_initPP(Element *self, PyObject *args)
|
|
937
|
+
{
|
|
938
|
+
EXITCODE_IF(self->elem_initPP == TRUE, "initialized the pre-processing function already", FALSE);
|
|
939
|
+
EXITCODE_IF(self->elem_initialized == FALSE, "must initialize element to a field (G1,G2, or GT)", FALSE);
|
|
940
|
+
|
|
941
|
+
/* initialize and store preprocessing information in e_pp */
|
|
942
|
+
if(self->element_type >= G1 && self->element_type < GT) {
|
|
943
|
+
/* set the pre-processing stuff here */
|
|
944
|
+
element_pp_init(self->e_pp, self->e);
|
|
945
|
+
self->elem_initPP = TRUE;
|
|
946
|
+
Py_RETURN_TRUE;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
Py_RETURN_FALSE;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/* Takes a list of two objects in G1 & G2 respectively and computes the multi-pairing
|
|
953
|
+
PyObject *multi_pairing(Element *groupObj, PyObject *listG1, PyObject *listG2) {
|
|
954
|
+
|
|
955
|
+
int GroupSymmetric = FALSE;
|
|
956
|
+
// check for symmetric vs. asymmetric
|
|
957
|
+
if(pairing_is_symmetric(groupObj->pairing->pair_obj)) {
|
|
958
|
+
GroupSymmetric = TRUE;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
int length = PySequence_Length(listG1);
|
|
962
|
+
|
|
963
|
+
EXIT_IF(length != PySequence_Length(listG2), "unequal number of pairing elements.");
|
|
964
|
+
if(length > 0) {
|
|
965
|
+
|
|
966
|
+
element_t g1[length];
|
|
967
|
+
element_t g2[length];
|
|
968
|
+
int i, l = 0, r = 0;
|
|
969
|
+
|
|
970
|
+
for(i = 0; i < length; i++) {
|
|
971
|
+
PyObject *tmpObject1 = PySequence_GetItem(listG1, i);
|
|
972
|
+
PyObject *tmpObject2 = PySequence_GetItem(listG2, i);
|
|
973
|
+
|
|
974
|
+
if(PyElement_Check(tmpObject1) && PyElement_Check(tmpObject2)) {
|
|
975
|
+
Element *tmp1 = (Element *) tmpObject1;
|
|
976
|
+
Element *tmp2 = (Element *) tmpObject2;
|
|
977
|
+
if(GroupSymmetric == TRUE && (tmp1->element_type == G1 || tmp1->element_type == G2)) {
|
|
978
|
+
element_init_same_as(g1[l], tmp1->e);
|
|
979
|
+
element_set(g1[l], tmp1->e);
|
|
980
|
+
l++;
|
|
981
|
+
}
|
|
982
|
+
else if(tmp1->element_type == G1) {
|
|
983
|
+
element_init_G1(g1[l], groupObj->pairing->pair_obj);
|
|
984
|
+
element_set(g1[l], tmp1->e);
|
|
985
|
+
l++;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
if(GroupSymmetric == TRUE && (tmp2->element_type == G1 || tmp2->element_type == G2)) {
|
|
989
|
+
element_init_same_as(g2[r], tmp2->e);
|
|
990
|
+
element_set(g2[r], tmp2->e);
|
|
991
|
+
r++;
|
|
992
|
+
}
|
|
993
|
+
else if(tmp2->element_type == G2) {
|
|
994
|
+
element_init_G2(g2[r], groupObj->pairing->pair_obj);
|
|
995
|
+
element_set(g2[r], tmp2->e);
|
|
996
|
+
r++;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
Py_DECREF(tmpObject1);
|
|
1000
|
+
Py_DECREF(tmpObject2);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
Element *newObject = NULL;
|
|
1004
|
+
if(l == r) {
|
|
1005
|
+
newObject = createNewElement(GT, groupObj->pairing);
|
|
1006
|
+
element_prod_pairing(newObject->e, g1, g2, l); // pairing product calculation
|
|
1007
|
+
}
|
|
1008
|
+
else {
|
|
1009
|
+
EXIT_IF(TRUE, "invalid pairing element types in list.");
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// clean up
|
|
1013
|
+
for(i = 0; i < l; i++) { element_clear(g1[i]); }
|
|
1014
|
+
for(i = 0; i < r; i++) { element_clear(g2[i]); }
|
|
1015
|
+
return (PyObject *) newObject;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
EXIT_IF(TRUE, "list is empty.");
|
|
1019
|
+
}
|
|
1020
|
+
*/
|
|
1021
|
+
|
|
1022
|
+
/* this is a type method that is visible on the global or class level. Therefore,
|
|
1023
|
+
the function prototype needs the self (element class) and the args (tuple of Element objects).
|
|
1024
|
+
*/
|
|
1025
|
+
PyObject *Apply_pairing(Element *self, PyObject *args)
|
|
1026
|
+
{
|
|
1027
|
+
// lhs => G1 and rhs => G2
|
|
1028
|
+
Element *newObject, *lhs, *rhs, *group = NULL;
|
|
1029
|
+
PyObject *lhs2, *rhs2;
|
|
1030
|
+
|
|
1031
|
+
debug("Applying pairing...\n");
|
|
1032
|
+
if(!PyArg_ParseTuple(args, "OO|O", &lhs2, &rhs2, &group)) {
|
|
1033
|
+
EXIT_IF(TRUE, "invalid arguments: G1, G2, groupObject.");
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
// if(PySequence_Check(lhs2) && PySequence_Check(rhs2)) {
|
|
1037
|
+
// VERIFY_GROUP(group);
|
|
1038
|
+
// return multi_pairing(group, lhs2, rhs2);
|
|
1039
|
+
// }
|
|
1040
|
+
|
|
1041
|
+
if(PyElement_Check(lhs2) && PyElement_Check(rhs2)) {
|
|
1042
|
+
|
|
1043
|
+
lhs = (Element *) lhs2;
|
|
1044
|
+
rhs = (Element *) rhs2;
|
|
1045
|
+
IS_SAME_GROUP(lhs, rhs);
|
|
1046
|
+
|
|
1047
|
+
if(pair_rule(lhs->element_type, rhs->element_type) == TRUE) {
|
|
1048
|
+
debug("Pairing is symmetric.\n");
|
|
1049
|
+
debug_e("LHS: '%B'\n", lhs->e);
|
|
1050
|
+
debug_e("RHS: '%B'\n", rhs->e);
|
|
1051
|
+
//
|
|
1052
|
+
newObject = createNewElement(GT, lhs->pairing);
|
|
1053
|
+
if(lhs->element_type == G1) {
|
|
1054
|
+
pairing_apply(newObject->e, lhs->e, rhs->e);
|
|
1055
|
+
}
|
|
1056
|
+
else if(lhs->element_type == G2) {
|
|
1057
|
+
pairing_apply(newObject->e, rhs->e, lhs->e);
|
|
1058
|
+
}
|
|
1059
|
+
//
|
|
1060
|
+
#ifdef BENCHMARK_ENABLED
|
|
1061
|
+
UPDATE_BENCHMARK(PAIRINGS, newObject->pairing->dBench);
|
|
1062
|
+
#endif
|
|
1063
|
+
return (PyObject *) newObject;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
EXIT_IF(TRUE, "pairings only apply to elements of G1 x G2 --> GT");
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
PyObject *sha2_hash(Element *self, PyObject *args) {
|
|
1070
|
+
Element *object;
|
|
1071
|
+
PyObject *str = NULL;
|
|
1072
|
+
uint8_t *hash_hex = NULL;
|
|
1073
|
+
uint8_t label = 0x00;
|
|
1074
|
+
|
|
1075
|
+
debug("Hashing the element...\n");
|
|
1076
|
+
EXIT_IF(!PyArg_ParseTuple(args, "O|c", &object, &label), "missing element object");
|
|
1077
|
+
|
|
1078
|
+
if(!PyElement_Check(object)) EXIT_IF(TRUE, "not a valid element object.");
|
|
1079
|
+
EXIT_IF(object->elem_initialized == FALSE, "null element object.");
|
|
1080
|
+
int hash_size = SHA_LEN;
|
|
1081
|
+
uint8_t hash_buf[hash_size + 1];
|
|
1082
|
+
memset(hash_buf, 0, hash_size);
|
|
1083
|
+
// hash element to a buffer
|
|
1084
|
+
element_to_key(object->e, hash_buf, hash_size, label);
|
|
1085
|
+
|
|
1086
|
+
hash_hex = (uint8_t *) convert_buffer_to_hex(hash_buf, (size_t) hash_size);
|
|
1087
|
+
// printf_buffer_as_hex(hash_buf, hash_size);
|
|
1088
|
+
|
|
1089
|
+
// str = PyBytes_FromStringAndSize((const char *) hash_buf, hash_size);
|
|
1090
|
+
str = PyBytes_FromString((const char *) hash_hex);
|
|
1091
|
+
free(hash_hex);
|
|
1092
|
+
|
|
1093
|
+
return str;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// note that this is a class instance function and thus, self will refer to the class object 'element'
|
|
1097
|
+
// the args will contain the references to the objects passed in by the caller.
|
|
1098
|
+
// The hash function should be able to handle elements of various types and accept
|
|
1099
|
+
// a field to hash too. For example, a string can be hashed to Zr or G1, an element in G1 can be
|
|
1100
|
+
static PyObject *Element_hash(Element *self, PyObject *args) {
|
|
1101
|
+
Element *newObject = NULL, *object = NULL;
|
|
1102
|
+
Pairing *group = NULL;
|
|
1103
|
+
PyObject *objList = NULL, *tmpObject = NULL, *tmp_obj = NULL;
|
|
1104
|
+
// hashing element to Zr
|
|
1105
|
+
uint8_t hash_buf[SHA_LEN+1];
|
|
1106
|
+
memset(hash_buf, '\0', SHA_LEN);
|
|
1107
|
+
int result, i;
|
|
1108
|
+
GroupType type = ZR;
|
|
1109
|
+
char *tmp = NULL, *str;
|
|
1110
|
+
|
|
1111
|
+
// make sure args have the right type -- check that args contain a "string" and "string"
|
|
1112
|
+
if(!PyArg_ParseTuple(args, "OO|i", &group, &objList, &type)) {
|
|
1113
|
+
tmp = "invalid object types";
|
|
1114
|
+
goto cleanup;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
VERIFY_GROUP(group);
|
|
1118
|
+
// first case: is a string and type may or may not be set
|
|
1119
|
+
if(PyBytes_CharmCheck(objList)) {
|
|
1120
|
+
str = NULL;
|
|
1121
|
+
PyBytes_ToString2(str, objList, tmp_obj);
|
|
1122
|
+
if(type == ZR) {
|
|
1123
|
+
debug("Hashing string '%s' to Zr...\n", str);
|
|
1124
|
+
// create an element of Zr
|
|
1125
|
+
// hash bytes using SHA1
|
|
1126
|
+
|
|
1127
|
+
newObject = createNewElement(ZR, group);
|
|
1128
|
+
// extract element in hash
|
|
1129
|
+
result = element_from_hash(newObject->e, (uint8_t *) str, strlen(str));
|
|
1130
|
+
if(result != ELEMENT_OK) {
|
|
1131
|
+
tmp = "could not hash to bytes.";
|
|
1132
|
+
goto cleanup;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
else if(type == G1 || type == G2) {
|
|
1136
|
+
// element to G1
|
|
1137
|
+
debug("Hashing string '%s'\n", str);
|
|
1138
|
+
debug("Target GroupType => '%d'", type);
|
|
1139
|
+
|
|
1140
|
+
newObject = createNewElement(type, group);
|
|
1141
|
+
// hash bytes using SHA
|
|
1142
|
+
result = element_from_hash(newObject->e, (uint8_t *) str, strlen(str));
|
|
1143
|
+
if(result != ELEMENT_OK) {
|
|
1144
|
+
tmp = "could not hash to bytes.";
|
|
1145
|
+
goto cleanup;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
}
|
|
1149
|
+
else {
|
|
1150
|
+
// not supported, right?
|
|
1151
|
+
tmp = "cannot hash a string to that field. Only Zr or G1.";
|
|
1152
|
+
goto cleanup;
|
|
1153
|
+
}
|
|
1154
|
+
if(tmp_obj != NULL) Py_DECREF(tmp_obj);
|
|
1155
|
+
}
|
|
1156
|
+
// element type to ZR or G1. Can also contain multiple elements
|
|
1157
|
+
// second case: is a tuple of elements of which could be a string or group elements
|
|
1158
|
+
else if(PySequence_Check(objList)) {
|
|
1159
|
+
int size = PySequence_Length(objList);
|
|
1160
|
+
if(size > 0) {
|
|
1161
|
+
// its a tuple of Elements
|
|
1162
|
+
tmpObject = PySequence_GetItem(objList, 0);
|
|
1163
|
+
if(PyElement_Check(tmpObject)) {
|
|
1164
|
+
object = (Element *) tmpObject;
|
|
1165
|
+
result = element_to_key(object->e, hash_buf, SHA_LEN, 0);
|
|
1166
|
+
}
|
|
1167
|
+
else if(PyBytes_CharmCheck(tmpObject)) {
|
|
1168
|
+
str = NULL;
|
|
1169
|
+
PyBytes_ToString2(str, tmpObject, tmp_obj);
|
|
1170
|
+
result = hash_buffer_to_bytes((uint8_t *) str, strlen(str), hash_buf, SHA_LEN, HASH_FUNCTION_STR_TO_Zr_CRH);
|
|
1171
|
+
debug("hash str element =>");
|
|
1172
|
+
printf_buffer_as_hex(hash_buf, SHA_LEN);
|
|
1173
|
+
}
|
|
1174
|
+
Py_DECREF(tmpObject);
|
|
1175
|
+
|
|
1176
|
+
uint8_t out_buf[SHA_LEN+1];
|
|
1177
|
+
// convert the contents of tmp_buf to a string?
|
|
1178
|
+
for(i = 1; i < size; i++) {
|
|
1179
|
+
tmpObject = PySequence_GetItem(objList, i);
|
|
1180
|
+
if(PyElement_Check(tmpObject)) {
|
|
1181
|
+
object = (Element *) tmpObject;
|
|
1182
|
+
memset(out_buf, '\0', SHA_LEN);
|
|
1183
|
+
// current hash_buf output concatenated with object are sha1 hashed into hash_buf
|
|
1184
|
+
result = hash2_element_to_bytes(&object->e, hash_buf, SHA_LEN, out_buf); // TODO: fix this
|
|
1185
|
+
debug("hash element => ");
|
|
1186
|
+
printf_buffer_as_hex(out_buf, SHA_LEN);
|
|
1187
|
+
memcpy(hash_buf, out_buf, SHA_LEN);
|
|
1188
|
+
}
|
|
1189
|
+
else if(PyBytes_CharmCheck(tmpObject)) {
|
|
1190
|
+
str = NULL;
|
|
1191
|
+
PyBytes_ToString2(str, tmpObject, tmp_obj);
|
|
1192
|
+
// this assumes that the string is the first object (NOT GOOD, change)
|
|
1193
|
+
result = hash2_buffer_to_bytes((uint8_t *) str, strlen(str), hash_buf, SHA_LEN, out_buf); // TODO: fix this
|
|
1194
|
+
memcpy(hash_buf, out_buf, SHA_LEN);
|
|
1195
|
+
|
|
1196
|
+
// hash2_element_to_bytes()
|
|
1197
|
+
}
|
|
1198
|
+
Py_DECREF(tmpObject);
|
|
1199
|
+
}
|
|
1200
|
+
if(type == ZR) { newObject = createNewElement(ZR, group); }
|
|
1201
|
+
else if(type == G1) { newObject = createNewElement(G1, group); }
|
|
1202
|
+
else {
|
|
1203
|
+
tmp = "invalid object type";
|
|
1204
|
+
goto cleanup;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
element_from_hash(newObject->e, hash_buf, SHA_LEN);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
// third case: a tuple with one element and
|
|
1211
|
+
else if(PyElement_Check(objList)) {
|
|
1212
|
+
// one element
|
|
1213
|
+
object = (Element *) objList;
|
|
1214
|
+
if(object->elem_initialized == FALSE) {
|
|
1215
|
+
tmp = "element not initialized.";
|
|
1216
|
+
goto cleanup;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
// TODO: add type == ZR?
|
|
1220
|
+
// Hash an element of Zr to an element of G1.
|
|
1221
|
+
if(type == G1) {
|
|
1222
|
+
newObject = createNewElement(G1, group);
|
|
1223
|
+
// hash the element to the G1 field (uses sha2 as well)
|
|
1224
|
+
result = element_to_key(object->e, hash_buf, SHA_LEN, 0);
|
|
1225
|
+
if(result != ELEMENT_OK) {
|
|
1226
|
+
tmp = "could not hash to bytes";
|
|
1227
|
+
goto cleanup;
|
|
1228
|
+
}
|
|
1229
|
+
element_from_hash(newObject->e, hash_buf, HASH_LEN);
|
|
1230
|
+
}
|
|
1231
|
+
else {
|
|
1232
|
+
tmp = "can only hash an element of Zr to G1. Random Oracle model.";
|
|
1233
|
+
goto cleanup;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
else {
|
|
1237
|
+
tmp = "invalid object types";
|
|
1238
|
+
goto cleanup;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
return (PyObject *) newObject;
|
|
1243
|
+
|
|
1244
|
+
cleanup:
|
|
1245
|
+
if(newObject != NULL) Py_XDECREF(newObject);
|
|
1246
|
+
EXIT_IF(TRUE, tmp);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
static PyObject *Element_equals(PyObject *lhs, PyObject *rhs, int opid) {
|
|
1250
|
+
Element *self = NULL, *other = NULL;
|
|
1251
|
+
int result = -1;
|
|
1252
|
+
|
|
1253
|
+
EXIT_IF(opid != Py_EQ && opid != Py_NE, "comparison supported: '==' or '!='");
|
|
1254
|
+
// check type of lhs & rhs
|
|
1255
|
+
if(PyElement_Check(lhs) && PyElement_Check(rhs)) {
|
|
1256
|
+
self = (Element *) lhs;
|
|
1257
|
+
other = (Element *) rhs;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
debug("Starting '%s'\n", __func__);
|
|
1261
|
+
|
|
1262
|
+
if(self != NULL && other != NULL) {
|
|
1263
|
+
// lhs and rhs are both elements
|
|
1264
|
+
IS_SAME_GROUP(self, other);
|
|
1265
|
+
if(self->elem_initialized && other->elem_initialized) {
|
|
1266
|
+
result = element_cmp(self->e, other->e);
|
|
1267
|
+
}
|
|
1268
|
+
else {
|
|
1269
|
+
debug("one of the elements is not initialized.\n");
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
if(opid == Py_EQ) {
|
|
1275
|
+
if(result == 0) {
|
|
1276
|
+
Py_RETURN_TRUE;
|
|
1277
|
+
}
|
|
1278
|
+
Py_RETURN_FALSE;
|
|
1279
|
+
}
|
|
1280
|
+
else { /* Py_NE */
|
|
1281
|
+
if(result != 0) {
|
|
1282
|
+
Py_RETURN_TRUE;
|
|
1283
|
+
}
|
|
1284
|
+
Py_RETURN_FALSE;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
static PyObject *Element_long(PyObject *o1) {
|
|
1289
|
+
if(PyElement_Check(o1)) {
|
|
1290
|
+
// finish this function
|
|
1291
|
+
Element *value = (Element *) o1;
|
|
1292
|
+
if(value->element_type == ZR) {
|
|
1293
|
+
integer_t val;
|
|
1294
|
+
bn_inits(val);
|
|
1295
|
+
element_to_int(val, value->e); // fix this
|
|
1296
|
+
PyObject *obj = intToLongObj(val); // borrowed reference
|
|
1297
|
+
bn_free(val);
|
|
1298
|
+
return obj;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
EXIT_IF(TRUE, "cannot cast pairing object to an integer.");
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
static long Element_index(Element *o1) {
|
|
1305
|
+
long result = -1;
|
|
1306
|
+
|
|
1307
|
+
if(o1->element_type == ZR) {
|
|
1308
|
+
integer_t o;
|
|
1309
|
+
bn_inits(o);
|
|
1310
|
+
element_to_int(o, o1->e); // fix this
|
|
1311
|
+
PyObject *temp = intToLongObj(o); // fix this
|
|
1312
|
+
result = PyObject_Hash(temp);
|
|
1313
|
+
bn_free(o);
|
|
1314
|
+
Py_XDECREF(temp);
|
|
1315
|
+
}
|
|
1316
|
+
return result;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
UNARY(instance_negate, 'i', Element_negate)
|
|
1320
|
+
UNARY(instance_invert, 'i', Element_invert)
|
|
1321
|
+
BINARY(instance_add, 'a', Element_add)
|
|
1322
|
+
BINARY(instance_sub, 's', Element_sub)
|
|
1323
|
+
|
|
1324
|
+
static PyObject *Serialize_cmp(Element *o1, PyObject *args) {
|
|
1325
|
+
|
|
1326
|
+
Element *self = NULL;
|
|
1327
|
+
EXIT_IF(!PyArg_ParseTuple(args, "O", &self), "invalid argument.");
|
|
1328
|
+
if(!PyElement_Check(self)) EXIT_IF(TRUE, "not a valid element object.");
|
|
1329
|
+
EXIT_IF(self->elem_initialized == FALSE, "element not initialized");
|
|
1330
|
+
|
|
1331
|
+
int elem_len = 0;
|
|
1332
|
+
EXIT_IF(check_type(self->element_type) == FALSE, "invalid type.");
|
|
1333
|
+
|
|
1334
|
+
// determine size of buffer we need to allocate
|
|
1335
|
+
elem_len = element_length(self->e);
|
|
1336
|
+
EXIT_IF(elem_len == 0, "uninitialized element.");
|
|
1337
|
+
|
|
1338
|
+
uint8_t data_buf[elem_len + 1];
|
|
1339
|
+
memset(data_buf, 0, elem_len);
|
|
1340
|
+
// write to char buffer
|
|
1341
|
+
element_to_bytes(data_buf, elem_len, self->e);
|
|
1342
|
+
debug("result => ");
|
|
1343
|
+
printf_buffer_as_hex(data_buf, elem_len);
|
|
1344
|
+
|
|
1345
|
+
// convert to base64 and return as a string?
|
|
1346
|
+
size_t length = 0;
|
|
1347
|
+
char *base64_data_buf = NewBase64Encode(data_buf, elem_len, FALSE, &length);
|
|
1348
|
+
PyObject *result = PyBytes_FromFormat("%d:%s", self->element_type, (const char *) base64_data_buf);
|
|
1349
|
+
debug("base64 enc => '%s'\n", base64_data_buf);
|
|
1350
|
+
free(base64_data_buf);
|
|
1351
|
+
|
|
1352
|
+
return result;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
static PyObject *Deserialize_cmp(Element *self, PyObject *args) {
|
|
1356
|
+
Element *origObject = NULL;
|
|
1357
|
+
Pairing *group = NULL;
|
|
1358
|
+
PyObject *object;
|
|
1359
|
+
|
|
1360
|
+
if(PyArg_ParseTuple(args, "OO", &group, &object)) {
|
|
1361
|
+
|
|
1362
|
+
VERIFY_GROUP(group);
|
|
1363
|
+
if(PyBytes_Check(object)) {
|
|
1364
|
+
uint8_t *serial_buf = (uint8_t *) PyBytes_AsString(object);
|
|
1365
|
+
int type = atoi((const char *) &(serial_buf[0]));
|
|
1366
|
+
uint8_t *base64_buf = (uint8_t *)(serial_buf + 2);
|
|
1367
|
+
|
|
1368
|
+
size_t deserialized_len = 0;
|
|
1369
|
+
uint8_t *binary_buf = NewBase64Decode((const char *) base64_buf, strlen((char *) base64_buf), &deserialized_len);
|
|
1370
|
+
|
|
1371
|
+
if((type >= ZR && type <= GT) && deserialized_len > 0) {
|
|
1372
|
+
debug("result => ");
|
|
1373
|
+
printf_buffer_as_hex(binary_buf, deserialized_len);
|
|
1374
|
+
origObject = createNewElement(type, group);
|
|
1375
|
+
element_from_bytes(origObject->e, binary_buf, deserialized_len);
|
|
1376
|
+
free(binary_buf);
|
|
1377
|
+
|
|
1378
|
+
return (PyObject *) origObject;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
EXIT_IF(TRUE, "string object malformed.");
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
EXIT_IF(TRUE, "nothing to deserialize in element.");
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
static PyObject *Group_Check(Element *self, PyObject *args) {
|
|
1388
|
+
|
|
1389
|
+
Pairing *group = NULL;
|
|
1390
|
+
PyObject *object = NULL;
|
|
1391
|
+
if(PyArg_ParseTuple(args, "OO", &group, &object)) {
|
|
1392
|
+
VERIFY_GROUP(group); /* verify group object is still active */
|
|
1393
|
+
if(PyElement_Check(object)) {
|
|
1394
|
+
Element *elem = (Element *) object;
|
|
1395
|
+
|
|
1396
|
+
int result = element_is_member(elem->e);
|
|
1397
|
+
EXIT_IF(result == (int) ELEMENT_INVALID_ARG, "invalid object type.");
|
|
1398
|
+
|
|
1399
|
+
if(result == TRUE) {
|
|
1400
|
+
Py_INCREF(Py_True);
|
|
1401
|
+
return Py_True;
|
|
1402
|
+
}
|
|
1403
|
+
else {
|
|
1404
|
+
Py_INCREF(Py_False);
|
|
1405
|
+
return Py_False;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
PyErr_SetString(ElementError, "invalid object type.");
|
|
1411
|
+
return NULL;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
static PyObject *Get_Order(Element *self, PyObject *args) {
|
|
1415
|
+
Pairing *group = NULL;
|
|
1416
|
+
EXIT_IF(!PyArg_ParseTuple(args, "O", &group), "invalid group object");
|
|
1417
|
+
|
|
1418
|
+
VERIFY_GROUP(group);
|
|
1419
|
+
|
|
1420
|
+
integer_t x;
|
|
1421
|
+
bn_inits(x);
|
|
1422
|
+
get_order(x);
|
|
1423
|
+
PyObject *object = (PyObject *) intToLongObj(x);
|
|
1424
|
+
bn_free(x);
|
|
1425
|
+
return object; /* returns a PyInt */
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
#ifdef BENCHMARK_ENABLED
|
|
1429
|
+
|
|
1430
|
+
#define BenchmarkIdentifier 1
|
|
1431
|
+
#define GET_RESULTS_FUNC GetResultsWithPair
|
|
1432
|
+
#define GROUP_OBJECT Pairing
|
|
1433
|
+
#define BENCH_ERROR ElementError
|
|
1434
|
+
/* helper function for granularBenchmar */
|
|
1435
|
+
PyObject *PyCreateList(Operations *gBench, MeasureType type)
|
|
1436
|
+
{
|
|
1437
|
+
int countZR = -1, countG1 = -1, countG2 = -1, countGT = -1;
|
|
1438
|
+
GetField(countZR, type, ZR, gBench);
|
|
1439
|
+
GetField(countG1, type, G1, gBench);
|
|
1440
|
+
GetField(countG2, type, G2, gBench);
|
|
1441
|
+
GetField(countGT, type, GT, gBench);
|
|
1442
|
+
|
|
1443
|
+
PyObject *objList = Py_BuildValue("[iiii]", countZR, countG1, countG2, countGT);
|
|
1444
|
+
return objList;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
#include "benchmark_util.c"
|
|
1448
|
+
|
|
1449
|
+
#endif
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1453
|
+
|
|
1454
|
+
PyTypeObject PairingType = {
|
|
1455
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
1456
|
+
"pairing.Pairing", /*tp_name*/
|
|
1457
|
+
sizeof(Pairing), /*tp_basicsize*/
|
|
1458
|
+
0, /*tp_itemsize*/
|
|
1459
|
+
(destructor)Pairing_dealloc, /*tp_dealloc*/
|
|
1460
|
+
0, /*tp_print*/
|
|
1461
|
+
0, /*tp_getattr*/
|
|
1462
|
+
0, /*tp_setattr*/
|
|
1463
|
+
0, /*tp_reserved*/
|
|
1464
|
+
(reprfunc)Pairing_print, /*tp_repr*/
|
|
1465
|
+
0, /*tp_as_number*/
|
|
1466
|
+
0, /*tp_as_sequence*/
|
|
1467
|
+
0, /*tp_as_mapping*/
|
|
1468
|
+
0, /*tp_hash */
|
|
1469
|
+
0, /*tp_call*/
|
|
1470
|
+
(reprfunc)Pairing_print, /*tp_str*/
|
|
1471
|
+
0, /*tp_getattro*/
|
|
1472
|
+
0, /*tp_setattro*/
|
|
1473
|
+
0, /*tp_as_buffer*/
|
|
1474
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
1475
|
+
"Pairing group parameters", /* tp_doc */
|
|
1476
|
+
0, /* tp_traverse */
|
|
1477
|
+
0, /* tp_clear */
|
|
1478
|
+
0, /* tp_richcompare */
|
|
1479
|
+
0, /* tp_weaklistoffset */
|
|
1480
|
+
0, /* tp_iter */
|
|
1481
|
+
0, /* tp_iternext */
|
|
1482
|
+
0, /* tp_methods */
|
|
1483
|
+
0, /* tp_members */
|
|
1484
|
+
0, /* tp_getset */
|
|
1485
|
+
0, /* tp_base */
|
|
1486
|
+
0, /* tp_dict */
|
|
1487
|
+
0, /* tp_descr_get */
|
|
1488
|
+
0, /* tp_descr_set */
|
|
1489
|
+
0, /* tp_dictoffset */
|
|
1490
|
+
(initproc)Pairing_init, /* tp_init */
|
|
1491
|
+
0, /* tp_alloc */
|
|
1492
|
+
Pairing_new, /* tp_new */
|
|
1493
|
+
};
|
|
1494
|
+
#else
|
|
1495
|
+
/* python 2.x series */
|
|
1496
|
+
PyTypeObject PairingType = {
|
|
1497
|
+
PyObject_HEAD_INIT(NULL)
|
|
1498
|
+
0, /*ob_size*/
|
|
1499
|
+
"pairing.Pairing", /*tp_name*/
|
|
1500
|
+
sizeof(Pairing), /*tp_basicsize*/
|
|
1501
|
+
0, /*tp_itemsize*/
|
|
1502
|
+
(destructor)Pairing_dealloc, /*tp_dealloc*/
|
|
1503
|
+
0, /*tp_print*/
|
|
1504
|
+
0, /*tp_getattr*/
|
|
1505
|
+
0, /*tp_setattr*/
|
|
1506
|
+
0, /*tp_compare*/
|
|
1507
|
+
(reprfunc)Pairing_print, /*tp_repr*/
|
|
1508
|
+
0, /*tp_as_number*/
|
|
1509
|
+
0, /*tp_as_sequence*/
|
|
1510
|
+
0, /*tp_as_mapping*/
|
|
1511
|
+
0, /*tp_hash */
|
|
1512
|
+
0, /*tp_call*/
|
|
1513
|
+
(reprfunc)Pairing_print, /*tp_str*/
|
|
1514
|
+
0, /*tp_getattro*/
|
|
1515
|
+
0, /*tp_setattro*/
|
|
1516
|
+
0, /*tp_as_buffer*/
|
|
1517
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
1518
|
+
"Pairing group parameters", /* tp_doc */
|
|
1519
|
+
0, /* tp_traverse */
|
|
1520
|
+
0, /* tp_clear */
|
|
1521
|
+
0, /* tp_richcompare */
|
|
1522
|
+
0, /* tp_weaklistoffset */
|
|
1523
|
+
0, /* tp_iter */
|
|
1524
|
+
0, /* tp_iternext */
|
|
1525
|
+
0, /* tp_methods */
|
|
1526
|
+
0, /* tp_members */
|
|
1527
|
+
0, /* tp_getset */
|
|
1528
|
+
0, /* tp_base */
|
|
1529
|
+
0, /* tp_dict */
|
|
1530
|
+
0, /* tp_descr_get */
|
|
1531
|
+
0, /* tp_descr_set */
|
|
1532
|
+
0, /* tp_dictoffset */
|
|
1533
|
+
(initproc) Pairing_init, /* tp_init */
|
|
1534
|
+
0, /* tp_alloc */
|
|
1535
|
+
Pairing_new, /* tp_new */
|
|
1536
|
+
};
|
|
1537
|
+
|
|
1538
|
+
#endif
|
|
1539
|
+
|
|
1540
|
+
// new
|
|
1541
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1542
|
+
PyNumberMethods element_number = {
|
|
1543
|
+
instance_add, /* nb_add */
|
|
1544
|
+
instance_sub, /* nb_subtract */
|
|
1545
|
+
Element_mul, /* nb_multiply */
|
|
1546
|
+
0, /* nb_remainder */
|
|
1547
|
+
0, /* nb_divmod */
|
|
1548
|
+
Element_pow, /* nb_power */
|
|
1549
|
+
instance_negate, /* nb_negative */
|
|
1550
|
+
0, /* nb_positive */
|
|
1551
|
+
0, /* nb_absolute */
|
|
1552
|
+
0, /* nb_bool */
|
|
1553
|
+
(unaryfunc)instance_invert, /* nb_invert */
|
|
1554
|
+
0, /* nb_lshift */
|
|
1555
|
+
0, /* nb_rshift */
|
|
1556
|
+
0, /* nb_and */
|
|
1557
|
+
0, /* nb_xor */
|
|
1558
|
+
0, /* nb_or */
|
|
1559
|
+
(unaryfunc)Element_long, /* nb_int */
|
|
1560
|
+
0, /* nb_reserved */
|
|
1561
|
+
0, /* nb_float */
|
|
1562
|
+
instance_add, /* nb_inplace_add */
|
|
1563
|
+
instance_sub, /* nb_inplace_subtract */
|
|
1564
|
+
Element_mul, /* nb_inplace_multiply */
|
|
1565
|
+
0, /* nb_inplace_remainder */
|
|
1566
|
+
Element_pow, /* nb_inplace_power */
|
|
1567
|
+
0, /* nb_inplace_lshift */
|
|
1568
|
+
0, /* nb_inplace_rshift */
|
|
1569
|
+
0, /* nb_inplace_and */
|
|
1570
|
+
0, /* nb_inplace_xor */
|
|
1571
|
+
0, /* nb_inplace_or */
|
|
1572
|
+
0, /* nb_floor_divide */
|
|
1573
|
+
Element_div, /* nb_true_divide */
|
|
1574
|
+
0, /* nb_inplace_floor_divide */
|
|
1575
|
+
Element_div, /* nb_inplace_true_divide */
|
|
1576
|
+
0, /* nb_index */
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
PyTypeObject ElementType = {
|
|
1580
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
1581
|
+
"pairing.Element", /*tp_name*/
|
|
1582
|
+
sizeof(Element), /*tp_basicsize*/
|
|
1583
|
+
0, /*tp_itemsize*/
|
|
1584
|
+
(destructor)Element_dealloc, /*tp_dealloc*/
|
|
1585
|
+
0, /*tp_print*/
|
|
1586
|
+
0, /*tp_getattr*/
|
|
1587
|
+
0, /*tp_setattr*/
|
|
1588
|
+
0, /*tp_reserved*/
|
|
1589
|
+
(reprfunc)Element_print, /*tp_repr*/
|
|
1590
|
+
&element_number, /*tp_as_number*/
|
|
1591
|
+
0, /*tp_as_sequence*/
|
|
1592
|
+
0, /*tp_as_mapping*/
|
|
1593
|
+
(hashfunc)Element_index, /*tp_hash */
|
|
1594
|
+
0, /*tp_call*/
|
|
1595
|
+
0, /*tp_str*/
|
|
1596
|
+
0, /*tp_getattro*/
|
|
1597
|
+
0, /*tp_setattro*/
|
|
1598
|
+
0, /*tp_as_buffer*/
|
|
1599
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
1600
|
+
"Pairing objects", /* tp_doc */
|
|
1601
|
+
0, /* tp_traverse */
|
|
1602
|
+
0, /* tp_clear */
|
|
1603
|
+
Element_equals, /* tp_richcompare */
|
|
1604
|
+
0, /* tp_weaklistoffset */
|
|
1605
|
+
0, /* tp_iter */
|
|
1606
|
+
0, /* tp_iternext */
|
|
1607
|
+
Element_methods, /* tp_methods */
|
|
1608
|
+
Element_members, /* tp_members */
|
|
1609
|
+
0, /* tp_getset */
|
|
1610
|
+
0, /* tp_base */
|
|
1611
|
+
0, /* tp_dict */
|
|
1612
|
+
0, /* tp_descr_get */
|
|
1613
|
+
0, /* tp_descr_set */
|
|
1614
|
+
0, /* tp_dictoffset */
|
|
1615
|
+
(initproc)Element_init, /* tp_init */
|
|
1616
|
+
0, /* tp_alloc */
|
|
1617
|
+
Element_new, /* tp_new */
|
|
1618
|
+
};
|
|
1619
|
+
#else
|
|
1620
|
+
/* python 2.x series */
|
|
1621
|
+
PyNumberMethods element_number = {
|
|
1622
|
+
instance_add, /* nb_add */
|
|
1623
|
+
instance_sub, /* nb_subtract */
|
|
1624
|
+
Element_mul, /* nb_multiply */
|
|
1625
|
+
Element_div, /* nb_divide */
|
|
1626
|
+
0, /* nb_remainder */
|
|
1627
|
+
0, /* nb_divmod */
|
|
1628
|
+
Element_pow, /* nb_power */
|
|
1629
|
+
instance_negate, /* nb_negative */
|
|
1630
|
+
0, /* nb_positive */
|
|
1631
|
+
0, /* nb_absolute */
|
|
1632
|
+
0, /* nb_nonzero */
|
|
1633
|
+
(unaryfunc)instance_invert, /* nb_invert */
|
|
1634
|
+
0, /* nb_lshift */
|
|
1635
|
+
0, /* nb_rshift */
|
|
1636
|
+
0, /* nb_and */
|
|
1637
|
+
0, /* nb_xor */
|
|
1638
|
+
0, /* nb_or */
|
|
1639
|
+
0, /* nb_coerce */
|
|
1640
|
+
0, /* nb_int */
|
|
1641
|
+
(unaryfunc)Element_long, /* nb_long */
|
|
1642
|
+
0, /* nb_float */
|
|
1643
|
+
0, /* nb_oct */
|
|
1644
|
+
0, /* nb_hex */
|
|
1645
|
+
instance_add, /* nb_inplace_add */
|
|
1646
|
+
instance_sub, /* nb_inplace_subtract */
|
|
1647
|
+
Element_mul, /* nb_inplace_multiply */
|
|
1648
|
+
Element_div, /* nb_inplace_divide */
|
|
1649
|
+
0, /* nb_inplace_remainder */
|
|
1650
|
+
0, /* nb_inplace_power */
|
|
1651
|
+
0, /* nb_inplace_lshift */
|
|
1652
|
+
0, /* nb_inplace_rshift */
|
|
1653
|
+
0, /* nb_inplace_and */
|
|
1654
|
+
0, /* nb_inplace_xor */
|
|
1655
|
+
0, /* nb_inplace_or */
|
|
1656
|
+
0, /* nb_floor_divide */
|
|
1657
|
+
0, /* nb_true_divide */
|
|
1658
|
+
0, /* nb_inplace_floor_divide */
|
|
1659
|
+
0, /* nb_inplace_true_divide */
|
|
1660
|
+
0, /* nb_index */
|
|
1661
|
+
};
|
|
1662
|
+
|
|
1663
|
+
PyTypeObject ElementType = {
|
|
1664
|
+
PyObject_HEAD_INIT(NULL)
|
|
1665
|
+
0, /*ob_size*/
|
|
1666
|
+
"pairing.Element", /*tp_name*/
|
|
1667
|
+
sizeof(Element), /*tp_basicsize*/
|
|
1668
|
+
0, /*tp_itemsize*/
|
|
1669
|
+
(destructor)Element_dealloc, /*tp_dealloc*/
|
|
1670
|
+
0, /*tp_print*/
|
|
1671
|
+
0, /*tp_getattr*/
|
|
1672
|
+
0, /*tp_setattr*/
|
|
1673
|
+
0, /*tp_compare*/
|
|
1674
|
+
0, /*tp_repr*/
|
|
1675
|
+
&element_number, /*tp_as_number*/
|
|
1676
|
+
0, /*tp_as_sequence*/
|
|
1677
|
+
0, /*tp_as_mapping*/
|
|
1678
|
+
(hashfunc)Element_index, /*tp_hash */
|
|
1679
|
+
0, /*tp_call*/
|
|
1680
|
+
(reprfunc)Element_print, /*tp_str*/
|
|
1681
|
+
0, /*tp_getattro*/
|
|
1682
|
+
0, /*tp_setattro*/
|
|
1683
|
+
0, /*tp_as_buffer*/
|
|
1684
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
|
1685
|
+
"Pairing objects", /* tp_doc */
|
|
1686
|
+
0, /* tp_traverse */
|
|
1687
|
+
0, /* tp_clear */
|
|
1688
|
+
Element_equals, /* tp_richcompare */
|
|
1689
|
+
0, /* tp_weaklistoffset */
|
|
1690
|
+
0, /* tp_iter */
|
|
1691
|
+
0, /* tp_iternext */
|
|
1692
|
+
Element_methods, /* tp_methods */
|
|
1693
|
+
Element_members, /* tp_members */
|
|
1694
|
+
0, /* tp_getset */
|
|
1695
|
+
0, /* tp_base */
|
|
1696
|
+
0, /* tp_dict */
|
|
1697
|
+
0, /* tp_descr_get */
|
|
1698
|
+
0, /* tp_descr_set */
|
|
1699
|
+
0, /* tp_dictoffset */
|
|
1700
|
+
(initproc) Element_init, /* tp_init */
|
|
1701
|
+
0, /* tp_alloc */
|
|
1702
|
+
Element_new, /* tp_new */
|
|
1703
|
+
};
|
|
1704
|
+
|
|
1705
|
+
#endif
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
struct module_state {
|
|
1709
|
+
PyObject *error;
|
|
1710
|
+
};
|
|
1711
|
+
|
|
1712
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1713
|
+
#define GETSTATE(m) ((struct module_state *) PyModule_GetState(m))
|
|
1714
|
+
#else
|
|
1715
|
+
#define GETSTATE(m) (&_state)
|
|
1716
|
+
static struct module_state _state;
|
|
1717
|
+
#endif
|
|
1718
|
+
|
|
1719
|
+
// end
|
|
1720
|
+
PyMemberDef Element_members[] = {
|
|
1721
|
+
{"type", T_INT, offsetof(Element, element_type), 0,
|
|
1722
|
+
"group type"},
|
|
1723
|
+
{"initialized", T_INT, offsetof(Element, elem_initialized), 0,
|
|
1724
|
+
"determine initialization status"},
|
|
1725
|
+
{NULL} /* Sentinel */
|
|
1726
|
+
};
|
|
1727
|
+
|
|
1728
|
+
PyMethodDef Element_methods[] = {
|
|
1729
|
+
{"initPP", (PyCFunction)Element_initPP, METH_NOARGS, "Initialize the pre-processing field of element."},
|
|
1730
|
+
{"set", (PyCFunction)Element_set, METH_VARARGS, "Set an element to a fixed value."},
|
|
1731
|
+
{NULL} /* Sentinel */
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1734
|
+
PyMethodDef pairing_methods[] = {
|
|
1735
|
+
{"init", (PyCFunction)Element_elem, METH_VARARGS, "Create an element in group ZR and optionally set value."},
|
|
1736
|
+
{"pair", (PyCFunction)Apply_pairing, METH_VARARGS, "Apply pairing between an element of G1 and G2 and returns an element mapped to GT"},
|
|
1737
|
+
{"hashPair", (PyCFunction)sha2_hash, METH_VARARGS, "Compute a sha1 hash of an element type"},
|
|
1738
|
+
{"H", (PyCFunction)Element_hash, METH_VARARGS, "Hash an element type to a specific field: Zr, G1, or G2"},
|
|
1739
|
+
{"random", (PyCFunction)Element_random, METH_VARARGS, "Return a random element in a specific group: G1, G2, Zr"},
|
|
1740
|
+
{"serialize", (PyCFunction)Serialize_cmp, METH_VARARGS, "Serialize an element type into bytes."},
|
|
1741
|
+
{"deserialize", (PyCFunction)Deserialize_cmp, METH_VARARGS, "De-serialize an bytes object into an element object"},
|
|
1742
|
+
{"ismember", (PyCFunction) Group_Check, METH_VARARGS, "Group membership test for element objects."},
|
|
1743
|
+
{"order", (PyCFunction) Get_Order, METH_VARARGS, "Get the group order for a particular field."},
|
|
1744
|
+
#ifdef BENCHMARK_ENABLED
|
|
1745
|
+
{"InitBenchmark", (PyCFunction)InitBenchmark, METH_VARARGS, "Initialize a benchmark object"},
|
|
1746
|
+
{"StartBenchmark", (PyCFunction)StartBenchmark, METH_VARARGS, "Start a new benchmark with some options"},
|
|
1747
|
+
{"EndBenchmark", (PyCFunction)EndBenchmark, METH_VARARGS, "End a given benchmark"},
|
|
1748
|
+
{"GetBenchmark", (PyCFunction)GetBenchmark, METH_VARARGS, "Returns contents of a benchmark object"},
|
|
1749
|
+
{"GetGeneralBenchmarks", (PyCFunction)GetAllBenchmarks, METH_VARARGS, "Retrieve general benchmark info as a dictionary"},
|
|
1750
|
+
{"GetGranularBenchmarks", (PyCFunction) GranularBenchmark, METH_VARARGS, "Retrieve granular benchmarks as a dictionary"},
|
|
1751
|
+
#endif
|
|
1752
|
+
{NULL} /* Sentinel */
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1756
|
+
static int pairings_traverse(PyObject *m, visitproc visit, void *arg) {
|
|
1757
|
+
Py_VISIT(GETSTATE(m)->error);
|
|
1758
|
+
return 0;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
static int pairings_clear(PyObject *m) {
|
|
1762
|
+
Py_CLEAR(GETSTATE(m)->error);
|
|
1763
|
+
Py_XDECREF(ElementError);
|
|
1764
|
+
return 0;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
static int pairings_free(PyObject *m) {
|
|
1768
|
+
return 0;
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
static struct PyModuleDef moduledef = {
|
|
1772
|
+
PyModuleDef_HEAD_INIT,
|
|
1773
|
+
"pairing",
|
|
1774
|
+
NULL,
|
|
1775
|
+
sizeof(struct module_state),
|
|
1776
|
+
pairing_methods,
|
|
1777
|
+
NULL,
|
|
1778
|
+
pairings_traverse,
|
|
1779
|
+
(inquiry) pairings_clear, // clear function to call during GC clearing of the module object
|
|
1780
|
+
(freefunc) pairings_free //
|
|
1781
|
+
};
|
|
1782
|
+
|
|
1783
|
+
#define CLEAN_EXIT goto LEAVE;
|
|
1784
|
+
#define INITERROR return NULL
|
|
1785
|
+
PyMODINIT_FUNC
|
|
1786
|
+
PyInit_pairing(void) {
|
|
1787
|
+
#else
|
|
1788
|
+
#define CLEAN_EXIT goto LEAVE;
|
|
1789
|
+
#define INITERROR return
|
|
1790
|
+
void initpairing(void) {
|
|
1791
|
+
#endif
|
|
1792
|
+
PyObject* m;
|
|
1793
|
+
|
|
1794
|
+
if(PyType_Ready(&PairingType) < 0)
|
|
1795
|
+
CLEAN_EXIT;
|
|
1796
|
+
if(PyType_Ready(&ElementType) < 0)
|
|
1797
|
+
CLEAN_EXIT;
|
|
1798
|
+
#ifdef BENCHMARK_ENABLED
|
|
1799
|
+
if(import_benchmark() < 0)
|
|
1800
|
+
CLEAN_EXIT;
|
|
1801
|
+
if(PyType_Ready(&BenchmarkType) < 0)
|
|
1802
|
+
CLEAN_EXIT;
|
|
1803
|
+
if(PyType_Ready(&OperationsType) < 0)
|
|
1804
|
+
CLEAN_EXIT;
|
|
1805
|
+
#endif
|
|
1806
|
+
|
|
1807
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1808
|
+
m = PyModule_Create(&moduledef);
|
|
1809
|
+
#else
|
|
1810
|
+
m = Py_InitModule("pairing", pairing_methods);
|
|
1811
|
+
#endif
|
|
1812
|
+
|
|
1813
|
+
struct module_state *st = GETSTATE(m);
|
|
1814
|
+
st->error = PyErr_NewException("pairing.Error", NULL, NULL);
|
|
1815
|
+
if(st->error == NULL)
|
|
1816
|
+
CLEAN_EXIT;
|
|
1817
|
+
ElementError = st->error;
|
|
1818
|
+
Py_INCREF(ElementError);
|
|
1819
|
+
|
|
1820
|
+
Py_INCREF(&ElementType);
|
|
1821
|
+
PyModule_AddObject(m, "pc_element", (PyObject *)&ElementType);
|
|
1822
|
+
Py_INCREF(&PairingType);
|
|
1823
|
+
PyModule_AddObject(m, "pairing", (PyObject *)&PairingType);
|
|
1824
|
+
|
|
1825
|
+
PyModule_AddIntConstant(m, "ZR", ZR);
|
|
1826
|
+
PyModule_AddIntConstant(m, "G1", G1);
|
|
1827
|
+
PyModule_AddIntConstant(m, "G2", G2);
|
|
1828
|
+
PyModule_AddIntConstant(m, "GT", GT);
|
|
1829
|
+
|
|
1830
|
+
#ifdef BENCHMARK_ENABLED
|
|
1831
|
+
ADD_BENCHMARK_OPTIONS(m);
|
|
1832
|
+
PyModule_AddStringConstant(m, "Pair", _PAIR_OPT);
|
|
1833
|
+
PyModule_AddStringConstant(m, "Granular", _GRAN_OPT);
|
|
1834
|
+
#endif
|
|
1835
|
+
|
|
1836
|
+
/* only supporting one for now */
|
|
1837
|
+
PyModule_AddIntConstant(m, "BN158", 0);
|
|
1838
|
+
PyModule_AddIntConstant(m, "BN254", 1);
|
|
1839
|
+
PyModule_AddIntConstant(m, "BN256", 2);
|
|
1840
|
+
// PyModule_AddIntConstant(m, "BN638", 3);
|
|
1841
|
+
// PyModule_AddIntConstant(m, "KSS508",4);
|
|
1842
|
+
|
|
1843
|
+
LEAVE:
|
|
1844
|
+
if (PyErr_Occurred()) {
|
|
1845
|
+
PyErr_Clear();
|
|
1846
|
+
Py_XDECREF(m);
|
|
1847
|
+
INITERROR;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
#if PY_MAJOR_VERSION >= 3
|
|
1851
|
+
return m;
|
|
1852
|
+
#endif
|
|
1853
|
+
}
|