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,296 @@
1
+ '''
2
+ MPC Utility Functions for Charm
3
+
4
+ Common utilities for multi-party computation protocols including:
5
+ - Byte/integer conversion with consistent big-endian ordering
6
+ - Bit decomposition and reconstruction for OT-based protocols
7
+ - Pedersen commitment scheme for hiding commitments
8
+
9
+ :Authors: Elton de Souza
10
+ :Date: 01/2026
11
+ '''
12
+
13
+ from charm.toolbox.ecgroup import ECGroup, ZR, G
14
+ from typing import List, Tuple, Any, Optional
15
+
16
+ # Type aliases
17
+ ZRElement = Any
18
+ GElement = Any
19
+ ECGroupType = Any
20
+
21
+
22
+ def int_to_bytes(n: int, length: int) -> bytes:
23
+ """
24
+ Convert a non-negative integer to a fixed-length byte string.
25
+
26
+ Uses big-endian byte ordering (most significant byte first),
27
+ which is standard for cryptographic protocols.
28
+
29
+ Parameters
30
+ ----------
31
+ n : int
32
+ Non-negative integer to convert. Must fit within `length` bytes.
33
+ length : int
34
+ Exact number of bytes in the output. Value is zero-padded if needed.
35
+
36
+ Returns
37
+ -------
38
+ bytes
39
+ Big-endian representation of `n` with exactly `length` bytes.
40
+
41
+ Raises
42
+ ------
43
+ OverflowError
44
+ If `n` is too large to fit in `length` bytes.
45
+ ValueError
46
+ If `n` is negative.
47
+
48
+ Examples
49
+ --------
50
+ >>> int_to_bytes(256, 2)
51
+ b'\\x01\\x00'
52
+ >>> int_to_bytes(0, 4)
53
+ b'\\x00\\x00\\x00\\x00'
54
+ """
55
+ if n < 0:
56
+ raise ValueError("n must be non-negative")
57
+ return n.to_bytes(length, byteorder='big')
58
+
59
+
60
+ def bytes_to_int(b: bytes) -> int:
61
+ """
62
+ Convert a byte string to a non-negative integer.
63
+
64
+ Uses big-endian byte ordering (most significant byte first),
65
+ which is standard for cryptographic protocols.
66
+
67
+ Parameters
68
+ ----------
69
+ b : bytes
70
+ Byte string to convert.
71
+
72
+ Returns
73
+ -------
74
+ int
75
+ The integer value represented by the bytes.
76
+
77
+ Examples
78
+ --------
79
+ >>> bytes_to_int(b'\\x01\\x00')
80
+ 256
81
+ >>> bytes_to_int(b'\\x00\\x00\\x00\\x00')
82
+ 0
83
+ """
84
+ return int.from_bytes(b, byteorder='big')
85
+
86
+
87
+ def bit_decompose(value: Any, order: int, num_bits: int) -> List[int]:
88
+ """
89
+ Decompose a field element into its bit representation.
90
+
91
+ The input value is first reduced modulo order to ensure consistent
92
+ behavior for values at or near the group order boundary.
93
+
94
+ Parameters
95
+ ----------
96
+ value : ZR element or int
97
+ The value to decompose (will be reduced mod order)
98
+ order : int
99
+ The group order
100
+ num_bits : int
101
+ Number of bits to extract
102
+
103
+ Returns
104
+ -------
105
+ list of int
106
+ List of bits (0 or 1), LSB first
107
+
108
+ Examples
109
+ --------
110
+ >>> bit_decompose(5, 2**256, 4)
111
+ [1, 0, 1, 0]
112
+ >>> bit_decompose(0, 2**256, 4)
113
+ [0, 0, 0, 0]
114
+ """
115
+ if hasattr(value, '__int__'):
116
+ v = int(value) % order
117
+ else:
118
+ v = int(str(value)) % order
119
+
120
+ bits = []
121
+ for i in range(num_bits):
122
+ bits.append((v >> i) & 1)
123
+ return bits
124
+
125
+
126
+ def bits_to_int(bits: List[int], order: int) -> int:
127
+ """
128
+ Reconstruct an integer from its bit representation, reduced mod order.
129
+
130
+ This is the inverse of bit_decompose. The result is always reduced
131
+ modulo the group order to ensure values stay in the valid field range.
132
+
133
+ Parameters
134
+ ----------
135
+ bits : list of int
136
+ List of bits (0 or 1), LSB first
137
+ order : int
138
+ The group order
139
+
140
+ Returns
141
+ -------
142
+ int
143
+ The reconstructed integer, reduced mod order
144
+
145
+ Examples
146
+ --------
147
+ >>> bits_to_int([1, 0, 1, 0], 2**256)
148
+ 5
149
+ >>> bits_to_int([0, 0, 0, 0], 2**256)
150
+ 0
151
+ """
152
+ result = 0
153
+ for i, bit in enumerate(bits):
154
+ if bit:
155
+ result += (1 << i)
156
+ return result % order
157
+
158
+
159
+ class PedersenCommitment:
160
+ """
161
+ Pedersen Commitment Scheme for Elliptic Curve Groups.
162
+
163
+ Implements the information-theoretically hiding commitment scheme:
164
+ C = g^value * h^randomness
165
+
166
+ where g and h are generators with unknown discrete log relationship.
167
+
168
+ Properties:
169
+ - Computationally binding (under DLP assumption)
170
+ - Information-theoretically hiding
171
+ - Additively homomorphic
172
+
173
+ Parameters
174
+ ----------
175
+ group : ECGroup
176
+ An elliptic curve group object
177
+ g : GElement, optional
178
+ First generator (random if not provided)
179
+ h : GElement, optional
180
+ Second generator (random if not provided)
181
+
182
+ Examples
183
+ --------
184
+ >>> from charm.toolbox.eccurve import secp256k1
185
+ >>> from charm.toolbox.ecgroup import ECGroup, ZR
186
+ >>> group = ECGroup(secp256k1)
187
+ >>> pc = PedersenCommitment(group)
188
+ >>> pc.setup()
189
+ >>> value = group.random(ZR)
190
+ >>> c, r = pc.commit(value)
191
+ >>> pc.open(c, value, r)
192
+ True
193
+ """
194
+
195
+ def __init__(self, group: ECGroup, g: Optional[GElement] = None,
196
+ h: Optional[GElement] = None):
197
+ if group is None:
198
+ raise ValueError("group cannot be None")
199
+ self.group = group
200
+ self.order = int(group.order())
201
+ self._g = g
202
+ self._h = h
203
+
204
+ def setup(self) -> Tuple[GElement, GElement]:
205
+ """Generate random generators if not already set."""
206
+ if self._g is None:
207
+ self._g = self.group.random(G)
208
+ if self._h is None:
209
+ self._h = self.group.random(G)
210
+ return self._g, self._h
211
+
212
+ @property
213
+ def g(self) -> GElement:
214
+ """First generator."""
215
+ if self._g is None:
216
+ raise RuntimeError("Call setup() first")
217
+ return self._g
218
+
219
+ @property
220
+ def h(self) -> GElement:
221
+ """Second generator."""
222
+ if self._h is None:
223
+ raise RuntimeError("Call setup() first")
224
+ return self._h
225
+
226
+ def commit(self, value: Any, randomness: Optional[ZRElement] = None
227
+ ) -> Tuple[GElement, ZRElement]:
228
+ """
229
+ Create Pedersen commitment: C = g^value * h^randomness.
230
+
231
+ Parameters
232
+ ----------
233
+ value : ZRElement or int
234
+ Value to commit to
235
+ randomness : ZRElement, optional
236
+ Randomness for commitment (generated if not provided)
237
+
238
+ Returns
239
+ -------
240
+ tuple
241
+ (commitment, randomness)
242
+ """
243
+ if randomness is None:
244
+ randomness = self.group.random(ZR)
245
+
246
+ if isinstance(value, int):
247
+ value = self.group.init(ZR, value % self.order)
248
+
249
+ commitment = (self.g ** value) * (self.h ** randomness)
250
+ return commitment, randomness
251
+
252
+ def open(self, commitment: GElement, value: Any,
253
+ randomness: ZRElement) -> bool:
254
+ """
255
+ Verify that a commitment opens to the given value.
256
+
257
+ Parameters
258
+ ----------
259
+ commitment : GElement
260
+ The commitment to verify
261
+ value : ZRElement or int
262
+ The claimed value
263
+ randomness : ZRElement
264
+ The randomness used in commitment
265
+
266
+ Returns
267
+ -------
268
+ bool
269
+ True if commitment opens correctly
270
+ """
271
+ if isinstance(value, int):
272
+ value = self.group.init(ZR, value % self.order)
273
+
274
+ expected = (self.g ** value) * (self.h ** randomness)
275
+ return commitment == expected
276
+
277
+ def add(self, c1: GElement, c2: GElement) -> GElement:
278
+ """
279
+ Homomorphically add two commitments.
280
+
281
+ If c1 = Commit(v1, r1) and c2 = Commit(v2, r2),
282
+ then c1 * c2 = Commit(v1 + v2, r1 + r2).
283
+
284
+ Parameters
285
+ ----------
286
+ c1 : GElement
287
+ First commitment
288
+ c2 : GElement
289
+ Second commitment
290
+
291
+ Returns
292
+ -------
293
+ GElement
294
+ Combined commitment
295
+ """
296
+ return c1 * c2
charm/toolbox/msp.py ADDED
@@ -0,0 +1,175 @@
1
+ """
2
+ This class is adapted from the SecretUtil class in charm/toolbox/secretutil.py.
3
+ It provides the following methods:
4
+ - createPolicy: convert a Boolean formula encoded as a string into a policy represented like a tree;
5
+ - convertPolicyToMSP: convert a policy into a monotone span program (MSP);
6
+ - getCoefficients: given a policy, returns a coefficient for every attribute;
7
+ - strip_index: remove the index from an attribute (i.e., x_y -> x);
8
+ - prune: determine whether a given set of attributes satisfies the policy
9
+ (returns false if it doesn't, otherwise a good enough subset of attributes);
10
+ - getAttributeList: retrieve the attributes that occur in a policy tree in order (left to right).
11
+ """
12
+
13
+ from charm.core.math.pairing import ZR
14
+ from charm.toolbox.policytree import *
15
+
16
+
17
+ class MSP:
18
+
19
+ def __init__(self, groupObj, verbose=True):
20
+ self.len_longest_row = 1
21
+ self.group = groupObj
22
+
23
+ def createPolicy(self, policy_string):
24
+ """
25
+ Convert a Boolean formula represented as a string into a policy represented like a tree.
26
+ """
27
+
28
+ assert type(policy_string) in [bytes, str], "invalid type for policy_string"
29
+ if type(policy_string) == bytes:
30
+ policy_string = policy_string.decode('utf-8')
31
+ parser = PolicyParser()
32
+ policy_obj = parser.parse(policy_string)
33
+ _dictCount, _dictLabel = {}, {}
34
+ parser.findDuplicates(policy_obj, _dictCount)
35
+ for i in _dictCount.keys():
36
+ if _dictCount[i] > 1: _dictLabel[i] = 0
37
+ parser.labelDuplicates(policy_obj, _dictLabel)
38
+ return policy_obj
39
+
40
+ def convert_policy_to_msp(self, tree):
41
+ """
42
+ Convert a policy into a monotone span program (MSP)
43
+ represented by a dictionary with (attribute, row) pairs
44
+ """
45
+
46
+ root_vector = [1]
47
+ # listOfAttributeRowPairs = {}
48
+ self.len_longest_row = 1
49
+ return self._convert_policy_to_msp(tree, root_vector)
50
+
51
+ def _convert_policy_to_msp(self, subtree, curr_vector):
52
+ """
53
+ Given a vector for the current node,
54
+ returns the vectors for its children in the form of a dictionary
55
+ """
56
+
57
+ if subtree is None:
58
+ return None
59
+
60
+ type = subtree.getNodeType()
61
+
62
+ if type == OpType.ATTR:
63
+ # print ('ATTR: ', subtree, subtree.getAttributeAndIndex(), currVector)
64
+ return {subtree.getAttributeAndIndex(): curr_vector}
65
+
66
+ if type == OpType.OR:
67
+ left_list = self._convert_policy_to_msp(subtree.getLeft(), curr_vector)
68
+ right_list = self._convert_policy_to_msp(subtree.getRight(), curr_vector)
69
+ # print ('OR l: ', leftList, 'r: ', rightList)
70
+ left_list.update(right_list)
71
+ return left_list
72
+
73
+ if type == OpType.AND:
74
+ length = len(curr_vector)
75
+ left_vector = curr_vector + [0] * (self.len_longest_row - length) + [1]
76
+ right_vector = [0] * self.len_longest_row + [-1] # [0]*k creates a vector of k zeroes
77
+ # extendedVector = currVector + [0]*(self.lengthOfLongestRow-length)
78
+ # leftVector = extendedVector + [1]
79
+ # rightVector = extendedVector + [2] # [0]*k creates a vector of k zeroes
80
+ self.len_longest_row += 1
81
+ left_list = self._convert_policy_to_msp(subtree.getLeft(), left_vector)
82
+ right_list = self._convert_policy_to_msp(subtree.getRight(), right_vector)
83
+ # print ('AND l: ', leftList, 'r: ', rightList)
84
+ left_list.update(right_list)
85
+ return left_list
86
+
87
+ return None
88
+
89
+ def getCoefficients(self, tree):
90
+ """
91
+ Given a policy, returns a coefficient for every attribute.
92
+ """
93
+
94
+ coeffs = {}
95
+ self._getCoefficientsDict(tree, coeffs)
96
+ return coeffs
97
+
98
+ def recoverCoefficients(self, list):
99
+ """
100
+ recovers the coefficients over a binary tree.
101
+ """
102
+
103
+ coeff = {}
104
+ list2 = [self.group.init(ZR, i) for i in list]
105
+ for i in list2:
106
+ result = 1
107
+ for j in list2:
108
+ if not (i == j):
109
+ # lagrange basis poly
110
+ result *= (0 - j) / (i - j)
111
+ # print("coeff '%d' => '%s'" % (i, result))
112
+ coeff[int(i)] = result
113
+ return coeff
114
+
115
+ def _getCoefficientsDict(self, tree, coeff_list, coeff=1):
116
+ """
117
+ recover coefficient over a binary tree where possible node types are OR = (1 of 2)
118
+ and AND = (2 of 2) secret sharing. The leaf nodes are attributes and the coefficients are
119
+ recorded in a coeff-list dictionary.
120
+ """
121
+
122
+ if tree:
123
+ node = tree.getNodeType()
124
+ if (node == OpType.AND):
125
+ this_coeff = self.recoverCoefficients([1, 2])
126
+ # left child => coeff[1], right child => coeff[2]
127
+ self._getCoefficientsDict(tree.getLeft(), coeff_list, coeff * this_coeff[1])
128
+ self._getCoefficientsDict(tree.getRight(), coeff_list, coeff * this_coeff[2])
129
+ elif (node == OpType.OR):
130
+ this_coeff = self.recoverCoefficients([1])
131
+ self._getCoefficientsDict(tree.getLeft(), coeff_list, coeff * this_coeff[1])
132
+ self._getCoefficientsDict(tree.getRight(), coeff_list, coeff * this_coeff[1])
133
+ elif (node == OpType.ATTR):
134
+ attr = tree.getAttributeAndIndex()
135
+ coeff_list[attr] = coeff
136
+ else:
137
+ return None
138
+
139
+ def strip_index(self, node_str):
140
+ """
141
+ Remove the index from an attribute (i.e., x_y -> x).
142
+ """
143
+
144
+ if node_str.find('_') != -1:
145
+ return node_str.split('_')[0]
146
+ return node_str
147
+
148
+ def prune(self, policy, attributes):
149
+ """
150
+ Determine whether a given set of attributes satisfies the policy
151
+ (returns false if it doesn't, otherwise a good enough subset of attributes).
152
+ """
153
+
154
+ parser = PolicyParser()
155
+ return parser.prune(policy, attributes)
156
+
157
+ def getAttributeList(self, Node):
158
+ """
159
+ Retrieve the attributes that occur in a policy tree in order (left to right).
160
+ """
161
+
162
+ aList = []
163
+ self._getAttributeList(Node, aList)
164
+ return aList
165
+
166
+ def _getAttributeList(self, Node, List):
167
+ if (Node == None):
168
+ return None
169
+ # V, L, R
170
+ if (Node.getNodeType() == OpType.ATTR):
171
+ List.append(Node.getAttributeAndIndex()) # .getAttribute()
172
+ else:
173
+ self._getAttributeList(Node.getLeft(), List)
174
+ self._getAttributeList(Node.getRight(), List)
175
+ return None