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
charm/toolbox/node.py ADDED
@@ -0,0 +1,120 @@
1
+ import string
2
+ from charm.toolbox.enum import *
3
+
4
+ OpType = Enum('OR', 'AND', 'ATTR', 'THRESHOLD', 'CONDITIONAL', 'NONE')
5
+
6
+ class BinNode:
7
+ def __init__(self, value, left=None, right=None):
8
+ #types of node
9
+ # self.OR = 1
10
+ # self.AND = 2
11
+ # self.ATTR = 0
12
+ self.negated = False
13
+ self.index = None
14
+ #OF = '' # anything above 1 and 2
15
+ if(isinstance(value, str)):
16
+ if value[0] == '!':
17
+ value = value[1:] # remove but set flag
18
+ self.negated = True
19
+ if value.find('_') != -1:
20
+ val = value.split('_')
21
+ self.index = int(val[1]) # index
22
+ value = val[0]
23
+ self.type = OpType.ATTR
24
+ self.attribute = value.upper()
25
+
26
+ elif(value >= OpType.OR and value < OpType.NONE):
27
+ self.type = value
28
+ if self.type == OpType.OR:
29
+ self.threshold = 1
30
+ elif self.type == OpType.AND:
31
+ self.threshold = 2
32
+ # elif self.type == OpType.THRESHOLD:
33
+ self.attribute = ''
34
+ else:
35
+ self.type = None
36
+ self.attribute = ''
37
+
38
+ self.left = left
39
+ self.right = right
40
+
41
+ def __repr__(self):
42
+ return str(self)
43
+
44
+ def __str__(self):
45
+ if(self.type == OpType.ATTR):
46
+ if self.negated: prefix = '!'
47
+ else: prefix = ''
48
+ if self.index != None: postfix = '_' + str(self.index)
49
+ else: postfix = ''
50
+ return prefix + self.attribute + postfix
51
+ else:
52
+ left = str(self.left)
53
+ right = str(self.right)
54
+
55
+ if(self.type == OpType.OR):
56
+ return ('('+ left + ' or ' + right + ')')
57
+ elif(self.type == OpType.AND):
58
+ return ('(' + left + ' and ' + right + ')')
59
+ return None
60
+
61
+ def getAttribute(self):
62
+ if (self.type == OpType.ATTR):
63
+ if self.negated: prefix = '!'
64
+ else: prefix = ''
65
+ return prefix + self.attribute
66
+ return
67
+
68
+ def getAttributeAndIndex(self):
69
+ if (self.type == OpType.ATTR):
70
+ if self.negated: prefix = '!'
71
+ else: prefix = ''
72
+ if self.index != None: postfix = '_' + str(self.index)
73
+ else: postfix = ''
74
+
75
+ return prefix + self.attribute + postfix
76
+ return
77
+
78
+ def __iter__(self):
79
+ return self
80
+
81
+ def __eq__(self, other):
82
+ #print("checking...:", self, str(other))
83
+ if other == None:
84
+ return False
85
+ if type(self) == type(other):
86
+ return self.getAttribute() == other.getAttribute()
87
+ elif type(other) in [str, bytes]:
88
+ return other in self.getAttributeAndIndex()
89
+ elif type(self) in [str, bytes]:
90
+ return self in other.getAttributeAndIndex()
91
+ else:
92
+ raise ValueError('BinNode - invalid comparison.')
93
+
94
+ def getLeft(self):
95
+ return self.left
96
+
97
+ def getRight(self):
98
+ return self.right
99
+
100
+ def getNodeType(self):
101
+ return self.type
102
+
103
+ def addSubNode(self, left, right):
104
+ # set subNodes appropriately
105
+ self.left = left if left != None else None
106
+ self.right = right if left != None else None
107
+
108
+ # only applies function on leaf nodes
109
+ def traverse(self, function):
110
+ # visit node then traverse left and right
111
+ function(self.type, self)
112
+ if(self.left == None):
113
+ return None
114
+ self.left.traverse(function)
115
+ if(self.right == None):
116
+ return None
117
+ self.right.traverse(function)
118
+ return None
119
+
120
+
@@ -0,0 +1,22 @@
1
+ """
2
+ Oblivious Transfer (OT) Protocols for Charm
3
+
4
+ This module provides implementations of Oblivious Transfer protocols
5
+ for use with elliptic curve groups.
6
+
7
+ Available classes:
8
+ - SimpleOT: Simplest OT (Chou-Orlandi style) for 1-out-of-2 OT
9
+ - OTExtension: IKNP-style OT Extension for efficient many-OT execution
10
+ - DPF: Distributed Point Function based on GGM construction
11
+ - MPFSS: Multi-Point Function Secret Sharing using DPF
12
+ - SilentOT: Silent OT Extension using PCG (Boyle et al. Crypto 2019)
13
+ """
14
+
15
+ from charm.toolbox.ot.base_ot import SimpleOT
16
+ from charm.toolbox.ot.ot_extension import OTExtension
17
+ from charm.toolbox.ot.dpf import DPF
18
+ from charm.toolbox.ot.mpfss import MPFSS
19
+ from charm.toolbox.ot.silent_ot import SilentOT
20
+
21
+ __all__ = ['SimpleOT', 'OTExtension', 'DPF', 'MPFSS', 'SilentOT']
22
+
@@ -0,0 +1,374 @@
1
+ '''
2
+ Simplest Oblivious Transfer (Chou-Orlandi style) for Elliptic Curve Groups
3
+
4
+ | From: "The Simplest Protocol for Oblivious Transfer"
5
+ | By: Tung Chou and Claudio Orlandi
6
+ | Published: LATINCRYPT 2015
7
+ | URL: https://eprint.iacr.org/2015/267
8
+
9
+ * type: oblivious transfer (1-out-of-2)
10
+ * setting: Elliptic Curve DDH-hard group
11
+ * assumption: DDH
12
+
13
+ :Authors: Elton de Souza
14
+ :Date: 01/2026
15
+ '''
16
+
17
+ from charm.toolbox.ecgroup import ECGroup, ZR, G
18
+ from charm.toolbox.symcrypto import AuthenticatedCryptoAbstraction
19
+ from hashlib import sha256
20
+ import logging
21
+
22
+ # Module logger
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class SimpleOT:
27
+ """
28
+ Simplest Oblivious Transfer based on Chou-Orlandi for EC groups.
29
+
30
+ This implementation is thread-safe - each instance maintains its own
31
+ group reference and state.
32
+
33
+ Implements 1-out-of-2 OT where:
34
+ - Sender has two messages (m0, m1)
35
+ - Receiver has a choice bit b
36
+ - Receiver learns m_b without learning m_{1-b}
37
+ - Sender learns nothing about b
38
+
39
+ >>> from charm.toolbox.eccurve import secp256k1
40
+ >>> from charm.toolbox.ecgroup import ECGroup
41
+ >>> group = ECGroup(secp256k1)
42
+ >>> sender = SimpleOT(group)
43
+ >>> receiver = SimpleOT(group)
44
+ >>> # Sender setup: generates public parameters
45
+ >>> sender_params = sender.sender_setup()
46
+ >>> # Receiver chooses bit 0
47
+ >>> receiver_response, receiver_state = receiver.receiver_choose(sender_params, 0)
48
+ >>> # Sender transfers encrypted messages
49
+ >>> m0, m1 = b'message zero!!!!', b'message one!!!!!'
50
+ >>> ciphertexts = sender.sender_transfer(receiver_response, m0, m1)
51
+ >>> # Receiver retrieves chosen message
52
+ >>> result = receiver.receiver_retrieve(ciphertexts, receiver_state)
53
+ >>> result == m0
54
+ True
55
+ >>> # Test with choice bit 1
56
+ >>> sender2 = SimpleOT(group)
57
+ >>> receiver2 = SimpleOT(group)
58
+ >>> sender_params2 = sender2.sender_setup()
59
+ >>> receiver_response2, receiver_state2 = receiver2.receiver_choose(sender_params2, 1)
60
+ >>> ciphertexts2 = sender2.sender_transfer(receiver_response2, m0, m1)
61
+ >>> result2 = receiver2.receiver_retrieve(ciphertexts2, receiver_state2)
62
+ >>> result2 == m1
63
+ True
64
+
65
+ Security Note
66
+ -------------
67
+ - Each SimpleOT instance should be used for a SINGLE OT operation.
68
+ - Reusing instances with the same keys is NOT recommended for security.
69
+ - The instance generates fresh randomness per transfer but shares the
70
+ sender's key across transfers if sender_setup is not called again.
71
+ - For multiple OT operations, create new SimpleOT instances or use
72
+ OT extension (see OTExtension class).
73
+ - To regenerate keys on an existing instance, call reset_sender() before
74
+ sender_setup(), or simply call sender_setup() again which generates
75
+ fresh keys.
76
+
77
+ Security Limitations
78
+ --------------------
79
+ WARNING: This implementation is NOT constant-time and is vulnerable to
80
+ timing attacks. The following operations leak timing information:
81
+
82
+ - Modular inversion: Variable-time modular inverse operations
83
+ - Bit extraction: Conditional logic based on secret choice bit values
84
+ - Conditional branching: Control flow depends on secret data
85
+
86
+ This implementation is suitable for research and educational purposes only.
87
+ Do NOT use in production environments where side-channel attacks are a concern.
88
+ Production deployments should use constant-time cryptographic implementations
89
+ with proper side-channel mitigations.
90
+
91
+ Encryption Note
92
+ ---------------
93
+ This implementation uses AuthenticatedCryptoAbstraction for symmetric
94
+ encryption of OT messages. The current implementation provides AEAD
95
+ (Authenticated Encryption with Associated Data) using AES-CBC with
96
+ HMAC-SHA256 in an Encrypt-then-MAC construction. While this provides
97
+ authentication, it is not as robust as AES-GCM. For production use,
98
+ consider verifying the underlying implementation uses authenticated
99
+ encryption (e.g., AES-GCM) to prevent ciphertext malleability attacks.
100
+ """
101
+
102
+ def __init__(self, groupObj):
103
+ """
104
+ Initialize SimpleOT with an elliptic curve group.
105
+
106
+ Parameters
107
+ ----------
108
+ groupObj : ECGroup
109
+ An elliptic curve group object from charm.toolbox.ecgroup
110
+ """
111
+ if groupObj is None:
112
+ raise ValueError("groupObj cannot be None")
113
+ self.group = groupObj
114
+ self._a = None # Sender's private key
115
+ self._A = None # Sender's public key
116
+ self._g = None # Generator point
117
+
118
+ def _derive_key(self, point):
119
+ """
120
+ Derive a symmetric key from an EC point using SHA-256.
121
+
122
+ Parameters
123
+ ----------
124
+ point : ec_element
125
+ An elliptic curve point
126
+
127
+ Returns
128
+ -------
129
+ bytes
130
+ 32-byte key suitable for symmetric encryption
131
+ """
132
+ point_bytes = self.group.serialize(point)
133
+ return sha256(point_bytes).digest()
134
+
135
+ def _validate_point(self, point, name="point"):
136
+ """
137
+ Validate that a point is a valid non-identity element on the curve.
138
+
139
+ Parameters
140
+ ----------
141
+ point : ec_element
142
+ An elliptic curve point to validate
143
+ name : str
144
+ Name of the point for error messages
145
+
146
+ Raises
147
+ ------
148
+ ValueError
149
+ If the point is invalid, at infinity (identity), or not on the curve
150
+
151
+ Note on Subgroup Validation
152
+ ---------------------------
153
+ For curves with cofactor > 1 (e.g., Curve25519 with cofactor 8), an
154
+ additional subgroup membership test is required to prevent small subgroup
155
+ attacks. This check verifies that ``point ** order == identity``.
156
+
157
+ However, secp256k1 (the default curve) has **cofactor 1** (prime order
158
+ group), meaning all non-identity points on the curve are already in the
159
+ prime-order subgroup. Therefore, subgroup validation is unnecessary for
160
+ secp256k1 and is not performed here.
161
+
162
+ If this implementation is extended to support curves with cofactor > 1,
163
+ add the following check after the on-curve validation::
164
+
165
+ # Subgroup membership test (required for curves with cofactor > 1):
166
+ # order = self.group.order()
167
+ # if not (point ** order).isInf():
168
+ # raise ValueError(f"Invalid {name}: point not in prime-order subgroup")
169
+ """
170
+ # Check for identity element (point at infinity)
171
+ if point.isInf():
172
+ raise ValueError(f"Invalid {name}: point is at infinity (identity element)")
173
+
174
+ # Validate point is on curve by serialize/deserialize round-trip
175
+ # The deserialize function validates the point is on the curve
176
+ try:
177
+ serialized = self.group.serialize(point)
178
+ deserialized = self.group.deserialize(serialized)
179
+ if deserialized is None or deserialized is False:
180
+ raise ValueError(f"Invalid {name}: point is not on the curve")
181
+ except Exception as e:
182
+ raise ValueError(f"Invalid {name}: failed to validate point - {e}")
183
+
184
+ # Note: Subgroup membership test is NOT performed here because secp256k1
185
+ # has cofactor 1. For curves with cofactor > 1, uncomment the check above.
186
+
187
+ def reset_sender(self):
188
+ """
189
+ Reset the sender's state, clearing all keys.
190
+
191
+ Call this method before sender_setup() to ensure fresh keys are
192
+ generated. This is useful when reusing a SimpleOT instance for
193
+ multiple OT operations (though creating new instances is preferred).
194
+
195
+ Note: sender_setup() also generates fresh keys, so calling
196
+ reset_sender() is optional but makes the intent explicit.
197
+ """
198
+ self._a = None
199
+ self._A = None
200
+ self._g = None
201
+ logger.debug("Sender state reset - keys cleared")
202
+
203
+ def sender_setup(self):
204
+ """
205
+ Sender generates public parameters for the OT protocol.
206
+
207
+ Returns
208
+ -------
209
+ dict
210
+ Dictionary containing:
211
+ - 'A': sender's public key (g^a)
212
+ - 'g': generator point
213
+ """
214
+ self._a = self.group.random(ZR)
215
+ g = self.group.random(G)
216
+ self._A = g ** self._a
217
+ self._g = g
218
+
219
+ logger.debug("Sender setup: a=%s, A=%s, g=%s", self._a, self._A, g)
220
+
221
+ return {'A': self._A, 'g': g}
222
+
223
+ def receiver_choose(self, sender_params, choice_bit):
224
+ """
225
+ Receiver generates response based on choice bit.
226
+
227
+ Parameters
228
+ ----------
229
+ sender_params : dict
230
+ Public parameters from sender_setup containing 'A' and 'g'
231
+ choice_bit : int
232
+ The receiver's choice (0 or 1)
233
+
234
+ Returns
235
+ -------
236
+ tuple
237
+ (receiver_response, receiver_state) where:
238
+ - receiver_response: dict with 'B' to send to sender
239
+ - receiver_state: dict with private state for receiver_retrieve
240
+
241
+ Raises
242
+ ------
243
+ ValueError
244
+ If choice_bit is not 0 or 1, or if sender's points are invalid
245
+ """
246
+ if choice_bit not in (0, 1):
247
+ raise ValueError("choice_bit must be 0 or 1")
248
+
249
+ A = sender_params['A']
250
+ g = sender_params['g']
251
+
252
+ # Validate sender's points are valid curve points (not identity or off-curve)
253
+ # This prevents attacks using invalid or small-subgroup points
254
+ self._validate_point(g, "generator g")
255
+ self._validate_point(A, "sender public key A")
256
+
257
+ # Receiver picks random b
258
+ b = self.group.random(ZR)
259
+
260
+ # Compute B based on choice:
261
+ # If choice=0: B = g^b (so B^a = g^(ab) = k0)
262
+ # If choice=1: B = A * g^b (so (B/A)^a = g^(ab) = k1)
263
+ if choice_bit == 0:
264
+ B = g ** b
265
+ else:
266
+ B = A * (g ** b)
267
+
268
+ logger.debug("Receiver choose (bit=%d): b=%s, B=%s", choice_bit, b, B)
269
+
270
+ # The key the receiver will compute: k_choice = A^b
271
+ receiver_state = {
272
+ 'b': b,
273
+ 'A': A,
274
+ 'choice_bit': choice_bit
275
+ }
276
+
277
+ return {'B': B}, receiver_state
278
+
279
+ def sender_transfer(self, receiver_response, m0, m1):
280
+ """
281
+ Sender encrypts both messages using derived keys.
282
+
283
+ Parameters
284
+ ----------
285
+ receiver_response : dict
286
+ Response from receiver_choose containing 'B'
287
+ m0 : bytes
288
+ First message (sent if receiver chose 0)
289
+ m1 : bytes
290
+ Second message (sent if receiver chose 1)
291
+
292
+ Returns
293
+ -------
294
+ dict
295
+ Dictionary containing:
296
+ - 'e0': encrypted m0
297
+ - 'e1': encrypted m1
298
+
299
+ Raises
300
+ ------
301
+ RuntimeError
302
+ If sender_setup was not called first
303
+ """
304
+ if self._a is None or self._A is None:
305
+ raise RuntimeError("sender_setup must be called before sender_transfer")
306
+
307
+ B = receiver_response['B']
308
+
309
+ # Validate receiver's point B is a valid curve point (not identity or off-curve)
310
+ # This prevents attacks using invalid or small-subgroup points
311
+ self._validate_point(B, "receiver public key B")
312
+
313
+ # Compute keys:
314
+ # k0 = H(B^a) - receiver gets this if they chose 0
315
+ # k1 = H((B/A)^a) = H(B^a / A^a) - receiver gets this if they chose 1
316
+ k0_point = B ** self._a
317
+ k1_point = (B * (self._A ** -1)) ** self._a
318
+
319
+ k0 = self._derive_key(k0_point)
320
+ k1 = self._derive_key(k1_point)
321
+
322
+ logger.debug("Sender transfer: k0_point=%s, k1_point=%s", k0_point, k1_point)
323
+
324
+ # Encrypt messages
325
+ cipher0 = AuthenticatedCryptoAbstraction(k0)
326
+ cipher1 = AuthenticatedCryptoAbstraction(k1)
327
+
328
+ e0 = cipher0.encrypt(m0)
329
+ e1 = cipher1.encrypt(m1)
330
+
331
+ return {'e0': e0, 'e1': e1}
332
+
333
+ def receiver_retrieve(self, sender_ciphertexts, receiver_state):
334
+ """
335
+ Receiver decrypts the chosen message.
336
+
337
+ Parameters
338
+ ----------
339
+ sender_ciphertexts : dict
340
+ Ciphertexts from sender_transfer containing 'e0' and 'e1'
341
+ receiver_state : dict
342
+ Private state from receiver_choose
343
+
344
+ Returns
345
+ -------
346
+ bytes
347
+ The decrypted chosen message
348
+
349
+ Raises
350
+ ------
351
+ ValueError
352
+ If decryption fails (should not happen in honest execution)
353
+ """
354
+ b = receiver_state['b']
355
+ A = receiver_state['A']
356
+ choice_bit = receiver_state['choice_bit']
357
+
358
+ # Compute the key: k_choice = A^b
359
+ # This equals:
360
+ # - k0 = (g^a)^b = g^(ab) if choice=0 (since B = g^b, B^a = g^(ab))
361
+ # - k1 = (g^a)^b = g^(ab) if choice=1 (since B = A*g^b, (B/A)^a = g^(ab))
362
+ k_point = A ** b
363
+ k = self._derive_key(k_point)
364
+
365
+ logger.debug("Receiver retrieve (choice=%d): k_point=%s", choice_bit, k_point)
366
+
367
+ # Decrypt the chosen ciphertext
368
+ cipher = AuthenticatedCryptoAbstraction(k)
369
+
370
+ if choice_bit == 0:
371
+ return cipher.decrypt(sender_ciphertexts['e0'])
372
+ else:
373
+ return cipher.decrypt(sender_ciphertexts['e1'])
374
+