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.
Files changed (323) hide show
  1. charm/__init__.py +5 -0
  2. charm/adapters/__init__.py +0 -0
  3. charm/adapters/abenc_adapt_hybrid.py +90 -0
  4. charm/adapters/dabenc_adapt_hybrid.py +145 -0
  5. charm/adapters/ibenc_adapt_hybrid.py +72 -0
  6. charm/adapters/ibenc_adapt_identityhash.py +80 -0
  7. charm/adapters/kpabenc_adapt_hybrid.py +91 -0
  8. charm/adapters/pkenc_adapt_bchk05.py +121 -0
  9. charm/adapters/pkenc_adapt_chk04.py +91 -0
  10. charm/adapters/pkenc_adapt_hybrid.py +98 -0
  11. charm/adapters/pksig_adapt_naor01.py +89 -0
  12. charm/config.py +7 -0
  13. charm/core/__init__.py +0 -0
  14. charm/core/benchmark/benchmark_util.c +353 -0
  15. charm/core/benchmark/benchmark_util.h +61 -0
  16. charm/core/benchmark/benchmarkmodule.c +476 -0
  17. charm/core/benchmark/benchmarkmodule.h +162 -0
  18. charm/core/benchmark.cpython-313-darwin.so +0 -0
  19. charm/core/crypto/AES/AES.c +1464 -0
  20. charm/core/crypto/AES.cpython-313-darwin.so +0 -0
  21. charm/core/crypto/DES/DES.c +113 -0
  22. charm/core/crypto/DES.cpython-313-darwin.so +0 -0
  23. charm/core/crypto/DES3/DES3.c +26 -0
  24. charm/core/crypto/DES3.cpython-313-darwin.so +0 -0
  25. charm/core/crypto/__init__.py +0 -0
  26. charm/core/crypto/cryptobase/XOR.c +80 -0
  27. charm/core/crypto/cryptobase/_counter.c +496 -0
  28. charm/core/crypto/cryptobase/_counter.h +54 -0
  29. charm/core/crypto/cryptobase/block_template.c +900 -0
  30. charm/core/crypto/cryptobase/block_template.h +69 -0
  31. charm/core/crypto/cryptobase/cryptobasemodule.c +220 -0
  32. charm/core/crypto/cryptobase/libtom/tomcrypt.h +90 -0
  33. charm/core/crypto/cryptobase/libtom/tomcrypt_argchk.h +44 -0
  34. charm/core/crypto/cryptobase/libtom/tomcrypt_cfg.h +186 -0
  35. charm/core/crypto/cryptobase/libtom/tomcrypt_cipher.h +941 -0
  36. charm/core/crypto/cryptobase/libtom/tomcrypt_custom.h +556 -0
  37. charm/core/crypto/cryptobase/libtom/tomcrypt_des.c +1912 -0
  38. charm/core/crypto/cryptobase/libtom/tomcrypt_hash.h +407 -0
  39. charm/core/crypto/cryptobase/libtom/tomcrypt_mac.h +496 -0
  40. charm/core/crypto/cryptobase/libtom/tomcrypt_macros.h +435 -0
  41. charm/core/crypto/cryptobase/libtom/tomcrypt_math.h +534 -0
  42. charm/core/crypto/cryptobase/libtom/tomcrypt_misc.h +103 -0
  43. charm/core/crypto/cryptobase/libtom/tomcrypt_pk.h +653 -0
  44. charm/core/crypto/cryptobase/libtom/tomcrypt_pkcs.h +90 -0
  45. charm/core/crypto/cryptobase/libtom/tomcrypt_prng.h +199 -0
  46. charm/core/crypto/cryptobase/stream_template.c +271 -0
  47. charm/core/crypto/cryptobase/strxor.c +229 -0
  48. charm/core/crypto/cryptobase.cpython-313-darwin.so +0 -0
  49. charm/core/engine/__init__.py +5 -0
  50. charm/core/engine/protocol.py +293 -0
  51. charm/core/engine/util.py +174 -0
  52. charm/core/math/__init__.py +0 -0
  53. charm/core/math/elliptic_curve/ecmodule.c +1986 -0
  54. charm/core/math/elliptic_curve/ecmodule.h +230 -0
  55. charm/core/math/elliptic_curve.cpython-313-darwin.so +0 -0
  56. charm/core/math/elliptic_curve.pyi +63 -0
  57. charm/core/math/integer/integermodule.c +2539 -0
  58. charm/core/math/integer/integermodule.h +145 -0
  59. charm/core/math/integer.cpython-313-darwin.so +0 -0
  60. charm/core/math/integer.pyi +76 -0
  61. charm/core/math/pairing/miracl/miracl_config.h +37 -0
  62. charm/core/math/pairing/miracl/miracl_interface.h +118 -0
  63. charm/core/math/pairing/miracl/miracl_interface2.h +126 -0
  64. charm/core/math/pairing/miracl/pairingmodule2.c +2094 -0
  65. charm/core/math/pairing/miracl/pairingmodule2.h +307 -0
  66. charm/core/math/pairing/pairingmodule.c +2230 -0
  67. charm/core/math/pairing/pairingmodule.h +241 -0
  68. charm/core/math/pairing/relic/pairingmodule3.c +1853 -0
  69. charm/core/math/pairing/relic/pairingmodule3.h +233 -0
  70. charm/core/math/pairing/relic/relic_interface.c +1337 -0
  71. charm/core/math/pairing/relic/relic_interface.h +217 -0
  72. charm/core/math/pairing/relic/test_relic.c +171 -0
  73. charm/core/math/pairing.cpython-313-darwin.so +0 -0
  74. charm/core/math/pairing.pyi +69 -0
  75. charm/core/utilities/base64.c +248 -0
  76. charm/core/utilities/base64.h +15 -0
  77. charm/schemes/__init__.py +0 -0
  78. charm/schemes/abenc/__init__.py +0 -0
  79. charm/schemes/abenc/abenc_accountability_jyjxgd20.py +647 -0
  80. charm/schemes/abenc/abenc_bsw07.py +146 -0
  81. charm/schemes/abenc/abenc_ca_cpabe_ar17.py +684 -0
  82. charm/schemes/abenc/abenc_dacmacs_yj14.py +298 -0
  83. charm/schemes/abenc/abenc_lsw08.py +159 -0
  84. charm/schemes/abenc/abenc_maabe_rw15.py +236 -0
  85. charm/schemes/abenc/abenc_maabe_yj14.py +297 -0
  86. charm/schemes/abenc/abenc_tbpre_lww14.py +309 -0
  87. charm/schemes/abenc/abenc_unmcpabe_yahk14.py +223 -0
  88. charm/schemes/abenc/abenc_waters09.py +144 -0
  89. charm/schemes/abenc/abenc_yct14.py +208 -0
  90. charm/schemes/abenc/abenc_yllc15.py +178 -0
  91. charm/schemes/abenc/ac17.py +248 -0
  92. charm/schemes/abenc/bsw07.py +141 -0
  93. charm/schemes/abenc/cgw15.py +277 -0
  94. charm/schemes/abenc/dabe_aw11.py +204 -0
  95. charm/schemes/abenc/dfa_fe12.py +144 -0
  96. charm/schemes/abenc/pk_hve08.py +179 -0
  97. charm/schemes/abenc/waters11.py +143 -0
  98. charm/schemes/aggrsign_MuSig.py +150 -0
  99. charm/schemes/aggrsign_bls.py +267 -0
  100. charm/schemes/blindsig_ps16.py +654 -0
  101. charm/schemes/chamhash_adm05.py +113 -0
  102. charm/schemes/chamhash_rsa_hw09.py +100 -0
  103. charm/schemes/commit/__init__.py +0 -0
  104. charm/schemes/commit/commit_gs08.py +77 -0
  105. charm/schemes/commit/commit_pedersen92.py +53 -0
  106. charm/schemes/encap_bchk05.py +62 -0
  107. charm/schemes/grpsig/__init__.py +0 -0
  108. charm/schemes/grpsig/groupsig_bgls04.py +114 -0
  109. charm/schemes/grpsig/groupsig_bgls04_var.py +115 -0
  110. charm/schemes/hibenc/__init__.py +0 -0
  111. charm/schemes/hibenc/hibenc_bb04.py +105 -0
  112. charm/schemes/hibenc/hibenc_lew11.py +193 -0
  113. charm/schemes/ibenc/__init__.py +0 -0
  114. charm/schemes/ibenc/clpkc_rp03.py +119 -0
  115. charm/schemes/ibenc/ibenc_CW13_z.py +168 -0
  116. charm/schemes/ibenc/ibenc_bb03.py +94 -0
  117. charm/schemes/ibenc/ibenc_bf01.py +121 -0
  118. charm/schemes/ibenc/ibenc_ckrs09.py +120 -0
  119. charm/schemes/ibenc/ibenc_cllww12_z.py +172 -0
  120. charm/schemes/ibenc/ibenc_lsw08.py +120 -0
  121. charm/schemes/ibenc/ibenc_sw05.py +238 -0
  122. charm/schemes/ibenc/ibenc_waters05.py +144 -0
  123. charm/schemes/ibenc/ibenc_waters05_z.py +164 -0
  124. charm/schemes/ibenc/ibenc_waters09.py +107 -0
  125. charm/schemes/ibenc/ibenc_waters09_z.py +147 -0
  126. charm/schemes/joye_scheme.py +106 -0
  127. charm/schemes/lem_scheme.py +207 -0
  128. charm/schemes/pk_fre_ccv11.py +107 -0
  129. charm/schemes/pk_vrf.py +127 -0
  130. charm/schemes/pkenc/__init__.py +0 -0
  131. charm/schemes/pkenc/pkenc_cs98.py +108 -0
  132. charm/schemes/pkenc/pkenc_elgamal85.py +122 -0
  133. charm/schemes/pkenc/pkenc_gm82.py +98 -0
  134. charm/schemes/pkenc/pkenc_paillier99.py +118 -0
  135. charm/schemes/pkenc/pkenc_rabin.py +254 -0
  136. charm/schemes/pkenc/pkenc_rsa.py +186 -0
  137. charm/schemes/pksig/__init__.py +0 -0
  138. charm/schemes/pksig/pksig_CW13_z.py +135 -0
  139. charm/schemes/pksig/pksig_bls04.py +87 -0
  140. charm/schemes/pksig/pksig_boyen.py +156 -0
  141. charm/schemes/pksig/pksig_chch.py +97 -0
  142. charm/schemes/pksig/pksig_chp.py +70 -0
  143. charm/schemes/pksig/pksig_cl03.py +150 -0
  144. charm/schemes/pksig/pksig_cl04.py +87 -0
  145. charm/schemes/pksig/pksig_cllww12_z.py +142 -0
  146. charm/schemes/pksig/pksig_cyh.py +132 -0
  147. charm/schemes/pksig/pksig_dsa.py +76 -0
  148. charm/schemes/pksig/pksig_ecdsa.py +71 -0
  149. charm/schemes/pksig/pksig_hess.py +104 -0
  150. charm/schemes/pksig/pksig_hw.py +110 -0
  151. charm/schemes/pksig/pksig_lamport.py +63 -0
  152. charm/schemes/pksig/pksig_ps01.py +135 -0
  153. charm/schemes/pksig/pksig_ps02.py +124 -0
  154. charm/schemes/pksig/pksig_ps03.py +119 -0
  155. charm/schemes/pksig/pksig_rsa_hw09.py +206 -0
  156. charm/schemes/pksig/pksig_schnorr91.py +77 -0
  157. charm/schemes/pksig/pksig_waters.py +115 -0
  158. charm/schemes/pksig/pksig_waters05.py +121 -0
  159. charm/schemes/pksig/pksig_waters09.py +121 -0
  160. charm/schemes/pre_mg07.py +150 -0
  161. charm/schemes/prenc/pre_afgh06.py +126 -0
  162. charm/schemes/prenc/pre_bbs98.py +123 -0
  163. charm/schemes/prenc/pre_nal16.py +216 -0
  164. charm/schemes/protocol_a01.py +272 -0
  165. charm/schemes/protocol_ao00.py +215 -0
  166. charm/schemes/protocol_cns07.py +274 -0
  167. charm/schemes/protocol_schnorr91.py +125 -0
  168. charm/schemes/sigma1.py +64 -0
  169. charm/schemes/sigma2.py +129 -0
  170. charm/schemes/sigma3.py +126 -0
  171. charm/schemes/threshold/__init__.py +59 -0
  172. charm/schemes/threshold/dkls23_dkg.py +556 -0
  173. charm/schemes/threshold/dkls23_presign.py +1089 -0
  174. charm/schemes/threshold/dkls23_sign.py +761 -0
  175. charm/schemes/threshold/xrpl_wallet.py +967 -0
  176. charm/test/__init__.py +0 -0
  177. charm/test/adapters/__init__.py +0 -0
  178. charm/test/adapters/abenc_adapt_hybrid_test.py +29 -0
  179. charm/test/adapters/dabenc_adapt_hybrid_test.py +56 -0
  180. charm/test/adapters/ibenc_adapt_hybrid_test.py +36 -0
  181. charm/test/adapters/ibenc_adapt_identityhash_test.py +32 -0
  182. charm/test/adapters/kpabenc_adapt_hybrid_test.py +30 -0
  183. charm/test/benchmark/abenc_yllc15_bench.py +92 -0
  184. charm/test/benchmark/benchmark_test.py +148 -0
  185. charm/test/benchmark_threshold.py +260 -0
  186. charm/test/conftest.py +38 -0
  187. charm/test/fuzz/__init__.py +1 -0
  188. charm/test/fuzz/conftest.py +5 -0
  189. charm/test/fuzz/fuzz_policy_parser.py +76 -0
  190. charm/test/fuzz/fuzz_serialization.py +83 -0
  191. charm/test/schemes/__init__.py +0 -0
  192. charm/test/schemes/abenc/__init__.py +0 -0
  193. charm/test/schemes/abenc/abenc_bsw07_test.py +39 -0
  194. charm/test/schemes/abenc/abenc_dacmacs_yj14_test.py +16 -0
  195. charm/test/schemes/abenc/abenc_lsw08_test.py +33 -0
  196. charm/test/schemes/abenc/abenc_maabe_yj14_test.py +16 -0
  197. charm/test/schemes/abenc/abenc_tbpre_lww14_test.py +16 -0
  198. charm/test/schemes/abenc/abenc_waters09_test.py +38 -0
  199. charm/test/schemes/abenc/abenc_yllc15_test.py +74 -0
  200. charm/test/schemes/chamhash_adm05_test.py +31 -0
  201. charm/test/schemes/chamhash_rsa_hw09_test.py +29 -0
  202. charm/test/schemes/commit/__init__.py +0 -0
  203. charm/test/schemes/commit/commit_gs08_test.py +24 -0
  204. charm/test/schemes/commit/commit_pedersen92_test.py +26 -0
  205. charm/test/schemes/dabe_aw11_test.py +45 -0
  206. charm/test/schemes/encap_bchk05_test.py +21 -0
  207. charm/test/schemes/grpsig/__init__.py +0 -0
  208. charm/test/schemes/grpsig/groupsig_bgls04_test.py +35 -0
  209. charm/test/schemes/grpsig/groupsig_bgls04_var_test.py +39 -0
  210. charm/test/schemes/hibenc/__init__.py +0 -0
  211. charm/test/schemes/hibenc/hibenc_bb04_test.py +28 -0
  212. charm/test/schemes/ibenc/__init__.py +0 -0
  213. charm/test/schemes/ibenc/ibenc_bb03_test.py +26 -0
  214. charm/test/schemes/ibenc/ibenc_bf01_test.py +24 -0
  215. charm/test/schemes/ibenc/ibenc_ckrs09_test.py +25 -0
  216. charm/test/schemes/ibenc/ibenc_lsw08_test.py +31 -0
  217. charm/test/schemes/ibenc/ibenc_sw05_test.py +32 -0
  218. charm/test/schemes/ibenc/ibenc_waters05_test.py +31 -0
  219. charm/test/schemes/ibenc/ibenc_waters09_test.py +27 -0
  220. charm/test/schemes/pk_vrf_test.py +29 -0
  221. charm/test/schemes/pkenc/__init__.py +0 -0
  222. charm/test/schemes/pkenc_test.py +255 -0
  223. charm/test/schemes/pksig/__init__.py +0 -0
  224. charm/test/schemes/pksig_test.py +376 -0
  225. charm/test/schemes/rsa_alg_test.py +340 -0
  226. charm/test/schemes/threshold_test.py +1792 -0
  227. charm/test/serialize/__init__.py +0 -0
  228. charm/test/serialize/serialize_test.py +40 -0
  229. charm/test/toolbox/__init__.py +0 -0
  230. charm/test/toolbox/conversion_test.py +30 -0
  231. charm/test/toolbox/ecgroup_test.py +53 -0
  232. charm/test/toolbox/integer_arithmetic_test.py +441 -0
  233. charm/test/toolbox/paddingschemes_test.py +238 -0
  234. charm/test/toolbox/policy_parser_stress_test.py +969 -0
  235. charm/test/toolbox/secretshare_test.py +28 -0
  236. charm/test/toolbox/symcrypto_test.py +108 -0
  237. charm/test/toolbox/test_policy_expression.py +16 -0
  238. charm/test/vectors/__init__.py +1 -0
  239. charm/test/vectors/test_bls_vectors.py +289 -0
  240. charm/test/vectors/test_pedersen_vectors.py +315 -0
  241. charm/test/vectors/test_schnorr_vectors.py +368 -0
  242. charm/test/zkp_compiler/__init__.py +9 -0
  243. charm/test/zkp_compiler/benchmark_zkp.py +258 -0
  244. charm/test/zkp_compiler/test_and_proof.py +240 -0
  245. charm/test/zkp_compiler/test_batch_verify.py +248 -0
  246. charm/test/zkp_compiler/test_dleq_proof.py +264 -0
  247. charm/test/zkp_compiler/test_or_proof.py +231 -0
  248. charm/test/zkp_compiler/test_proof_serialization.py +121 -0
  249. charm/test/zkp_compiler/test_range_proof.py +241 -0
  250. charm/test/zkp_compiler/test_representation_proof.py +325 -0
  251. charm/test/zkp_compiler/test_schnorr_proof.py +221 -0
  252. charm/test/zkp_compiler/test_thread_safety.py +169 -0
  253. charm/test/zkp_compiler/test_zkp_parser.py +139 -0
  254. charm/toolbox/ABEnc.py +26 -0
  255. charm/toolbox/ABEncMultiAuth.py +66 -0
  256. charm/toolbox/ABEnumeric.py +800 -0
  257. charm/toolbox/Commit.py +24 -0
  258. charm/toolbox/DFA.py +89 -0
  259. charm/toolbox/FSA.py +1254 -0
  260. charm/toolbox/Hash.py +39 -0
  261. charm/toolbox/IBEnc.py +62 -0
  262. charm/toolbox/IBSig.py +64 -0
  263. charm/toolbox/PKEnc.py +66 -0
  264. charm/toolbox/PKSig.py +56 -0
  265. charm/toolbox/PREnc.py +32 -0
  266. charm/toolbox/ZKProof.py +289 -0
  267. charm/toolbox/__init__.py +0 -0
  268. charm/toolbox/bitstring.py +49 -0
  269. charm/toolbox/broadcast.py +220 -0
  270. charm/toolbox/conversion.py +100 -0
  271. charm/toolbox/eccurve.py +149 -0
  272. charm/toolbox/ecgroup.py +143 -0
  273. charm/toolbox/enum.py +60 -0
  274. charm/toolbox/hash_module.py +91 -0
  275. charm/toolbox/integergroup.py +323 -0
  276. charm/toolbox/iterate.py +22 -0
  277. charm/toolbox/matrixops.py +76 -0
  278. charm/toolbox/mpc_utils.py +296 -0
  279. charm/toolbox/msp.py +175 -0
  280. charm/toolbox/mta.py +985 -0
  281. charm/toolbox/node.py +120 -0
  282. charm/toolbox/ot/__init__.py +22 -0
  283. charm/toolbox/ot/base_ot.py +374 -0
  284. charm/toolbox/ot/dpf.py +642 -0
  285. charm/toolbox/ot/mpfss.py +228 -0
  286. charm/toolbox/ot/ot_extension.py +589 -0
  287. charm/toolbox/ot/silent_ot.py +378 -0
  288. charm/toolbox/paddingschemes.py +423 -0
  289. charm/toolbox/paddingschemes_test.py +238 -0
  290. charm/toolbox/pairingcurves.py +85 -0
  291. charm/toolbox/pairinggroup.py +186 -0
  292. charm/toolbox/policy_expression_spec.py +70 -0
  293. charm/toolbox/policytree.py +189 -0
  294. charm/toolbox/reCompiler.py +346 -0
  295. charm/toolbox/redundancyschemes.py +65 -0
  296. charm/toolbox/schemebase.py +188 -0
  297. charm/toolbox/secretshare.py +104 -0
  298. charm/toolbox/secretutil.py +174 -0
  299. charm/toolbox/securerandom.py +73 -0
  300. charm/toolbox/sigmaprotocol.py +46 -0
  301. charm/toolbox/specialprimes.py +45 -0
  302. charm/toolbox/symcrypto.py +279 -0
  303. charm/toolbox/threshold_sharing.py +553 -0
  304. charm/toolbox/xmlserialize.py +94 -0
  305. charm/toolbox/zknode.py +105 -0
  306. charm/zkp_compiler/__init__.py +89 -0
  307. charm/zkp_compiler/and_proof.py +460 -0
  308. charm/zkp_compiler/batch_verify.py +324 -0
  309. charm/zkp_compiler/dleq_proof.py +423 -0
  310. charm/zkp_compiler/or_proof.py +305 -0
  311. charm/zkp_compiler/range_proof.py +417 -0
  312. charm/zkp_compiler/representation_proof.py +466 -0
  313. charm/zkp_compiler/schnorr_proof.py +273 -0
  314. charm/zkp_compiler/thread_safe.py +150 -0
  315. charm/zkp_compiler/zk_demo.py +489 -0
  316. charm/zkp_compiler/zkp_factory.py +330 -0
  317. charm/zkp_compiler/zkp_generator.py +370 -0
  318. charm/zkp_compiler/zkparser.py +269 -0
  319. charm_crypto_framework-0.61.1.dist-info/METADATA +337 -0
  320. charm_crypto_framework-0.61.1.dist-info/RECORD +323 -0
  321. charm_crypto_framework-0.61.1.dist-info/WHEEL +5 -0
  322. charm_crypto_framework-0.61.1.dist-info/licenses/LICENSE.txt +165 -0
  323. 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
+ }