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,330 @@
1
+ """
2
+ Factory for creating ZK proof instances without dynamic code execution.
3
+
4
+ This module provides a safe alternative to the exec()-based code generation
5
+ in zkp_generator.py, eliminating code injection vulnerabilities.
6
+ """
7
+
8
+ import logging
9
+ import re
10
+ from charm.zkp_compiler.zkparser import ZKParser
11
+ from charm.zkp_compiler.schnorr_proof import SchnorrProof, Proof
12
+ from charm.zkp_compiler.dleq_proof import DLEQProof
13
+ from charm.toolbox.ZKProof import ZKProofBase, ZKParseError, ZKValidationError
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ # Allowed characters in ZK statements
18
+ _VALID_STATEMENT_PATTERN = re.compile(r'^[\w\s\^\=\(\)\*]+$')
19
+
20
+
21
+ def validate_statement(statement):
22
+ """
23
+ Validate a ZK statement string.
24
+
25
+ Checks for valid characters and prevents injection attacks.
26
+
27
+ Args:
28
+ statement: The ZK statement string to validate
29
+
30
+ Raises:
31
+ ZKValidationError: If statement is invalid or contains suspicious characters
32
+ """
33
+ if not isinstance(statement, str):
34
+ raise ZKValidationError("Statement must be a string")
35
+
36
+ if not statement.strip():
37
+ raise ZKValidationError("Statement cannot be empty")
38
+
39
+ if not _VALID_STATEMENT_PATTERN.match(statement):
40
+ raise ZKValidationError(
41
+ "Statement contains invalid characters. "
42
+ "Only alphanumeric characters, ^, =, *, (, ), and whitespace are allowed."
43
+ )
44
+
45
+ # Check for suspicious patterns that might indicate injection attempts
46
+ suspicious_patterns = ['__', 'import', 'exec', 'eval', 'compile', 'open', 'file']
47
+ statement_lower = statement.lower()
48
+ for pattern in suspicious_patterns:
49
+ if pattern in statement_lower:
50
+ raise ZKValidationError(f"Statement contains suspicious pattern: {pattern}")
51
+
52
+ logger.debug("Statement validated: %s", statement)
53
+
54
+
55
+ class SchnorrProofInstance:
56
+ """
57
+ Wrapper that provides a clean API for Schnorr proofs.
58
+
59
+ Encapsulates the generator, public value, and optionally secret,
60
+ providing prove() and verify() methods.
61
+ """
62
+
63
+ def __init__(self, group, g, h, secret_x=None):
64
+ """
65
+ Initialize a Schnorr proof instance.
66
+
67
+ Args:
68
+ group: The pairing group to use
69
+ g: The generator element
70
+ h: The public element (h = g^x)
71
+ secret_x: The secret exponent (required for proving, optional for verifying)
72
+ """
73
+ self.group = group
74
+ self.g = g
75
+ self.h = h
76
+ self._secret_x = secret_x
77
+
78
+ def prove(self, interactive=False):
79
+ """
80
+ Generate a proof (non-interactive by default).
81
+
82
+ Args:
83
+ interactive: If True, raises an error (use create_interactive_prover instead)
84
+
85
+ Returns:
86
+ Proof object containing commitment, challenge, and response
87
+
88
+ Raises:
89
+ ZKValidationError: If secret is not available or interactive mode requested
90
+ """
91
+ if self._secret_x is None:
92
+ raise ZKValidationError("Cannot prove without secret")
93
+ if interactive:
94
+ raise ZKValidationError(
95
+ "For interactive proofs, use create_interactive_prover() instead"
96
+ )
97
+ return SchnorrProof.prove_non_interactive(
98
+ self.group, self.g, self.h, self._secret_x
99
+ )
100
+
101
+ def verify(self, proof):
102
+ """
103
+ Verify a proof.
104
+
105
+ Args:
106
+ proof: Proof object to verify
107
+
108
+ Returns:
109
+ True if proof is valid, False otherwise
110
+ """
111
+ return SchnorrProof.verify_non_interactive(
112
+ self.group, self.g, self.h, proof
113
+ )
114
+
115
+ def create_interactive_prover(self):
116
+ """
117
+ Create an interactive prover instance.
118
+
119
+ Returns:
120
+ SchnorrProof.Prover instance
121
+
122
+ Raises:
123
+ ZKValidationError: If secret is not available
124
+ """
125
+ if self._secret_x is None:
126
+ raise ZKValidationError("Cannot create prover without secret")
127
+ return SchnorrProof.Prover(self._secret_x, self.group)
128
+
129
+ def create_interactive_verifier(self):
130
+ """
131
+ Create an interactive verifier instance.
132
+
133
+ Returns:
134
+ SchnorrProof.Verifier instance
135
+ """
136
+ return SchnorrProof.Verifier(self.group)
137
+
138
+
139
+ class ZKProofFactory:
140
+ """
141
+ Factory for creating ZK proof instances without dynamic code execution.
142
+
143
+ This factory replaces the insecure exec()-based code generation with
144
+ direct class instantiation, eliminating code injection vulnerabilities.
145
+
146
+ Example:
147
+ >>> from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
148
+ >>> group = PairingGroup('SS512')
149
+ >>> g = group.random(G1)
150
+ >>> x = group.random(ZR)
151
+ >>> h = g ** x
152
+ >>>
153
+ >>> # Create a Schnorr proof instance
154
+ >>> proof_instance = ZKProofFactory.create_schnorr_proof(group, g, h, x)
155
+ >>> proof = proof_instance.prove()
156
+ >>> assert proof_instance.verify(proof)
157
+ """
158
+
159
+ @staticmethod
160
+ def create_schnorr_proof(group, g, h, secret_x=None):
161
+ """
162
+ Create a Schnorr proof instance for proving knowledge of discrete log.
163
+
164
+ Args:
165
+ group: The pairing group to use
166
+ g: The generator element
167
+ h: The public element (h = g^x)
168
+ secret_x: The secret exponent (required for proving, optional for verifying)
169
+
170
+ Returns:
171
+ SchnorrProofInstance: An instance that can prove or verify
172
+ """
173
+ logger.debug("Creating Schnorr proof instance")
174
+ return SchnorrProofInstance(group, g, h, secret_x)
175
+
176
+ @staticmethod
177
+ def create_from_statement(group, statement, public_params, secret_params=None):
178
+ """
179
+ Create a proof instance from a parsed ZK statement.
180
+
181
+ This method parses the statement and determines the appropriate
182
+ proof type, then creates the corresponding proof instance.
183
+
184
+ Args:
185
+ group: The pairing group to use
186
+ statement: A ZK statement string like "h = g^x"
187
+ public_params: Dict mapping variable names to public values
188
+ secret_params: Dict mapping variable names to secret values (optional)
189
+
190
+ Returns:
191
+ SchnorrProofInstance: An instance of the appropriate proof type
192
+
193
+ Raises:
194
+ ZKParseError: If the statement cannot be parsed
195
+ ZKValidationError: If required parameters are missing
196
+ """
197
+ # Validate statement first
198
+ validate_statement(statement)
199
+
200
+ # Parse the statement
201
+ try:
202
+ parser = ZKParser()
203
+ stmt_object = parser.parse(statement)
204
+ except Exception as e:
205
+ raise ZKParseError(f"Failed to parse statement: {e}") from e
206
+
207
+ # Extract required variables from the parsed statement
208
+ # For now, we support simple Schnorr-style statements: h = g^x
209
+ # The parser returns a tree structure that we need to analyze
210
+
211
+ if not isinstance(public_params, dict):
212
+ raise ZKValidationError("public_params must be a dictionary")
213
+
214
+ if secret_params is not None and not isinstance(secret_params, dict):
215
+ raise ZKValidationError("secret_params must be a dictionary")
216
+
217
+ # Check for required public parameters
218
+ if 'g' not in public_params:
219
+ raise ZKValidationError("Missing required public parameter: 'g' (generator)")
220
+ if 'h' not in public_params:
221
+ raise ZKValidationError("Missing required public parameter: 'h' (public value)")
222
+
223
+ g = public_params['g']
224
+ h = public_params['h']
225
+
226
+ # Get secret if available
227
+ secret_x = None
228
+ if secret_params and 'x' in secret_params:
229
+ secret_x = secret_params['x']
230
+
231
+ logger.debug("Created proof instance from statement: %s", statement)
232
+ return SchnorrProofInstance(group, g, h, secret_x)
233
+
234
+
235
+ def prove_and_verify_schnorr(group, g, h, x):
236
+ """
237
+ Proves and immediately verifies a Schnorr proof.
238
+
239
+ Useful for testing and debugging.
240
+
241
+ Args:
242
+ group: The pairing group to use
243
+ g: The generator element
244
+ h: The public element (h = g^x)
245
+ x: The secret exponent
246
+
247
+ Returns:
248
+ tuple: (proof, is_valid) where proof is the Proof object and is_valid is True if verification passed
249
+
250
+ Example::
251
+
252
+ group = PairingGroup('SS512')
253
+ g = group.random(G1)
254
+ x = group.random(ZR)
255
+ h = g ** x
256
+ proof, is_valid = prove_and_verify_schnorr(group, g, h, x)
257
+ assert is_valid
258
+ """
259
+ proof = SchnorrProof.prove_non_interactive(group, g, h, x)
260
+ is_valid = SchnorrProof.verify_non_interactive(group, g, h, proof)
261
+ return proof, is_valid
262
+
263
+
264
+ def prove_and_verify_dleq(group, g1, h1, g2, h2, x):
265
+ """
266
+ Proves and immediately verifies a DLEQ proof.
267
+
268
+ Useful for testing and debugging.
269
+
270
+ Args:
271
+ group: The pairing group to use
272
+ g1: The first generator element
273
+ h1: The first public element (h1 = g1^x)
274
+ g2: The second generator element
275
+ h2: The second public element (h2 = g2^x)
276
+ x: The secret exponent
277
+
278
+ Returns:
279
+ tuple: (proof, is_valid) where proof is the DLEQProofData object and is_valid is True if verification passed
280
+
281
+ Example::
282
+
283
+ group = PairingGroup('SS512')
284
+ g1 = group.random(G1)
285
+ g2 = group.random(G1)
286
+ x = group.random(ZR)
287
+ h1 = g1 ** x
288
+ h2 = g2 ** x
289
+ proof, is_valid = prove_and_verify_dleq(group, g1, h1, g2, h2, x)
290
+ assert is_valid
291
+ """
292
+ proof = DLEQProof.prove_non_interactive(group, g1, h1, g2, h2, x)
293
+ is_valid = DLEQProof.verify_non_interactive(group, g1, h1, g2, h2, proof)
294
+ return proof, is_valid
295
+
296
+
297
+ def configure_logging(level: str = 'WARNING') -> None:
298
+ """
299
+ Configure logging for all ZKP compiler modules.
300
+
301
+ Args:
302
+ level: Logging level ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
303
+
304
+ Example:
305
+ >>> from charm.zkp_compiler import configure_logging
306
+ >>> configure_logging('DEBUG') # Enable debug output
307
+ """
308
+ numeric_level = getattr(logging, level.upper(), logging.WARNING)
309
+
310
+ # Configure all ZKP module loggers
311
+ zkp_modules = [
312
+ 'charm.zkp_compiler.schnorr_proof',
313
+ 'charm.zkp_compiler.dleq_proof',
314
+ 'charm.zkp_compiler.representation_proof',
315
+ 'charm.zkp_compiler.and_proof',
316
+ 'charm.zkp_compiler.or_proof',
317
+ 'charm.zkp_compiler.range_proof',
318
+ 'charm.zkp_compiler.batch_verify',
319
+ ]
320
+
321
+ for module in zkp_modules:
322
+ module_logger = logging.getLogger(module)
323
+ module_logger.setLevel(numeric_level)
324
+ if not module_logger.handlers:
325
+ handler = logging.StreamHandler()
326
+ handler.setFormatter(logging.Formatter(
327
+ '%(name)s - %(levelname)s - %(message)s'
328
+ ))
329
+ module_logger.addHandler(handler)
330
+
@@ -0,0 +1,370 @@
1
+ """
2
+ Legacy ZKP Generator Module (DEPRECATED)
3
+ ========================================
4
+
5
+ .. deprecated:: 0.60
6
+ This module uses insecure dynamic code generation (exec/compile) which
7
+ can lead to code injection vulnerabilities. It will be removed in v0.80.
8
+
9
+ For production use, please migrate to the new secure API:
10
+
11
+ - :class:`charm.zkp_compiler.schnorr_proof.SchnorrProof`
12
+ - :class:`charm.zkp_compiler.dleq_proof.DLEQProof`
13
+ - :class:`charm.zkp_compiler.representation_proof.RepresentationProof`
14
+ - :class:`charm.zkp_compiler.zkp_factory.ZKProofFactory`
15
+
16
+ See the migration guide in doc/zkp_proof_types_design.md
17
+
18
+ Example Migration
19
+ -----------------
20
+ Old (deprecated)::
21
+
22
+ from charm.zkp_compiler.zkp_generator import executeIntZKProof
23
+ result = executeIntZKProof(public, secret, statement, party_info)
24
+
25
+ New (recommended)::
26
+
27
+ from charm.zkp_compiler.schnorr_proof import SchnorrProof
28
+ proof = SchnorrProof.prove_non_interactive(group, g, h, x)
29
+ is_valid = SchnorrProof.verify_non_interactive(group, g, h, proof)
30
+ """
31
+
32
+ import logging
33
+ import warnings
34
+
35
+ from pyparsing import *
36
+ from charm.zkp_compiler.zkparser import *
37
+ from charm.core.engine.protocol import *
38
+ from charm.core.engine.util import *
39
+ #from charm.core.math.pairing import *
40
+
41
+ # Emit deprecation warning when this module is imported
42
+ warnings.warn(
43
+ "The zkp_generator module is deprecated and will be removed in v0.80. "
44
+ "It uses insecure dynamic code execution (exec/compile). "
45
+ "Please migrate to charm.zkp_compiler.schnorr_proof or charm.zkp_compiler.zkp_factory. "
46
+ "See doc/zkp_proof_types_design.md for migration guide.",
47
+ DeprecationWarning,
48
+ stacklevel=2
49
+ )
50
+
51
+ # Set up logging instead of print statements
52
+ logger = logging.getLogger(__name__)
53
+
54
+ int_default = True
55
+
56
+ def newStateFunction(func_name, args=True):
57
+ if args:
58
+ return """\
59
+ def %s(self, input):\n""" % func_name
60
+ else:
61
+ return """\
62
+ def %s(self):\n""" % func_name
63
+
64
+ def addToCode(lines):
65
+ stmts = " " # 8 spaces
66
+ for stmt in lines:
67
+ if type(stmt) == str:
68
+ # print("Adding =>", stmt)
69
+ stmts += stmt + "; "
70
+ return stmts + "\n"
71
+
72
+ PROVER, VERIFIER = 1,2
73
+ # Handle a Schnorr HVZK proof-of-knowledge of a discrete logarithm
74
+ def KoDLFixedBase(publicDict, secretDict, baseVarKey, expVarKey, statesCode, interactive):
75
+ if type(publicDict) != dict or type(secretDict) != dict:
76
+ print("Type Error!"); return None
77
+
78
+ # First move of protocol: prover picks random integer "k", store k as a secret, output g^k
79
+ stateDef = newStateFunction("prover_state1", False)
80
+ # stateDef += addToCode(["print('State PROVER 1:')"]) # DEBUG
81
+ stateDef += addToCode(["pk = Protocol.get(self, "+str(list(publicDict.keys()))+", dict)"])
82
+ prov_keys, obj_ret, ver_keys2, ver_keys4 = "","", "", []
83
+ rand_elems,dl_elems,store_elems,non_int_def2 = [],[],[],""
84
+ for i in range(len(expVarKey)):
85
+ k = 'k' + str(i)
86
+ prov_keys += expVarKey[i]+","
87
+ rand_elems.append(k + " = self.group.random(ZR)")
88
+ dl_elems.append("val_"+ k + " = pk['" + baseVarKey + "'] ** " + k)
89
+ store_elems.append("Protocol.store(self, ('"+k+"',"+k+"), ('"+expVarKey[i]+"',"+expVarKey[i]+") )")
90
+ obj_ret += "'val_"+k+"':val_"+k+", "
91
+ ver_keys2 += ", ('val_"+k+"', input['val_"+k+"'])"
92
+ four = 'val_'+k
93
+ ver_keys4.append('%s' % four) # used in verify_state4
94
+ non_int_def2 += "input['%s']," % four # used for non-interactive in state def2
95
+ stateDef += addToCode(["("+prov_keys+") = Protocol.get(self, "+str(list(expVarKey))+")"])
96
+ stateDef += addToCode(rand_elems)
97
+ stateDef += addToCode(dl_elems)
98
+ stateDef += addToCode(store_elems)
99
+ stateDef += addToCode(["Protocol.setState(self, 3)","return {"+obj_ret+"'pk':pk }"])
100
+ statesCode += stateDef + "\n"
101
+
102
+ # Second move of protocol: verifier computes random challenge c, outputs c
103
+ stateDef2 = newStateFunction("verifier_state2")
104
+ c = 'c'
105
+ # stateDef2 += addToCode(["print('State VERIFIER 2:')"]) # DEBUG
106
+ if interactive == True:
107
+ stateDef2 += addToCode(["c = self.group.random(ZR)"])
108
+ else:
109
+ stateDef2 += addToCode(["c = self.group.hash(("+str(non_int_def2)+"), ZR)"])
110
+ stateDef2 += addToCode(["Protocol.store(self, ('c',c), ('pk',input['pk'])"+ ver_keys2 +" )",
111
+ "Protocol.setState(self, 4)", "return {'c':c}"])
112
+ statesCode += stateDef2 + "\n"
113
+
114
+ stateDef3 = newStateFunction("prover_state3")
115
+ # stateDef3 += addToCode(["print('State PROVER 3:')"]) # DEBUG
116
+ stateDef3 += addToCode(["c = input['c']"])
117
+ getVals, test_elems = "", ""
118
+ compute, ver_inputs = [],[]
119
+ prf_stmt = []
120
+ for i in range(len(expVarKey)):
121
+ z,k = 'z' + str(i),'k' + str(i)
122
+ getVals += "'"+ expVarKey[i] +"','"+k+"',"
123
+ compute.append(z + " = val['"+expVarKey[i]+"'] * c + val['"+k+"']")
124
+ test_elems += "'"+z+"':"+z+","
125
+ ver_inputs.append(z + " = input['"+z+"']")
126
+ prf_stmt.append("val['pk']['"+baseVarKey+"'] ** "+z) # used in verify_state4
127
+
128
+ stateDef3 += addToCode(["val = Protocol.get(self, ["+getVals+"], dict)"])
129
+ stateDef3 += addToCode(compute)
130
+ stateDef3 += addToCode(["Protocol.setState(self, 5)", "return {"+test_elems+"}"])
131
+ statesCode += stateDef3 + "\n"
132
+
133
+ stateDef4 = newStateFunction("verifier_state4")
134
+ # stateDef4 += addToCode(["print('State VERIFIER 4:')"]) # DEBUG
135
+ stateDef4 += addToCode(ver_inputs)
136
+ pk = ['pk']
137
+ pk.extend(ver_keys4); pk.append('c')
138
+
139
+ stateDef4 += addToCode(["val = Protocol.get(self, "+ str(pk) +", dict)"])
140
+ # need to compute g^z =?= g^k (val_k) * (pubkey)^c
141
+ verify4_stmt = []
142
+ for i in range(len(expVarKey)):
143
+ pub_key = secretDict[ expVarKey[i] ] # get pubkey for secret
144
+ verify4_stmt.append("\n if ("+ prf_stmt[i] + ") == " + "((val['pk']['"+pub_key+"'] ** val['c']) * val['"+ver_keys4[i]+"'] ): result = 'OK'\n else: result = 'FAIL'")
145
+ # verify4_stmt.append("print(val['pk']['g']); result = 'OK'")
146
+ stateDef4 += addToCode(verify4_stmt)
147
+ stateDef4 += addToCode(["Protocol.setState(self, 6)", "Protocol.setErrorCode(self, result)"] )
148
+ stateDef4 += addToCode(["print('Result => ',result); return result"])
149
+ statesCode += stateDef4 + "\n"
150
+
151
+ stateDef5 = newStateFunction("prover_state5")
152
+ # stateDef5 += addToCode(["print('State PROVER 5:')"]) # DEBUG
153
+ stateDef5 += addToCode(["Protocol.setState(self, None)", "Protocol.setErrorCode(self, input); return None"])
154
+ statesCode += stateDef5 + "\n"
155
+
156
+ stateDef6 = newStateFunction("verifier_state6")
157
+ # stateDef6 += addToCode(["print('State VERIFIER 6:')"]) # DEBUG
158
+ stateDef6 += addToCode(["Protocol.setState(self, None)", "return None"])
159
+ statesCode += stateDef6 + "\n"
160
+
161
+ # print("Finishing state 1 =>", statesCode)
162
+ # SECURITY: Removed filesystem write of generated code (tmpGenCode.py)
163
+ # The generated code is logged at DEBUG level for debugging purposes
164
+ logger.debug("Generated ZK proof code:\n%s", statesCode)
165
+
166
+ return statesCode
167
+
168
+
169
+ # Return a fixed preamble for an interactive ZK proof protocol.
170
+ def genIZKPreamble():
171
+ return """\
172
+ \nfrom charm.engine.protocol import *
173
+ from charm.engine.util import *
174
+ from socket import *
175
+ from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
176
+
177
+ class %s(Protocol):
178
+ def __init__(self, groupObj, common_input=None):
179
+ Protocol.__init__(self, None)
180
+ PROVER,VERIFIER = %s,%s
181
+ prover_states = { 1:self.prover_state1, 3:self.prover_state3, 5:self.prover_state5 }
182
+ verifier_states = { 2:self.verifier_state2, 4:self.verifier_state4, 6:self.verifier_state6 }
183
+ prover_trans = { 1:3, 3:5 }
184
+ verifier_trans = { 2:4, 4:6 }
185
+ # describe the parties involved and the valid transitions
186
+ Protocol.addPartyType(self, VERIFIER, verifier_states, verifier_trans)
187
+ Protocol.addPartyType(self, PROVER, prover_states, prover_trans, True)
188
+
189
+ # must pass in a group object parameter (allows us to operate in any setting)
190
+ self.group = groupObj
191
+
192
+ if common_input == None: # generate common parameters to P and V
193
+ db = {}
194
+ self.__gen_setup = True
195
+ else: # can be used as a sub-protocol if common_input is specified by caller
196
+ db = common_input
197
+ self.__gen_setup = False
198
+ self.PROVER, self.VERIFIER = PROVER, VERIFIER
199
+ Protocol.setSubclassVars(self, self.group, db)\n"""
200
+
201
+ # public contains a dictionary of the public group elements (keys appropriately labeled)
202
+ # secret contains a dictionary of the secret elements (keys must be appropriately labeled)
203
+ # statement is the statement for which we would like to prove via ZK and thus code
204
+ # we need to generate to prove the statement.
205
+ def parseAndGenerateCode(public, secretDict, statement, party_ID, interactive):
206
+ # parse the statement such that we know the baseVar, expName (secret)
207
+ output = genIZKPreamble()
208
+ output = output % ('ZKProof', PROVER, VERIFIER)
209
+
210
+ parser = ZKParser()
211
+ stmt_object = parser.parse(statement)
212
+ pk, sk = [], []
213
+ gen, sec = [], {}
214
+ extract(stmt_object, pk, sk, sec, gen)
215
+ # Get the preamble (including class definition and __init__ routine
216
+ # print("Public params...", pk)
217
+ # print("Secret keys...", sk)
218
+ # print("Secret key =>", sec)
219
+
220
+ baseVar = gen.pop() # NOTE: we only support one generator for now (i.e. 'g'), for more advanced
221
+ expSecret = sk # e.g. ['x', 'y',...]
222
+ secret = sec # mapping of secret to public key (e.g. {'x':'h', 'y':'j'}
223
+
224
+ # print("Input public =>", public)
225
+ # print("Input private =>", secret)
226
+
227
+ final_src = KoDLFixedBase(public, secret, baseVar, expSecret, output, interactive)
228
+ return final_src
229
+
230
+ def extract(node, pk, sk, sk_pk_map, gen):
231
+ if node.type == node.EXP:
232
+ # print("public =>", node.getLeft(), "in pk?")
233
+ # print("secret =>", node.getRight(), "in sk?")
234
+ if not node.getLeft() in pk:
235
+ pk.append(node.getLeft())
236
+ if not node.getLeft() in gen:
237
+ gen.append(node.getLeft()) # ONLY SUPPORT 1 generator (may need to re-arch generator to support multiple gens)
238
+ sk.append(node.getRight())
239
+
240
+ elif node.type == node.EQ:
241
+ # print("public =>", node.getLeft(), "in pk?")
242
+ extract(node.getRight(), pk, sk, sk_pk_map, gen)
243
+ sec_key = sk.pop()
244
+ sk_pk_map[sec_key] = node.getLeft()
245
+ sk.append(sec_key)
246
+ if not node.getLeft() in pk:
247
+ pk.append(node.getLeft())
248
+ elif node.type == node.AND:
249
+ extract(node.getLeft(), pk, sk, sk_pk_map, gen)
250
+ extract(node.getRight(), pk, sk, sk_pk_map, gen)
251
+ else:
252
+ return None
253
+ return None
254
+
255
+ # does tyep checking on the parsed statement object to determine
256
+ # 1) all the public keys (in stmt) appear in pk
257
+ # 2) all the secret keys (in stmt) appear in sk
258
+ def dict_check(node, pk, sk):
259
+ if node.type == node.EXP:
260
+ if not node.getLeft() in pk: return False
261
+ if not node.getRight() in sk: return False
262
+ elif node.type == node.EQ:
263
+ if not node.getLeft() in pk: return False
264
+ return dict_check(node.getRight(), pk, sk)
265
+ elif node.type == node.AND:
266
+ if dict_check(node.getLeft(), pk, sk) == False: return False
267
+ if dict_check(node.getRight(), pk, sk) == False: return False
268
+ elif node.type == node.OR:
269
+ if dict_check(node.getLeft(), pk, sk) or dict_check(node.getLeft(), pk, sk): return True
270
+ else: return False
271
+ return True
272
+
273
+ def write_out(name, prefix, value):
274
+ """Log debug output instead of writing to filesystem.
275
+
276
+ SECURITY: This function previously wrote to the filesystem, which could
277
+ allow attackers to write arbitrary content. Now it logs to the debug
278
+ logger instead.
279
+ """
280
+ logger.debug("%s: %s => %s", name, prefix, value)
281
+
282
+
283
+ # Generate an interactive ZK proof from a statement and variables. The output
284
+ # of this function is a subclass of Protocol. To execute the proof, first
285
+ # set it up using the Protocol API and run Execute().
286
+ def executeIntZKProof(public, secret, statement, party_info, interactive=int_default):
287
+ """Execute an interactive ZK proof.
288
+
289
+ .. deprecated:: 0.60
290
+ This function uses insecure dynamic code execution (exec/compile).
291
+ Use :class:`charm.zkp_compiler.zkp_factory.ZKProofFactory` instead.
292
+
293
+ Migration example::
294
+
295
+ # Old (deprecated):
296
+ # result = executeIntZKProof(public, secret, statement, party_info)
297
+
298
+ # New (recommended):
299
+ from charm.zkp_compiler.zkp_factory import ZKProofFactory
300
+ proof_instance = ZKProofFactory.create_schnorr_proof(group, g, h, x)
301
+ proof = proof_instance.prove()
302
+ is_valid = proof_instance.verify(proof)
303
+ """
304
+ warnings.warn(
305
+ "executeIntZKProof() uses insecure dynamic code execution. "
306
+ "Use charm.zkp_compiler.zkp_factory.ZKProofFactory instead.",
307
+ DeprecationWarning,
308
+ stacklevel=2
309
+ )
310
+ logger.info("Executing Interactive ZK proof...")
311
+ # verify that party_info contains wellformed dictionary
312
+ party_keys = set(['party', 'setting', 'socket'])
313
+ if not party_keys.issubset(set(party_info.keys())):
314
+ missing_keys = party_keys.difference_update(set(party_info_keys()))
315
+ logger.error("Required key/values missing: '%s'", missing_keys)
316
+ return None
317
+
318
+ p_name, p_socket, groupObj = party_info['party'], party_info['socket'], party_info['setting']
319
+ if p_name.upper() == 'PROVER': partyID = PROVER
320
+ elif p_name.upper() == 'VERIFIER': partyID = VERIFIER
321
+ else: logger.error("Unrecognized party!"); return None
322
+
323
+ # Parse through the statement and insert code into each state of the prover and/or verifier
324
+ ZKClass = parseAndGenerateCode(public, secret, statement, partyID, interactive)
325
+ dummy_class = '<string>'
326
+ # SECURITY WARNING: compile() and exec() are used here for legacy compatibility.
327
+ # This is a known security vulnerability. Use ZKProofFactory for new code.
328
+ proof_code = compile(ZKClass, dummy_class, 'exec')
329
+ logger.debug("Proof code object => %s", proof_code)
330
+ # return proof_code
331
+ ns = {}
332
+ exec(proof_code, globals(), ns) # nosec B102 - legacy code, deprecated
333
+ ZKProof = ns['ZKProof']
334
+
335
+ prov_db = None
336
+ if(partyID == PROVER):
337
+ prov_db = {}; prov_db.update(public); prov_db.update(secret)
338
+ zkp = ZKProof(groupObj, prov_db)
339
+ zkp.setup( {'name':p_name.lower(), 'type':partyID, 'socket':p_socket})
340
+ # is there a way to check type of socket?
341
+ zkp.execute(partyID)
342
+ return zkp.result
343
+
344
+
345
+ def executeNonIntZKProof(public, secret, statement, party_info):
346
+ """Execute a non-interactive ZK proof.
347
+
348
+ .. deprecated:: 0.60
349
+ This function uses insecure dynamic code execution (exec/compile).
350
+ Use :class:`charm.zkp_compiler.schnorr_proof.SchnorrProof` instead.
351
+
352
+ Migration example::
353
+
354
+ # Old (deprecated):
355
+ # result = executeNonIntZKProof(public, secret, statement, party_info)
356
+
357
+ # New (recommended):
358
+ from charm.zkp_compiler.schnorr_proof import SchnorrProof
359
+ proof = SchnorrProof.prove_non_interactive(group, g, h, x)
360
+ is_valid = SchnorrProof.verify_non_interactive(group, g, h, proof)
361
+ """
362
+ warnings.warn(
363
+ "executeNonIntZKProof() uses insecure dynamic code execution. "
364
+ "Use charm.zkp_compiler.schnorr_proof.SchnorrProof instead.",
365
+ DeprecationWarning,
366
+ stacklevel=2
367
+ )
368
+ logger.info("Executing Non-interactive ZK proof...")
369
+ return executeIntZKProof(public, secret, statement, party_info, interactive=False)
370
+