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,258 @@
1
+ """
2
+ Performance benchmarks for ZKP compiler.
3
+
4
+ Compares proof generation and verification times across different curves:
5
+ - BN254 (128-bit security, recommended)
6
+ - SS512 (80-bit security, legacy)
7
+ - MNT224 (112-bit security)
8
+
9
+ Run with: python -m charm.test.zkp_compiler.benchmark_zkp
10
+ """
11
+
12
+ import time
13
+ import statistics
14
+ from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
15
+
16
+ from charm.zkp_compiler.schnorr_proof import SchnorrProof
17
+ from charm.zkp_compiler.dleq_proof import DLEQProof
18
+ from charm.zkp_compiler.representation_proof import RepresentationProof
19
+ from charm.zkp_compiler.and_proof import ANDProof
20
+ from charm.zkp_compiler.or_proof import ORProof
21
+ from charm.zkp_compiler.range_proof import RangeProof
22
+
23
+
24
+ CURVES = ['BN254', 'SS512', 'MNT224']
25
+ ITERATIONS = 10
26
+
27
+
28
+ def benchmark_schnorr(group, iterations=ITERATIONS):
29
+ """Benchmark Schnorr proof."""
30
+ g = group.random(G1)
31
+ x = group.random(ZR)
32
+ h = g ** x
33
+
34
+ prove_times = []
35
+ verify_times = []
36
+
37
+ for _ in range(iterations):
38
+ start = time.perf_counter()
39
+ proof = SchnorrProof.prove_non_interactive(group, g, h, x)
40
+ prove_times.append(time.perf_counter() - start)
41
+
42
+ start = time.perf_counter()
43
+ SchnorrProof.verify_non_interactive(group, g, h, proof)
44
+ verify_times.append(time.perf_counter() - start)
45
+
46
+ return {
47
+ 'prove_mean': statistics.mean(prove_times) * 1000,
48
+ 'prove_std': statistics.stdev(prove_times) * 1000 if len(prove_times) > 1 else 0,
49
+ 'verify_mean': statistics.mean(verify_times) * 1000,
50
+ 'verify_std': statistics.stdev(verify_times) * 1000 if len(verify_times) > 1 else 0,
51
+ }
52
+
53
+
54
+ def benchmark_dleq(group, iterations=ITERATIONS):
55
+ """Benchmark DLEQ proof."""
56
+ g1 = group.random(G1)
57
+ g2 = group.random(G1)
58
+ x = group.random(ZR)
59
+ h1 = g1 ** x
60
+ h2 = g2 ** x
61
+
62
+ prove_times = []
63
+ verify_times = []
64
+
65
+ for _ in range(iterations):
66
+ start = time.perf_counter()
67
+ proof = DLEQProof.prove_non_interactive(group, g1, h1, g2, h2, x)
68
+ prove_times.append(time.perf_counter() - start)
69
+
70
+ start = time.perf_counter()
71
+ DLEQProof.verify_non_interactive(group, g1, h1, g2, h2, proof)
72
+ verify_times.append(time.perf_counter() - start)
73
+
74
+ return {
75
+ 'prove_mean': statistics.mean(prove_times) * 1000,
76
+ 'prove_std': statistics.stdev(prove_times) * 1000 if len(prove_times) > 1 else 0,
77
+ 'verify_mean': statistics.mean(verify_times) * 1000,
78
+ 'verify_std': statistics.stdev(verify_times) * 1000 if len(verify_times) > 1 else 0,
79
+ }
80
+
81
+
82
+ def benchmark_representation(group, iterations=ITERATIONS):
83
+ """Benchmark Representation proof."""
84
+ g1, g2 = group.random(G1), group.random(G1)
85
+ x1, x2 = group.random(ZR), group.random(ZR)
86
+ h = (g1 ** x1) * (g2 ** x2)
87
+ generators = [g1, g2]
88
+ witnesses = [x1, x2]
89
+
90
+ prove_times = []
91
+ verify_times = []
92
+
93
+ for _ in range(iterations):
94
+ start = time.perf_counter()
95
+ proof = RepresentationProof.prove_non_interactive(group, generators, h, witnesses)
96
+ prove_times.append(time.perf_counter() - start)
97
+
98
+ start = time.perf_counter()
99
+ RepresentationProof.verify_non_interactive(group, generators, h, proof)
100
+ verify_times.append(time.perf_counter() - start)
101
+
102
+ return {
103
+ 'prove_mean': statistics.mean(prove_times) * 1000,
104
+ 'prove_std': statistics.stdev(prove_times) * 1000 if len(prove_times) > 1 else 0,
105
+ 'verify_mean': statistics.mean(verify_times) * 1000,
106
+ 'verify_std': statistics.stdev(verify_times) * 1000 if len(verify_times) > 1 else 0,
107
+ }
108
+
109
+
110
+ def benchmark_and(group, iterations=ITERATIONS):
111
+ """Benchmark AND proof."""
112
+ g = group.random(G1)
113
+ x, y = group.random(ZR), group.random(ZR)
114
+ h1, h2 = g ** x, g ** y
115
+
116
+ statements = [
117
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1, 'x': x}},
118
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2, 'x': y}},
119
+ ]
120
+ statements_public = [
121
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1}},
122
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2}},
123
+ ]
124
+
125
+ prove_times = []
126
+ verify_times = []
127
+
128
+ for _ in range(iterations):
129
+ start = time.perf_counter()
130
+ proof = ANDProof.prove_non_interactive(group, statements)
131
+ prove_times.append(time.perf_counter() - start)
132
+
133
+ start = time.perf_counter()
134
+ ANDProof.verify_non_interactive(group, statements_public, proof)
135
+ verify_times.append(time.perf_counter() - start)
136
+
137
+ return {
138
+ 'prove_mean': statistics.mean(prove_times) * 1000,
139
+ 'prove_std': statistics.stdev(prove_times) * 1000 if len(prove_times) > 1 else 0,
140
+ 'verify_mean': statistics.mean(verify_times) * 1000,
141
+ 'verify_std': statistics.stdev(verify_times) * 1000 if len(verify_times) > 1 else 0,
142
+ }
143
+
144
+
145
+
146
+ def benchmark_or(group, iterations=ITERATIONS):
147
+ """Benchmark OR proof."""
148
+ g = group.random(G1)
149
+ x = group.random(ZR)
150
+ h1 = g ** x # Prover knows DL of h1
151
+ h2 = g ** group.random(ZR) # Prover does NOT know DL of h2
152
+
153
+ prove_times = []
154
+ verify_times = []
155
+
156
+ for _ in range(iterations):
157
+ start = time.perf_counter()
158
+ proof = ORProof.prove_non_interactive(group, g, h1, h2, x, which=0)
159
+ prove_times.append(time.perf_counter() - start)
160
+
161
+ start = time.perf_counter()
162
+ ORProof.verify_non_interactive(group, g, h1, h2, proof)
163
+ verify_times.append(time.perf_counter() - start)
164
+
165
+ return {
166
+ 'prove_mean': statistics.mean(prove_times) * 1000,
167
+ 'prove_std': statistics.stdev(prove_times) * 1000 if len(prove_times) > 1 else 0,
168
+ 'verify_mean': statistics.mean(verify_times) * 1000,
169
+ 'verify_std': statistics.stdev(verify_times) * 1000 if len(verify_times) > 1 else 0,
170
+ }
171
+
172
+
173
+ def benchmark_range(group, iterations=ITERATIONS):
174
+ """Benchmark Range proof."""
175
+ g, h = group.random(G1), group.random(G1)
176
+ value = 42
177
+ randomness = group.random(ZR)
178
+ commitment = RangeProof.create_pedersen_commitment(group, g, h, value, randomness)
179
+
180
+ prove_times = []
181
+ verify_times = []
182
+
183
+ for _ in range(iterations):
184
+ start = time.perf_counter()
185
+ proof = RangeProof.prove(group, g, h, value, randomness, num_bits=8)
186
+ prove_times.append(time.perf_counter() - start)
187
+
188
+ start = time.perf_counter()
189
+ RangeProof.verify(group, g, h, commitment, proof)
190
+ verify_times.append(time.perf_counter() - start)
191
+
192
+ return {
193
+ 'prove_mean': statistics.mean(prove_times) * 1000,
194
+ 'prove_std': statistics.stdev(prove_times) * 1000 if len(prove_times) > 1 else 0,
195
+ 'verify_mean': statistics.mean(verify_times) * 1000,
196
+ 'verify_std': statistics.stdev(verify_times) * 1000 if len(verify_times) > 1 else 0,
197
+ }
198
+
199
+
200
+ def run_benchmarks():
201
+ """Run all benchmarks and print results."""
202
+ print("=" * 80)
203
+ print("ZKP Compiler Performance Benchmarks")
204
+ print("=" * 80)
205
+ print(f"Iterations per test: {ITERATIONS}")
206
+ print()
207
+
208
+ results = {}
209
+
210
+ for curve in CURVES:
211
+ print(f"Benchmarking {curve}...")
212
+ group = PairingGroup(curve)
213
+ results[curve] = {
214
+ 'schnorr': benchmark_schnorr(group),
215
+ 'dleq': benchmark_dleq(group),
216
+ 'representation': benchmark_representation(group),
217
+ 'and': benchmark_and(group),
218
+ 'or': benchmark_or(group),
219
+ 'range': benchmark_range(group),
220
+ }
221
+
222
+ print()
223
+ print_results_table(results)
224
+
225
+
226
+ def print_results_table(results):
227
+ """Print formatted results table."""
228
+ proof_types = ['schnorr', 'dleq', 'representation', 'and', 'or', 'range']
229
+
230
+ # Header
231
+ print("=" * 100)
232
+ print(f"{'Proof Type':<16} {'Curve':<10} {'Prove (ms)':<20} {'Verify (ms)':<20}")
233
+ print("=" * 100)
234
+
235
+ for proof_type in proof_types:
236
+ for i, curve in enumerate(CURVES):
237
+ data = results[curve][proof_type]
238
+ prove_str = f"{data['prove_mean']:>8.3f} ± {data['prove_std']:<6.3f}"
239
+ verify_str = f"{data['verify_mean']:>8.3f} ± {data['verify_std']:<6.3f}"
240
+
241
+ if i == 0:
242
+ print(f"{proof_type:<16} {curve:<10} {prove_str:<20} {verify_str:<20}")
243
+ else:
244
+ print(f"{'':<16} {curve:<10} {prove_str:<20} {verify_str:<20}")
245
+ print("-" * 100)
246
+
247
+ # Summary: fastest curve per proof type
248
+ print()
249
+ print("Summary: Fastest Curve per Proof Type")
250
+ print("-" * 50)
251
+ for proof_type in proof_types:
252
+ best_prove = min(CURVES, key=lambda c: results[c][proof_type]['prove_mean'])
253
+ best_verify = min(CURVES, key=lambda c: results[c][proof_type]['verify_mean'])
254
+ print(f"{proof_type:<16} Prove: {best_prove:<10} Verify: {best_verify:<10}")
255
+
256
+
257
+ if __name__ == '__main__':
258
+ run_benchmarks()
@@ -0,0 +1,240 @@
1
+ """
2
+ Unit tests for AND Composition ZK proof implementation.
3
+
4
+ Tests cover:
5
+ - Non-interactive AND proof protocol
6
+ - Multiple proof types (Schnorr, DLEQ)
7
+ - Serialization and deserialization
8
+ - Edge cases and error handling
9
+ """
10
+
11
+ import unittest
12
+ from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
13
+ from charm.zkp_compiler.and_proof import ANDProof, ANDProofData
14
+
15
+
16
+ class TestANDProofNonInteractive(unittest.TestCase):
17
+ """Tests for non-interactive AND proof."""
18
+
19
+ def setUp(self):
20
+ """Set up test fixtures."""
21
+ self.group = PairingGroup('BN254')
22
+
23
+ def test_two_schnorr_proofs(self):
24
+ """Test AND of two Schnorr proofs."""
25
+ g = self.group.random(G1)
26
+ x1 = self.group.random(ZR)
27
+ x2 = self.group.random(ZR)
28
+ h1 = g ** x1
29
+ h2 = g ** x2
30
+
31
+ # Create statements with secrets for proving
32
+ statements = [
33
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1, 'x': x1}},
34
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2, 'x': x2}},
35
+ ]
36
+ proof = ANDProof.prove_non_interactive(self.group, statements)
37
+
38
+ self.assertIsNotNone(proof)
39
+ self.assertIsNotNone(proof.sub_proofs)
40
+ self.assertIsNotNone(proof.shared_challenge)
41
+ self.assertEqual(len(proof.sub_proofs), 2)
42
+
43
+ # Create public statements for verification
44
+ statements_public = [
45
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1}},
46
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2}},
47
+ ]
48
+ result = ANDProof.verify_non_interactive(self.group, statements_public, proof)
49
+ self.assertTrue(result)
50
+
51
+ def test_three_schnorr_proofs(self):
52
+ """Test AND of three Schnorr proofs."""
53
+ g = self.group.random(G1)
54
+ x1 = self.group.random(ZR)
55
+ x2 = self.group.random(ZR)
56
+ x3 = self.group.random(ZR)
57
+ h1 = g ** x1
58
+ h2 = g ** x2
59
+ h3 = g ** x3
60
+
61
+ # Create statements with secrets for proving
62
+ statements = [
63
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1, 'x': x1}},
64
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2, 'x': x2}},
65
+ {'type': 'schnorr', 'params': {'g': g, 'h': h3, 'x': x3}},
66
+ ]
67
+ proof = ANDProof.prove_non_interactive(self.group, statements)
68
+
69
+ self.assertIsNotNone(proof)
70
+ self.assertEqual(len(proof.sub_proofs), 3)
71
+
72
+ # Create public statements for verification
73
+ statements_public = [
74
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1}},
75
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2}},
76
+ {'type': 'schnorr', 'params': {'g': g, 'h': h3}},
77
+ ]
78
+ result = ANDProof.verify_non_interactive(self.group, statements_public, proof)
79
+ self.assertTrue(result)
80
+
81
+ def test_mixed_proof_types(self):
82
+ """Test AND of Schnorr + DLEQ proofs."""
83
+ g = self.group.random(G1)
84
+ g1 = self.group.random(G1)
85
+ g2 = self.group.random(G1)
86
+ x = self.group.random(ZR)
87
+ y = self.group.random(ZR)
88
+ h = g ** x
89
+ h1 = g1 ** y
90
+ h2 = g2 ** y
91
+
92
+ # Create statements: Schnorr proof AND DLEQ proof
93
+ statements = [
94
+ {'type': 'schnorr', 'params': {'g': g, 'h': h, 'x': x}},
95
+ {'type': 'dleq', 'params': {'g1': g1, 'h1': h1, 'g2': g2, 'h2': h2, 'x': y}},
96
+ ]
97
+ proof = ANDProof.prove_non_interactive(self.group, statements)
98
+
99
+ self.assertIsNotNone(proof)
100
+ self.assertEqual(len(proof.sub_proofs), 2)
101
+ self.assertEqual(proof.sub_proofs[0]['type'], 'schnorr')
102
+ self.assertEqual(proof.sub_proofs[1]['type'], 'dleq')
103
+
104
+ # Create public statements for verification
105
+ statements_public = [
106
+ {'type': 'schnorr', 'params': {'g': g, 'h': h}},
107
+ {'type': 'dleq', 'params': {'g1': g1, 'h1': h1, 'g2': g2, 'h2': h2}},
108
+ ]
109
+ result = ANDProof.verify_non_interactive(self.group, statements_public, proof)
110
+ self.assertTrue(result)
111
+
112
+ def test_wrong_secret_fails(self):
113
+ """Test that wrong secret in one proof fails entire AND."""
114
+ g = self.group.random(G1)
115
+ x1 = self.group.random(ZR)
116
+ x2 = self.group.random(ZR)
117
+ wrong_x2 = self.group.random(ZR)
118
+ h1 = g ** x1
119
+ h2 = g ** x2
120
+
121
+ # Create statements with WRONG secret for second proof
122
+ statements = [
123
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1, 'x': x1}},
124
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2, 'x': wrong_x2}},
125
+ ]
126
+ proof = ANDProof.prove_non_interactive(self.group, statements)
127
+
128
+ # Create public statements for verification
129
+ statements_public = [
130
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1}},
131
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2}},
132
+ ]
133
+ result = ANDProof.verify_non_interactive(self.group, statements_public, proof)
134
+ self.assertFalse(result)
135
+
136
+ def test_tampered_proof_fails(self):
137
+ """Test that tampered proof fails verification."""
138
+ g = self.group.random(G1)
139
+ x1 = self.group.random(ZR)
140
+ x2 = self.group.random(ZR)
141
+ h1 = g ** x1
142
+ h2 = g ** x2
143
+
144
+ # Create valid statements
145
+ statements = [
146
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1, 'x': x1}},
147
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2, 'x': x2}},
148
+ ]
149
+ proof = ANDProof.prove_non_interactive(self.group, statements)
150
+
151
+ # Tamper with the shared challenge
152
+ tampered_proof = ANDProofData(
153
+ sub_proofs=proof.sub_proofs,
154
+ shared_challenge=proof.shared_challenge + self.group.random(ZR),
155
+ proof_type=proof.proof_type
156
+ )
157
+
158
+ # Create public statements for verification
159
+ statements_public = [
160
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1}},
161
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2}},
162
+ ]
163
+ result = ANDProof.verify_non_interactive(
164
+ self.group, statements_public, tampered_proof
165
+ )
166
+ self.assertFalse(result)
167
+
168
+ def test_empty_statements_fails(self):
169
+ """Test that empty statement list should fail."""
170
+ with self.assertRaises(ValueError):
171
+ ANDProof.prove_non_interactive(self.group, [])
172
+
173
+
174
+ class TestANDProofSerialization(unittest.TestCase):
175
+ """Tests for AND proof serialization."""
176
+
177
+ def setUp(self):
178
+ """Set up test fixtures."""
179
+ self.group = PairingGroup('BN254')
180
+
181
+ def test_serialization_roundtrip(self):
182
+ """Test serialize and deserialize proof."""
183
+ g = self.group.random(G1)
184
+ x1 = self.group.random(ZR)
185
+ x2 = self.group.random(ZR)
186
+ h1 = g ** x1
187
+ h2 = g ** x2
188
+
189
+ # Create statements and proof
190
+ statements = [
191
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1, 'x': x1}},
192
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2, 'x': x2}},
193
+ ]
194
+ proof = ANDProof.prove_non_interactive(self.group, statements)
195
+
196
+ # Serialize
197
+ serialized = ANDProof.serialize_proof(proof, self.group)
198
+ self.assertIsNotNone(serialized)
199
+ self.assertIsInstance(serialized, bytes)
200
+
201
+ # Deserialize
202
+ deserialized = ANDProof.deserialize_proof(serialized, self.group)
203
+ self.assertIsNotNone(deserialized)
204
+ self.assertIsInstance(deserialized, ANDProofData)
205
+ self.assertEqual(len(deserialized.sub_proofs), len(proof.sub_proofs))
206
+ self.assertEqual(deserialized.proof_type, proof.proof_type)
207
+
208
+ def test_serialized_proof_verifies(self):
209
+ """Test that deserialized proof still verifies."""
210
+ g = self.group.random(G1)
211
+ x1 = self.group.random(ZR)
212
+ x2 = self.group.random(ZR)
213
+ h1 = g ** x1
214
+ h2 = g ** x2
215
+
216
+ # Create statements and proof
217
+ statements = [
218
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1, 'x': x1}},
219
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2, 'x': x2}},
220
+ ]
221
+ proof = ANDProof.prove_non_interactive(self.group, statements)
222
+
223
+ # Serialize and deserialize
224
+ serialized = ANDProof.serialize_proof(proof, self.group)
225
+ deserialized = ANDProof.deserialize_proof(serialized, self.group)
226
+
227
+ # Verify the deserialized proof
228
+ statements_public = [
229
+ {'type': 'schnorr', 'params': {'g': g, 'h': h1}},
230
+ {'type': 'schnorr', 'params': {'g': g, 'h': h2}},
231
+ ]
232
+ result = ANDProof.verify_non_interactive(
233
+ self.group, statements_public, deserialized
234
+ )
235
+ self.assertTrue(result)
236
+
237
+
238
+ if __name__ == "__main__":
239
+ unittest.main()
240
+