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,315 @@
1
+ """
2
+ Pedersen Commitment Test Vectors
3
+
4
+ Test vectors for Pedersen Commitment scheme based on:
5
+ - Original paper: "Non-Interactive and Information-Theoretic Secure Verifiable Secret Sharing" (Pedersen, 1992)
6
+ - Standard commitment scheme properties: hiding and binding
7
+
8
+ These tests verify the mathematical correctness of the Pedersen commitment implementation.
9
+ """
10
+
11
+ import unittest
12
+ from charm.toolbox.ecgroup import ECGroup, ZR, G
13
+ from charm.schemes.commit.commit_pedersen92 import CM_Ped92
14
+
15
+
16
+ class TestPedersenMathematicalProperties(unittest.TestCase):
17
+ """
18
+ Test mathematical properties of Pedersen commitments.
19
+
20
+ Pedersen commitments have two key properties:
21
+ 1. Hiding: Commitment reveals nothing about the message
22
+ 2. Binding: Cannot open commitment to different message (computationally)
23
+ """
24
+
25
+ def setUp(self):
26
+ """Set up test fixtures with secp256k1 curve."""
27
+ # Use curve 714 (secp256k1) for 128-bit security
28
+ self.group = ECGroup(714)
29
+ self.pedersen = CM_Ped92(self.group)
30
+ self.pk = self.pedersen.setup()
31
+
32
+ def test_commitment_correctness(self):
33
+ """
34
+ Test Vector PEDERSEN-1: Commitment Correctness
35
+
36
+ Property: commit(m, r) produces C = g^m * h^r
37
+
38
+ Source: Pedersen 1992, Definition 1
39
+ """
40
+ msg = self.group.random(ZR)
41
+ (commit, decommit) = self.pedersen.commit(self.pk, msg)
42
+
43
+ # Verify commitment structure: C = g^m * h^r
44
+ expected = (self.pk['g'] ** msg) * (self.pk['h'] ** decommit)
45
+
46
+ self.assertEqual(commit, expected,
47
+ "Commitment must equal g^m * h^r")
48
+
49
+ def test_decommitment_verification(self):
50
+ """
51
+ Test Vector PEDERSEN-2: Decommitment Verification
52
+
53
+ Property: decommit(C, r, m) returns True for valid (C, r, m)
54
+
55
+ Source: Pedersen 1992, Verification procedure
56
+ """
57
+ msg = self.group.random(ZR)
58
+ (commit, decommit) = self.pedersen.commit(self.pk, msg)
59
+
60
+ result = self.pedersen.decommit(self.pk, commit, decommit, msg)
61
+
62
+ self.assertTrue(result,
63
+ "Valid decommitment must verify")
64
+
65
+ def test_wrong_message_decommit_fails(self):
66
+ """
67
+ Test Vector PEDERSEN-3: Binding Property
68
+
69
+ Property: Cannot decommit to a different message.
70
+
71
+ Source: Computational binding property
72
+ """
73
+ msg1 = self.group.random(ZR)
74
+ msg2 = self.group.random(ZR)
75
+
76
+ (commit, decommit) = self.pedersen.commit(self.pk, msg1)
77
+
78
+ # Try to decommit with wrong message
79
+ result = self.pedersen.decommit(self.pk, commit, decommit, msg2)
80
+
81
+ self.assertFalse(result,
82
+ "Decommitment with wrong message must fail (binding)")
83
+
84
+ def test_wrong_randomness_decommit_fails(self):
85
+ """
86
+ Test Vector PEDERSEN-4: Randomness Binding
87
+
88
+ Property: Cannot decommit with wrong randomness.
89
+ """
90
+ msg = self.group.random(ZR)
91
+ (commit, decommit) = self.pedersen.commit(self.pk, msg)
92
+
93
+ # Try with wrong randomness
94
+ wrong_decommit = self.group.random(ZR)
95
+ result = self.pedersen.decommit(self.pk, commit, wrong_decommit, msg)
96
+
97
+ self.assertFalse(result,
98
+ "Decommitment with wrong randomness must fail")
99
+
100
+ def test_different_randomness_different_commitments(self):
101
+ """
102
+ Test Vector PEDERSEN-5: Hiding Property (Statistical)
103
+
104
+ Property: Same message with different randomness produces different commitments.
105
+
106
+ Source: Information-theoretic hiding property
107
+ """
108
+ msg = self.group.random(ZR)
109
+
110
+ # Commit to same message twice (different randomness)
111
+ (commit1, _) = self.pedersen.commit(self.pk, msg)
112
+ (commit2, _) = self.pedersen.commit(self.pk, msg)
113
+
114
+ self.assertNotEqual(commit1, commit2,
115
+ "Same message with different randomness must produce different commitments")
116
+
117
+ def test_homomorphic_property(self):
118
+ """
119
+ Test Vector PEDERSEN-6: Homomorphic Property
120
+
121
+ Property: C(m1, r1) * C(m2, r2) = C(m1+m2, r1+r2)
122
+
123
+ Source: Pedersen commitments are additively homomorphic
124
+ """
125
+ m1 = self.group.random(ZR)
126
+ m2 = self.group.random(ZR)
127
+
128
+ (c1, r1) = self.pedersen.commit(self.pk, m1)
129
+ (c2, r2) = self.pedersen.commit(self.pk, m2)
130
+
131
+ # Compute product of commitments
132
+ c_product = c1 * c2
133
+
134
+ # This should equal commitment to sum
135
+ expected = (self.pk['g'] ** (m1 + m2)) * (self.pk['h'] ** (r1 + r2))
136
+
137
+ self.assertEqual(c_product, expected,
138
+ "Pedersen commitments must be additively homomorphic")
139
+
140
+ def test_homomorphic_decommit(self):
141
+ """
142
+ Test Vector PEDERSEN-7: Homomorphic Decommitment
143
+
144
+ Property: Can decommit product of commitments with sum of values.
145
+ """
146
+ m1 = self.group.random(ZR)
147
+ m2 = self.group.random(ZR)
148
+
149
+ (c1, r1) = self.pedersen.commit(self.pk, m1)
150
+ (c2, r2) = self.pedersen.commit(self.pk, m2)
151
+
152
+ # Product commitment
153
+ c_product = c1 * c2
154
+
155
+ # Should decommit with sums
156
+ result = self.pedersen.decommit(self.pk, c_product, r1 + r2, m1 + m2)
157
+
158
+ self.assertTrue(result,
159
+ "Homomorphic commitment must decommit with sum of values")
160
+
161
+
162
+ class TestPedersenEdgeCases(unittest.TestCase):
163
+ """
164
+ Edge case tests for Pedersen commitments.
165
+ """
166
+
167
+ def setUp(self):
168
+ """Set up test fixtures."""
169
+ self.group = ECGroup(714)
170
+ self.pedersen = CM_Ped92(self.group)
171
+ self.pk = self.pedersen.setup()
172
+
173
+ def test_zero_message(self):
174
+ """
175
+ Test Vector PEDERSEN-EDGE-1: Zero Message
176
+
177
+ Property: Commitment to zero message works correctly.
178
+ """
179
+ msg = self.group.init(ZR, 0)
180
+ (commit, decommit) = self.pedersen.commit(self.pk, msg)
181
+
182
+ result = self.pedersen.decommit(self.pk, commit, decommit, msg)
183
+
184
+ self.assertTrue(result,
185
+ "Commitment to zero must work correctly")
186
+
187
+ def test_one_message(self):
188
+ """
189
+ Test Vector PEDERSEN-EDGE-2: Message = 1
190
+
191
+ Property: Commitment to 1 works correctly.
192
+ """
193
+ msg = self.group.init(ZR, 1)
194
+ (commit, decommit) = self.pedersen.commit(self.pk, msg)
195
+
196
+ result = self.pedersen.decommit(self.pk, commit, decommit, msg)
197
+
198
+ self.assertTrue(result,
199
+ "Commitment to 1 must work correctly")
200
+
201
+ def test_negative_message(self):
202
+ """
203
+ Test Vector PEDERSEN-EDGE-3: Negative Message (Modular)
204
+
205
+ Property: Commitment to negative values (mod order) works correctly.
206
+ """
207
+ # In ZR, -1 is equivalent to order - 1
208
+ msg = self.group.init(ZR, -1)
209
+ (commit, decommit) = self.pedersen.commit(self.pk, msg)
210
+
211
+ result = self.pedersen.decommit(self.pk, commit, decommit, msg)
212
+
213
+ self.assertTrue(result,
214
+ "Commitment to negative value must work correctly")
215
+
216
+
217
+ class TestPedersenSecurityProperties(unittest.TestCase):
218
+ """
219
+ Security-focused tests for Pedersen commitments.
220
+ """
221
+
222
+ def setUp(self):
223
+ """Set up test fixtures."""
224
+ self.group = ECGroup(714)
225
+ self.pedersen = CM_Ped92(self.group)
226
+ self.pk = self.pedersen.setup()
227
+
228
+ def test_generators_are_independent(self):
229
+ """
230
+ Test Vector PEDERSEN-SEC-1: Generator Independence
231
+
232
+ Property: g and h should be independent (no known discrete log relation).
233
+
234
+ Note: This is a structural test - we verify g ≠ h.
235
+ True independence requires g, h to be generated from nothing-up-my-sleeve numbers.
236
+ """
237
+ self.assertNotEqual(self.pk['g'], self.pk['h'],
238
+ "Generators g and h must be different")
239
+
240
+ def test_commitment_not_identity(self):
241
+ """
242
+ Test Vector PEDERSEN-SEC-2: Non-trivial Commitment
243
+
244
+ Property: Commitment should not be identity element for random message.
245
+ """
246
+ msg = self.group.random(ZR)
247
+ (commit, _) = self.pedersen.commit(self.pk, msg)
248
+
249
+ identity = self.group.init(G, 1)
250
+
251
+ self.assertNotEqual(commit, identity,
252
+ "Commitment to random message should not be identity")
253
+
254
+ def test_random_commitment_does_not_verify(self):
255
+ """
256
+ Test Vector PEDERSEN-SEC-3: Random Commitment Rejection
257
+
258
+ Property: Random group element should not verify as valid commitment.
259
+ """
260
+ msg = self.group.random(ZR)
261
+ random_commit = self.group.random(G)
262
+ random_decommit = self.group.random(ZR)
263
+
264
+ result = self.pedersen.decommit(self.pk, random_commit, random_decommit, msg)
265
+
266
+ self.assertFalse(result,
267
+ "Random commitment should not verify")
268
+
269
+
270
+ class TestPedersenMultipleRuns(unittest.TestCase):
271
+ """
272
+ Statistical tests with multiple commitment operations.
273
+ """
274
+
275
+ def setUp(self):
276
+ """Set up test fixtures."""
277
+ self.group = ECGroup(714)
278
+ self.pedersen = CM_Ped92(self.group)
279
+ self.pk = self.pedersen.setup()
280
+
281
+ def test_multiple_commitments_all_verify(self):
282
+ """
283
+ Test Vector PEDERSEN-STAT-1: Multiple Commitment Verification
284
+
285
+ Property: All honestly generated commitments must verify.
286
+ """
287
+ for i in range(100):
288
+ msg = self.group.random(ZR)
289
+ (commit, decommit) = self.pedersen.commit(self.pk, msg)
290
+ result = self.pedersen.decommit(self.pk, commit, decommit, msg)
291
+
292
+ self.assertTrue(result,
293
+ f"Commitment {i+1} must verify (correctness)")
294
+
295
+ def test_all_commitments_unique(self):
296
+ """
297
+ Test Vector PEDERSEN-STAT-2: Commitment Uniqueness
298
+
299
+ Property: Different (message, randomness) pairs produce unique commitments.
300
+ """
301
+ commitments = set()
302
+
303
+ for _ in range(100):
304
+ msg = self.group.random(ZR)
305
+ (commit, _) = self.pedersen.commit(self.pk, msg)
306
+ # Convert to string for set comparison
307
+ commit_str = str(commit)
308
+
309
+ self.assertNotIn(commit_str, commitments,
310
+ "All commitments should be unique")
311
+ commitments.add(commit_str)
312
+
313
+
314
+ if __name__ == '__main__':
315
+ unittest.main()
@@ -0,0 +1,368 @@
1
+ """
2
+ Schnorr Zero-Knowledge Proof Test Vectors
3
+
4
+ Test vectors for Schnorr's ZKP protocol based on:
5
+ - Original paper: "Efficient Signature Generation by Smart Cards" (Schnorr, 1991)
6
+ - RFC 8235: Schnorr Non-interactive Zero-Knowledge Proof
7
+ - Fiat-Shamir heuristic for non-interactive proofs
8
+
9
+ These tests verify both interactive and non-interactive Schnorr proofs.
10
+ """
11
+
12
+ import unittest
13
+ from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
14
+ from charm.zkp_compiler.schnorr_proof import SchnorrProof, Proof
15
+ from charm.core.engine.util import objectToBytes
16
+
17
+
18
+ class TestSchnorrMathematicalProperties(unittest.TestCase):
19
+ """
20
+ Test mathematical properties of Schnorr ZK proofs.
21
+
22
+ These tests verify the fundamental algebraic properties that must hold
23
+ for any correct Schnorr proof implementation.
24
+ """
25
+
26
+ def setUp(self):
27
+ """Set up test fixtures with BN254 curve."""
28
+ self.group = PairingGroup('BN254')
29
+
30
+ def test_completeness_interactive(self):
31
+ """
32
+ Test Vector SCHNORR-1: Completeness (Interactive)
33
+
34
+ Property: Honest prover with valid witness always convinces honest verifier.
35
+
36
+ Source: Schnorr 1991, Definition of ZK proof system
37
+ """
38
+ # Generate secret and public values
39
+ x = self.group.random(ZR) # Secret
40
+ g = self.group.random(G1) # Generator
41
+ h = g ** x # Public value h = g^x
42
+
43
+ # Interactive protocol
44
+ prover = SchnorrProof.Prover(x, self.group)
45
+ verifier = SchnorrProof.Verifier(self.group)
46
+
47
+ # Step 1: Prover creates commitment
48
+ commitment = prover.create_commitment(g)
49
+
50
+ # Step 2: Verifier creates challenge
51
+ challenge = verifier.create_challenge()
52
+
53
+ # Step 3: Prover creates response
54
+ response = prover.create_response(challenge)
55
+
56
+ # Step 4: Verifier verifies
57
+ result = verifier.verify(g, h, commitment, response)
58
+
59
+ self.assertTrue(result,
60
+ "Completeness: Honest prover must always convince honest verifier")
61
+
62
+ def test_completeness_non_interactive(self):
63
+ """
64
+ Test Vector SCHNORR-2: Completeness (Non-Interactive)
65
+
66
+ Property: Non-interactive proof with valid witness always verifies.
67
+
68
+ Source: Fiat-Shamir heuristic applied to Schnorr protocol
69
+ """
70
+ x = self.group.random(ZR)
71
+ g = self.group.random(G1)
72
+ h = g ** x
73
+
74
+ # Generate non-interactive proof
75
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
76
+
77
+ # Verify
78
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
79
+
80
+ self.assertTrue(result,
81
+ "Completeness: Valid non-interactive proof must verify")
82
+
83
+ def test_soundness_wrong_witness(self):
84
+ """
85
+ Test Vector SCHNORR-3: Soundness (Wrong Witness)
86
+
87
+ Property: Prover with wrong witness cannot convince verifier.
88
+
89
+ Source: Soundness requirement for ZK proofs
90
+ """
91
+ x_real = self.group.random(ZR)
92
+ x_fake = self.group.random(ZR) # Wrong witness
93
+ g = self.group.random(G1)
94
+ h = g ** x_real # h = g^x_real
95
+
96
+ # Try to prove with wrong witness
97
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x_fake)
98
+
99
+ # Should fail verification (with overwhelming probability)
100
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
101
+
102
+ self.assertFalse(result,
103
+ "Soundness: Proof with wrong witness must not verify")
104
+
105
+ def test_verification_equation(self):
106
+ """
107
+ Test Vector SCHNORR-4: Verification Equation
108
+
109
+ Property: g^z = u * h^c where z = r + c*x, u = g^r, h = g^x
110
+
111
+ Source: Schnorr 1991, Protocol specification
112
+ """
113
+ x = self.group.random(ZR)
114
+ g = self.group.random(G1)
115
+ h = g ** x
116
+
117
+ # Generate proof
118
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
119
+
120
+ # Manually verify the equation: g^z = u * h^c
121
+ lhs = g ** proof.response
122
+ rhs = proof.commitment * (h ** proof.challenge)
123
+
124
+ self.assertEqual(lhs, rhs,
125
+ "Verification equation g^z = u * h^c must hold")
126
+
127
+ def test_challenge_binding(self):
128
+ """
129
+ Test Vector SCHNORR-5: Challenge Binding (Fiat-Shamir)
130
+
131
+ Property: Challenge is deterministically derived from (g, h, commitment)
132
+
133
+ Source: Fiat-Shamir heuristic security requirement
134
+ """
135
+ x = self.group.random(ZR)
136
+ g = self.group.random(G1)
137
+ h = g ** x
138
+
139
+ # Generate two proofs
140
+ proof1 = SchnorrProof.prove_non_interactive(self.group, g, h, x)
141
+ proof2 = SchnorrProof.prove_non_interactive(self.group, g, h, x)
142
+
143
+ # Commitments are random, so challenges should differ
144
+ # But if we recompute challenge from same commitment, it should match
145
+ expected_challenge = SchnorrProof._compute_challenge_hash(
146
+ self.group, g, h, proof1.commitment
147
+ )
148
+
149
+ self.assertEqual(proof1.challenge, expected_challenge,
150
+ "Challenge must be deterministically derived from public values")
151
+
152
+ def test_zero_knowledge_simulation(self):
153
+ """
154
+ Test Vector SCHNORR-6: Zero-Knowledge Property (Simulation)
155
+
156
+ Property: Proofs can be simulated without knowing the witness.
157
+ This demonstrates the zero-knowledge property.
158
+
159
+ Source: Schnorr 1991, Zero-knowledge proof
160
+
161
+ Note: This test verifies that simulated proofs have the same structure
162
+ as real proofs, demonstrating that proofs reveal nothing about x.
163
+ """
164
+ g = self.group.random(G1)
165
+ x = self.group.random(ZR)
166
+ h = g ** x
167
+
168
+ # Simulate a proof (without knowing x):
169
+ # 1. Choose random z and c
170
+ # 2. Compute u = g^z * h^(-c)
171
+ # This creates a valid-looking proof without knowing x
172
+
173
+ z_sim = self.group.random(ZR)
174
+ c_sim = self.group.random(ZR)
175
+ u_sim = (g ** z_sim) * (h ** (-c_sim))
176
+
177
+ # Verify the simulation satisfies the verification equation
178
+ lhs = g ** z_sim
179
+ rhs = u_sim * (h ** c_sim)
180
+
181
+ self.assertEqual(lhs, rhs,
182
+ "Simulated proof must satisfy verification equation")
183
+
184
+
185
+ class TestSchnorrEdgeCases(unittest.TestCase):
186
+ """
187
+ Edge case tests for Schnorr proofs.
188
+ """
189
+
190
+ def setUp(self):
191
+ """Set up test fixtures."""
192
+ self.group = PairingGroup('BN254')
193
+
194
+ def test_identity_commitment_rejection(self):
195
+ """
196
+ Test Vector SCHNORR-EDGE-1: Identity Commitment Attack
197
+
198
+ Property: Proof with identity element as commitment should be rejected.
199
+
200
+ Attack: Attacker submits identity as commitment to bypass verification.
201
+ """
202
+ x = self.group.random(ZR)
203
+ g = self.group.random(G1)
204
+ h = g ** x
205
+
206
+ # Create malicious proof with identity commitment
207
+ identity = self.group.init(G1, 1)
208
+ malicious_proof = Proof(
209
+ commitment=identity,
210
+ challenge=self.group.random(ZR),
211
+ response=self.group.random(ZR)
212
+ )
213
+
214
+ # Should be rejected
215
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, malicious_proof)
216
+
217
+ self.assertFalse(result,
218
+ "Proof with identity commitment must be rejected")
219
+
220
+ def test_zero_secret(self):
221
+ """
222
+ Test Vector SCHNORR-EDGE-2: Zero Secret
223
+
224
+ Property: Proof works correctly when secret x = 0 (h = g^0 = 1).
225
+ """
226
+ x = self.group.init(ZR, 0) # Zero secret
227
+ g = self.group.random(G1)
228
+ h = g ** x # h = identity
229
+
230
+ # Should still work correctly
231
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
232
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
233
+
234
+ self.assertTrue(result,
235
+ "Proof must work correctly for zero secret")
236
+
237
+ def test_one_secret(self):
238
+ """
239
+ Test Vector SCHNORR-EDGE-3: Secret = 1
240
+
241
+ Property: Proof works correctly when secret x = 1 (h = g).
242
+ """
243
+ x = self.group.init(ZR, 1)
244
+ g = self.group.random(G1)
245
+ h = g ** x # h = g
246
+
247
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
248
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
249
+
250
+ self.assertTrue(result,
251
+ "Proof must work correctly for secret = 1")
252
+
253
+ def test_large_secret(self):
254
+ """
255
+ Test Vector SCHNORR-EDGE-4: Large Secret
256
+
257
+ Property: Proof works correctly for secrets near the group order.
258
+ """
259
+ # Use a large secret (close to group order)
260
+ g = self.group.random(G1)
261
+ x = self.group.random(ZR) # Random element in ZR (full range)
262
+ h = g ** x
263
+
264
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
265
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
266
+
267
+ self.assertTrue(result,
268
+ "Proof must work correctly for large secrets")
269
+
270
+
271
+ class TestSchnorrSerialization(unittest.TestCase):
272
+ """
273
+ Serialization tests for Schnorr proofs.
274
+ """
275
+
276
+ def setUp(self):
277
+ """Set up test fixtures."""
278
+ self.group = PairingGroup('BN254')
279
+
280
+ def test_serialize_deserialize_roundtrip(self):
281
+ """
282
+ Test Vector SCHNORR-SER-1: Serialization Roundtrip
283
+
284
+ Property: serialize(deserialize(proof)) == proof
285
+ """
286
+ x = self.group.random(ZR)
287
+ g = self.group.random(G1)
288
+ h = g ** x
289
+
290
+ # Generate proof
291
+ original_proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
292
+
293
+ # Serialize and deserialize
294
+ serialized = SchnorrProof.serialize_proof(original_proof, self.group)
295
+ deserialized_proof = SchnorrProof.deserialize_proof(serialized, self.group)
296
+
297
+ # Verify deserialized proof
298
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, deserialized_proof)
299
+
300
+ self.assertTrue(result,
301
+ "Deserialized proof must verify correctly")
302
+
303
+ def test_serialized_proof_is_bytes(self):
304
+ """
305
+ Test Vector SCHNORR-SER-2: Serialization Format
306
+
307
+ Property: Serialized proof is bytes type.
308
+ """
309
+ x = self.group.random(ZR)
310
+ g = self.group.random(G1)
311
+ h = g ** x
312
+
313
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
314
+ serialized = SchnorrProof.serialize_proof(proof, self.group)
315
+
316
+ self.assertIsInstance(serialized, bytes,
317
+ "Serialized proof must be bytes")
318
+
319
+
320
+ class TestSchnorrMultipleRuns(unittest.TestCase):
321
+ """
322
+ Statistical tests running multiple proof generations.
323
+ """
324
+
325
+ def setUp(self):
326
+ """Set up test fixtures."""
327
+ self.group = PairingGroup('BN254')
328
+
329
+ def test_multiple_proofs_all_verify(self):
330
+ """
331
+ Test Vector SCHNORR-STAT-1: Multiple Proof Verification
332
+
333
+ Property: All honestly generated proofs must verify.
334
+ """
335
+ x = self.group.random(ZR)
336
+ g = self.group.random(G1)
337
+ h = g ** x
338
+
339
+ # Generate and verify 100 proofs
340
+ for i in range(100):
341
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
342
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
343
+ self.assertTrue(result,
344
+ f"Proof {i+1} must verify (completeness)")
345
+
346
+ def test_different_generators(self):
347
+ """
348
+ Test Vector SCHNORR-STAT-2: Different Generators
349
+
350
+ Property: Proofs work correctly with different generators.
351
+ """
352
+ x = self.group.random(ZR)
353
+
354
+ # Test with 10 different generators
355
+ for i in range(10):
356
+ g = self.group.random(G1)
357
+ h = g ** x
358
+
359
+ proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
360
+ result = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
361
+
362
+ self.assertTrue(result,
363
+ f"Proof with generator {i+1} must verify")
364
+
365
+
366
+ if __name__ == '__main__':
367
+ unittest.main()
368
+
@@ -0,0 +1,9 @@
1
+ """
2
+ Unit tests for the ZKP compiler module.
3
+
4
+ This package contains tests for:
5
+ - ZK statement parser (test_zkp_parser.py)
6
+ - Schnorr proof implementation (test_schnorr_proof.py)
7
+ - Proof serialization (test_proof_serialization.py)
8
+ """
9
+