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