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,654 @@
1
+ '''
2
+ **Pointcheval-Sanders Short Randomizable Signatures (PS16)**
3
+
4
+ *Authors:* David Pointcheval, Olivier Sanders
5
+
6
+ | **Title:** "Short Randomizable Signatures"
7
+ | **Published in:** RSA Conference on Topics in Cryptology, 2016
8
+ | **Available from:** https://dl.acm.org/doi/10.1007/978-3-319-29485-8_7
9
+ | **Notes:** Implements single/multi message signatures and blind signatures
10
+
11
+ .. rubric:: Scheme Properties
12
+
13
+ * **Type:** blind signature
14
+ * **Setting:** bilinear groups (asymmetric)
15
+ * **Assumption:** PS assumption
16
+
17
+ .. rubric:: Implementation
18
+
19
+ :Authors: Ahmed Bakr
20
+ :Date: 04/2023
21
+ '''
22
+
23
+ import sys
24
+ from charm.toolbox.pairinggroup import PairingGroup, ZR, G1, G2, pair
25
+ from charm.core.engine.util import objectToBytes
26
+ from charm.toolbox.PKSig import PKSig
27
+
28
+
29
+ def dump_to_zp_element(obj, group_obj):
30
+ serialized_message = objectToBytes(obj, group_obj)
31
+ return group_obj.hash(serialized_message) # convert the serialized message to object from Z_p
32
+
33
+
34
+ class ShnorrInteractiveZKP():
35
+ class Prover:
36
+ def __init__(self, secret_t, secret_messages, groupObj):
37
+ self.__r_t = None
38
+ self.__r_ms = None
39
+ self.group = groupObj
40
+ self.__ms = [dump_to_zp_element(secret_message, groupObj) for secret_message in secret_messages]
41
+ self.__t = secret_t # t is an element, so no need to transform it into an element
42
+
43
+ def create_prover_commitments(self, pk):
44
+ """
45
+ 1) This function is executed by the prover to send a random value to the verifier
46
+ """
47
+ if 'Ys' not in pk:
48
+ pk['Ys'] = [pk['Y']] # Hack to convert it to an array because this method is general and used for both single and multiple messages
49
+ self.__r_ms = [self.group.random() for _ in range(len(self.__ms))]
50
+ self.__r_t = self.group.random()
51
+ Y_pow_m_prod = pk['Ys'][0] ** self.__r_ms[0]
52
+ for i in range(1, len(self.__ms)):
53
+ Y_pow_m_prod *= pk['Ys'][i] ** self.__r_ms[i]
54
+ Rc = (pk['g'] ** self.__r_t) * Y_pow_m_prod # Follow the same equation used to blind the message
55
+ return Rc
56
+
57
+ def create_proof(self, c):
58
+ """
59
+ 3) This function is executed by the prover after he received the challenge value (c) from the verifier
60
+ """
61
+ s_t = self.__r_t + c * self.__t
62
+ s_ms = [r_m + c * m for (r_m, m) in zip(self.__r_ms, self.__ms)]
63
+ return (s_t, s_ms) # proof
64
+
65
+ class Verifier:
66
+
67
+ def __init__(self, groupObj):
68
+ self.group = groupObj
69
+
70
+ def create_verifier_challenge(self):
71
+ """
72
+ 2) This function is executed by the verifier after he had received the value u from the prover to send a challenge value to the prover.
73
+ """
74
+ self.c = self.group.random()
75
+ return self.c
76
+
77
+ def is_proof_verified(self, s_t, s_ms, pk, blinded_message, commitment):
78
+ """
79
+ 4) This function is executed by the verifier to verify the authenticity of the proof sent by the prover
80
+ """
81
+ if 'Ys' not in pk:
82
+ pk['Ys'] = [pk['Y']] # Hack to convert it to an array because this method is general and used for both single and multiple messages
83
+ Y_pow_m_prod = pk['Ys'][0] ** s_ms[0]
84
+ for i in range(1, len(s_ms)):
85
+ Y_pow_m_prod *= pk['Ys'][i] ** s_ms[i]
86
+ if (pk['g'] ** s_t) * Y_pow_m_prod == (blinded_message ** self.c) * commitment:
87
+ return True
88
+ return False
89
+
90
+
91
+ class PS_Sig(PKSig):
92
+
93
+ def __init__(self, groupObj):
94
+ PKSig.__init__(self)
95
+ self.group = groupObj
96
+
97
+ def _dump_to_zp_element(self, obj):
98
+ serialized_message = objectToBytes(obj, self.group)
99
+ return self.group.hash(serialized_message) # convert the serialized message to object from Z_p
100
+
101
+ def keygen(self):
102
+ """
103
+ This function is used to generate the secret key and the public key of the signer
104
+ """
105
+ print("This is a stub function. Implement it in the child class")
106
+
107
+ def sign(self, sk, message):
108
+ """
109
+ This function is used for the signer to sign a message
110
+ Inputs:
111
+ - sk: Secret key of the signer
112
+ - message: message to be signed
113
+ Outputs:
114
+ - sigma: Signature on the message
115
+ """
116
+ print("This is a stub function. Implement it in the child class")
117
+
118
+ def verify(self, message, pk, sig) -> bool:
119
+ """
120
+ This function is used for the user to verify a signature on a specific message using the message and the public
121
+ key of the signer.
122
+ Inputs:
123
+ - message: The message
124
+ - pk: Public key
125
+ - sig: signature
126
+ Outputs:
127
+ - True if the signature is valid on the message by the user whose public key is pk
128
+ - False, otherwise
129
+ """
130
+ print("This is a stub function. Implement it in the child class")
131
+
132
+
133
+ class PS_BlindSig(PS_Sig):
134
+
135
+ def __init__(self, groupObj):
136
+ PS_Sig.__init__(self, groupObj)
137
+
138
+ def keygen(self):
139
+ """
140
+ This function is used to generate the secret key and the public key of the signer
141
+ """
142
+ print("This is a stub function. Implement it in the child class")
143
+
144
+ def blind(self, message):
145
+ """
146
+ This function takes a message and blinds it to return a blinded message.
147
+ Inputs:
148
+ - message: message to be blinded
149
+ Outputs:
150
+ - blinded_message: A blinded message
151
+ """
152
+ print("This is a stub function. Implement it in the child class")
153
+
154
+ def sign(self, sk, blinded_message):
155
+ """
156
+ This function is used for the signer to sign a message
157
+ Inputs:
158
+ - sk: Secret key of the signer
159
+ - blinded_message: A blinded message to be signed
160
+ Outputs:
161
+ - sigma_dash: Signature on the blinded message
162
+ """
163
+ print("This is a stub function. Implement it in the child class")
164
+
165
+ def unblind(self, blinded_sig, t):
166
+ """
167
+ This function takes a blinded signature and returns the unblinded signature
168
+ Inputs:
169
+ - blinded_sig: Blinded signature
170
+ - t: random number used to blind the original message
171
+ Outputs:
172
+ - sigma: unblinded signature
173
+ """
174
+ print("This is a stub function. Implement it in the child class")
175
+
176
+ def proof_of_knowledge_of_commitment_secrets(self, t, messages, blinded_message, pk, group_obj, debug):
177
+ """This function runs shnorr' interactive proof of knowledge"""
178
+ shnorr_interactive_zkp = ShnorrInteractiveZKP()
179
+ print("Prover wants to prove knowledge of the secret message to the signer (verifier) for him to agree to sign the message")
180
+ prover = shnorr_interactive_zkp.Prover(secret_t=t, secret_messages=messages, groupObj=group_obj)
181
+ verifier = shnorr_interactive_zkp.Verifier(groupObj=group_obj)
182
+ commitments = prover.create_prover_commitments(pk)
183
+ print("Prover sent commitments to the verifier")
184
+ if debug:
185
+ print("Rc = ", commitments)
186
+ challenge = verifier.create_verifier_challenge()
187
+ print("Verifier sends the challenge to the prover: ", challenge)
188
+ s_t, s_m = prover.create_proof(challenge)
189
+ print("Prover sends the proof of knowledge to the verifier: ")
190
+ if debug:
191
+ print("s_t: ", s_t)
192
+ print("s_m: ", s_m)
193
+ prover_knowledge_of_secret_message_status = verifier.is_proof_verified(s_t, s_m, pk, blinded_message, commitments)
194
+ return prover_knowledge_of_secret_message_status
195
+
196
+
197
+ def verify(self, message, pk, sig) -> bool:
198
+ """
199
+ This function is used for the user to verify a signature on a specific message using the message and the public
200
+ key of the signer.
201
+ Inputs:
202
+ - message: The message
203
+ - pk: Public key
204
+ - sig: signature
205
+ Outputs:
206
+ - True if the signature is valid on the message by the user whose public key is pk
207
+ - False, otherwise
208
+ """
209
+ print("This is a stub function. Implement it in the child class")
210
+
211
+
212
+ class PS_BlindSingleMessageSig(PS_BlindSig):
213
+
214
+ def __init__(self, groupObj):
215
+ PS_BlindSig.__init__(self, groupObj)
216
+
217
+ def keygen(self):
218
+ """
219
+ This function is used to generate the secret key and the public key of the signer
220
+ Outputs:
221
+ - sk: Secret key
222
+ - pk: public key
223
+ """
224
+ g = self.group.random(G1)
225
+ g_tilde = self.group.random(G2)
226
+ x = self.group.random()
227
+ y = self.group.random()
228
+
229
+ X = g ** x
230
+ Y = g ** y
231
+ X_tilde = g_tilde ** x
232
+ Y_tilde = g_tilde ** y
233
+
234
+ pk = {'g': g, 'Y': Y, 'g_tilde': g_tilde, 'X_tilde': X_tilde, 'Y_tilde': Y_tilde}
235
+ sk = {'X': X}
236
+
237
+ return sk, pk
238
+
239
+ def blind(self, message, pk):
240
+ """
241
+ This function takes a message and blinds it to return a blinded message.
242
+ Inputs:
243
+ - message: message to be blinded
244
+ - pk: pk is needed to know some of the public parameters used in message blinding
245
+ Outputs:
246
+ - C: A blinded message
247
+ - t: Blind random value
248
+ """
249
+ m = self._dump_to_zp_element(message) # serialize the message to an element
250
+ t = self.group.random()
251
+ C = (pk['g'] ** t) * (pk['Y'] ** m)
252
+
253
+ return C, t
254
+
255
+ def sign(self, sk, pk, blinded_message):
256
+ """
257
+ This function is used for the signer to sign a message
258
+ Inputs:
259
+ - sk: Secret key of the signer
260
+ - pk: Public key of the signer
261
+ - blinded_message: A blinded message to be signed
262
+ Outputs:
263
+ - sigma_dash: Signature on the blinded message
264
+ """
265
+ C = blinded_message
266
+ u = self.group.random()
267
+ sigma_dash_1 = pk['g'] ** u
268
+ sigma_dash_2 = (sk['X'] * C) ** u
269
+ sigma_dash = (sigma_dash_1, sigma_dash_2)
270
+
271
+ return sigma_dash
272
+
273
+ def unblind(self, blinded_sig, t):
274
+ """
275
+ This function takes a blinded signature and returns the unblinded signature
276
+ Inputs:
277
+ - blinded_sig: Blinded signature
278
+ - t: random number used to blind the original message
279
+ Outputs:
280
+ - sigma: unblinded signature
281
+ """
282
+ sigma_dash_1, sigma_dash_2 = blinded_sig
283
+ sigma_1 = sigma_dash_1
284
+ sigma_2 = sigma_dash_2 / (sigma_dash_1 ** t)
285
+
286
+ sigma = (sigma_1, sigma_2)
287
+ return sigma
288
+
289
+ def verify(self, message, pk, sig) -> bool:
290
+ """
291
+ This function is used for the user to verify a signature on a specific message using the message and the public
292
+ key of the signer.
293
+ Inputs:
294
+ - message: The message
295
+ - pk: Public key
296
+ - sig: signature
297
+ Outputs:
298
+ - True if the signature is valid on the message by the user whose public key is pk
299
+ - False, otherwise
300
+ """
301
+ sigma_1, sigma_2 = sig
302
+ m = self._dump_to_zp_element(message) # serialize the message to an element
303
+ if pair(sigma_1, pk['X_tilde'] * (pk['Y_tilde'] ** m)) == pair(sigma_2, pk['g_tilde']):
304
+ return True
305
+ return False
306
+
307
+
308
+ class PS_BlindMultiMessageSig(PS_BlindSig):
309
+
310
+ def __init__(self, groupObj):
311
+ PS_BlindSig.__init__(self, groupObj)
312
+
313
+ def keygen(self, num_messages):
314
+ """
315
+ This function is used to generate the secret key and the public key of the signer
316
+ Outputs:
317
+ - sk: Secret key
318
+ - pk: public key
319
+ """
320
+ g = self.group.random(G1)
321
+ g_tilde = self.group.random(G2)
322
+ x = self.group.random()
323
+ ys = [self.group.random() for i in range(num_messages)]
324
+
325
+ X = g ** x
326
+ Ys = [g ** y for y in ys]
327
+ X_tilde = g_tilde ** x
328
+ Ys_tilde = [g_tilde ** y for y in ys]
329
+
330
+ pk = {'g': g, 'Ys': Ys, 'g_tilde': g_tilde, 'X_tilde': X_tilde, 'Ys_tilde': Ys_tilde}
331
+ sk = {'X': X}
332
+
333
+ return sk, pk
334
+
335
+ def blind(self, messages, pk):
336
+ """
337
+ This function takes a message and blinds it to return a blinded message.
338
+ Inputs:
339
+ - messages: List of messages to be blinded
340
+ - pk: pk is needed to know some of the public parameters used in message blinding
341
+ Outputs:
342
+ - C: A blinded message
343
+ - t: Blind random value
344
+ """
345
+ ms = [self._dump_to_zp_element(message) for message in messages] # serialize the message to an element
346
+ t = self.group.random()
347
+ Y_pow_m_product = pk['Ys'][0] ** ms[0]
348
+ for i in range(1, len(ms)):
349
+ Y_pow_m_product *= pk['Ys'][i] ** ms[i]
350
+ C = (pk['g'] ** t) * Y_pow_m_product
351
+
352
+ return C, t
353
+
354
+ def sign(self, sk, pk, blinded_message):
355
+ """
356
+ This function is used for the signer to sign a message
357
+ Inputs:
358
+ - sk: Secret key of the signer
359
+ - pk: Public key of the signer
360
+ - blinded_message: A blinded message to be signed
361
+ Outputs:
362
+ - sigma_dash: Signature on the blinded message
363
+ """
364
+ C = blinded_message
365
+ u = self.group.random()
366
+ sigma_dash_1 = pk['g'] ** u
367
+ sigma_dash_2 = (sk['X'] * C) ** u
368
+ sigma_dash = (sigma_dash_1, sigma_dash_2)
369
+
370
+ return sigma_dash
371
+
372
+ def unblind(self, blinded_sig, t):
373
+ """
374
+ This function takes a blinded signature and returns the unblinded signature
375
+ Inputs:
376
+ - blinded_sig: Blinded signature
377
+ - t: random number used to blind the original message
378
+ Outputs:
379
+ - sigma: unblinded signature
380
+ """
381
+ sigma_dash_1, sigma_dash_2 = blinded_sig
382
+ sigma_1 = sigma_dash_1
383
+ sigma_2 = sigma_dash_2 / (sigma_dash_1 ** t)
384
+
385
+ sigma = (sigma_1, sigma_2)
386
+ return sigma
387
+
388
+ def verify(self, messages, pk, sig) -> bool:
389
+ """
390
+ This function is used for the user to verify a signature on a specific message using the message and the public
391
+ key of the signer.
392
+ Inputs:
393
+ - messages: List of messages
394
+ - pk: Public key
395
+ - sig: signature
396
+ Outputs:
397
+ - True if the signature is valid on the message by the user whose public key is pk
398
+ - False, otherwise
399
+ """
400
+ sigma_1, sigma_2 = sig
401
+ ms = [self._dump_to_zp_element(message) for message in messages] # serialize the message to an element
402
+ Y_pow_m_product = pk['Ys_tilde'][0] ** ms[0]
403
+ for i in range(1, len(ms)):
404
+ Y_pow_m_product *= pk['Ys_tilde'][i] ** ms[i]
405
+ if pair(sigma_1, pk['X_tilde'] * Y_pow_m_product) == pair(sigma_2, pk['g_tilde']):
406
+ return True
407
+ return False
408
+
409
+
410
+ class PS_SigSingleMessage(PS_Sig):
411
+
412
+ def __init__(self, groupObj):
413
+ PS_Sig.__init__(self, groupObj)
414
+
415
+ def keygen(self):
416
+ """
417
+ This function is used to generate the secret key and the public key of the signer
418
+ """
419
+ g_tilde = self.group.random(G2)
420
+ x = self.group.random()
421
+ y = self.group.random()
422
+ X_tilde = g_tilde ** x
423
+ Y_tilde = g_tilde ** y
424
+
425
+ pk = {'g_tilde': g_tilde, 'X_tilde': X_tilde, 'Y_tilde': Y_tilde}
426
+ sk = {'x': x, 'y': y}
427
+
428
+ return sk, pk
429
+
430
+ def sign(self, sk, message):
431
+ """
432
+ This function is used for the signer to sign a message
433
+ Inputs:
434
+ - sk: Secret key of the signer
435
+ - message: message to be signed
436
+ Outputs:
437
+ - sigma: Signature on the message
438
+ """
439
+ m = self._dump_to_zp_element(message) # serialize the message to an element
440
+ h = self.group.random(G1)
441
+ sigma = (h, h ** (sk['x'] + sk['y'] * m))
442
+
443
+ return sigma
444
+
445
+ def verify(self, message, pk, sig) -> bool:
446
+ """
447
+ This function is used for the user to verify a signature on a specific message using the message and the public
448
+ key of the signer.
449
+ Inputs:
450
+ - message: The message
451
+ - pk: Public key
452
+ - sig: signature
453
+ Outputs:
454
+ - True if the signature is valid on the message by the user whose public key is pk
455
+ - False, otherwise
456
+ """
457
+ sigma_1, sigma_2 = sig
458
+ m = self._dump_to_zp_element(message) # serialize the message to an element
459
+ if pair(sigma_1, pk['X_tilde'] * (pk['Y_tilde'] ** m)) == pair(sigma_2, pk['g_tilde']):
460
+ return True
461
+ return False
462
+
463
+
464
+ class PS_SigMultiMessage(PS_Sig):
465
+
466
+ def __init__(self, groupObj):
467
+ PS_Sig.__init__(self, groupObj)
468
+
469
+ def keygen(self, num_messages):
470
+ """
471
+ This function is used to generate the secret key and the public key of the signer
472
+ Inputs:
473
+ - num_message: Number of messages
474
+ """
475
+ g_tilde = self.group.random(G2)
476
+ x = self.group.random()
477
+ ys = [self.group.random() for i in range(num_messages)]
478
+ X_tilde = g_tilde ** x
479
+ Ys_tilde = [g_tilde ** y for y in ys]
480
+
481
+ pk = {'g_tilde': g_tilde, 'X_tilde': X_tilde, 'Ys_tilde': Ys_tilde}
482
+ sk = {'x': x, 'ys': ys}
483
+
484
+ return sk, pk
485
+
486
+ def sign(self, sk, messages):
487
+ """
488
+ This function is used for the signer to sign a message
489
+ Inputs:
490
+ - sk: Secret key of the signer
491
+ - messages: List of messages to be signed
492
+ Outputs:
493
+ - sigma: Signature on the message
494
+ """
495
+ ms = [self._dump_to_zp_element(message) for message in messages]
496
+ h = self.group.random(G1)
497
+ Y_multiply_m_sum = sk['ys'][0] * ms[0]
498
+ for i in range(1, len(ms)):
499
+ Y_multiply_m_sum += sk['ys'][i] * ms[i]
500
+ sigma = (h, h ** (sk['x'] + Y_multiply_m_sum))
501
+
502
+ return sigma
503
+
504
+ def verify(self, messages, pk, sig) -> bool:
505
+ """
506
+ This function is used for the user to verify a signature on a specific message using the message and the public
507
+ key of the signer.
508
+ Inputs:
509
+ - messages: The list of messages
510
+ - pk: Public key
511
+ - sig: signature
512
+ Outputs:
513
+ - True if the signature is valid on the message by the user whose public key is pk
514
+ - False, otherwise
515
+ """
516
+ sigma_1, sigma_2 = sig
517
+ ms = [self._dump_to_zp_element(message) for message in messages]
518
+ Y_tilde_pow_m_product = pk['Ys_tilde'][0] ** ms[0]
519
+ for i in range(1, len(ms)):
520
+ Y_tilde_pow_m_product *= pk['Ys_tilde'][i] ** ms[i]
521
+ if pair(sigma_1, pk['X_tilde'] * Y_tilde_pow_m_product) == pair(sigma_2, pk['g_tilde']):
522
+ return True
523
+ return False
524
+
525
+
526
+ def single_message_main(debug=False):
527
+ print("************************************** Single Message Main ************************************************")
528
+ message = "Welcome to PS signature scheme"
529
+ group_obj = PairingGroup('MNT224')
530
+ ps_sig = PS_SigSingleMessage(group_obj)
531
+
532
+ sk, pk = ps_sig.keygen()
533
+ if debug:
534
+ print("sk = ", sk)
535
+ print("pk = ", pk)
536
+
537
+ sigma = ps_sig.sign(sk, message)
538
+ if debug:
539
+ print("signature: ", sigma)
540
+ verification_res = ps_sig.verify(message, pk, sigma)
541
+ if verification_res:
542
+ print("Verification is successful")
543
+ else:
544
+ print("Error! This signature is not valid on this message")
545
+ print("***********************************************************************************************************")
546
+
547
+
548
+ def multi_message_main(debug=False):
549
+ print("**************************************** Multi Messages Main **********************************************")
550
+ messages = ["Welcome to PS signature scheme", "PS can be used in many applications", "Most importantly, it can generate anonymous signatures"]
551
+ group_obj = PairingGroup('MNT224')
552
+ ps_sig = PS_SigMultiMessage(group_obj)
553
+
554
+ sk, pk = ps_sig.keygen(len(messages))
555
+ if debug:
556
+ print("sk = ", sk)
557
+ print("pk = ", pk)
558
+
559
+ sigma = ps_sig.sign(sk, messages)
560
+ if debug:
561
+ print("signature: ", sigma)
562
+ verification_res = ps_sig.verify(messages, pk, sigma)
563
+ if verification_res:
564
+ print("Verification is successful")
565
+ else:
566
+ print("Error! This signature is not valid on this message")
567
+ print("***********************************************************************************************************")
568
+
569
+
570
+ def blinded_single_message_main(debug=False):
571
+ print("******************************** Blinded Single Message Main **********************************************")
572
+ message = "Welcome to PS signature scheme"
573
+ group_obj = PairingGroup('MNT224')
574
+ ps_sig = PS_BlindSingleMessageSig(group_obj)
575
+
576
+ sk, pk = ps_sig.keygen()
577
+ if debug:
578
+ print("sk = ", sk)
579
+ print("pk = ", pk)
580
+
581
+ blinded_message, t = ps_sig.blind(message, pk)
582
+ if debug:
583
+ print("Blinded Message: ", blinded_message)
584
+
585
+ # Interactive ZKP
586
+ # user proves knowledge of the secret message to the signer to accept to sign the blinded message
587
+ prover_knowledge_of_secret_message_status = ps_sig.proof_of_knowledge_of_commitment_secrets(t, [message], blinded_message, pk, group_obj, debug)
588
+ print("Verifier validation of the proof status: ", prover_knowledge_of_secret_message_status)
589
+
590
+ if prover_knowledge_of_secret_message_status:
591
+ blinded_signature = ps_sig.sign(sk, pk, blinded_message)
592
+ if debug:
593
+ print("Blinded signature: ", blinded_signature)
594
+
595
+ signature = ps_sig.unblind(blinded_signature, t)
596
+ if debug:
597
+ print("Signature: ", signature)
598
+ verification_res = ps_sig.verify(message, pk, signature)
599
+ if verification_res:
600
+ print("Verification is successful")
601
+ else:
602
+ print("Error! This signature is not valid on this message")
603
+ else:
604
+ print("Error! Proof of knowledge verification error")
605
+ print("***********************************************************************************************************")
606
+
607
+
608
+ def blinded_multi_message_main(debug=False):
609
+ print("******************************** Blinded Multi Message Main ***********************************************")
610
+ messages = ["Welcome to PS signature scheme", "PS can be used in many applications", "Most importantly, it can generate anonymous signatures"]
611
+ group_obj = PairingGroup('MNT224')
612
+ ps_sig = PS_BlindMultiMessageSig(group_obj)
613
+
614
+ sk, pk = ps_sig.keygen(len(messages))
615
+ if debug:
616
+ print("sk = ", sk)
617
+ print("pk = ", pk)
618
+
619
+ blinded_message, t = ps_sig.blind(messages, pk)
620
+ if debug:
621
+ print("Blinded Message: ", blinded_message)
622
+ # Interactive ZKP
623
+ # user proves knowledge of the secret message to the signer to accept to sign the blinded message
624
+ prover_knowledge_of_secret_messages_status = ps_sig.proof_of_knowledge_of_commitment_secrets(t, messages,
625
+ blinded_message, pk,
626
+ group_obj, debug)
627
+ print("Verifier validation of the proof status: ", prover_knowledge_of_secret_messages_status)
628
+
629
+ if prover_knowledge_of_secret_messages_status:
630
+ blinded_signature = ps_sig.sign(sk, pk, blinded_message)
631
+ if debug:
632
+ print("Blinded signature: ", blinded_signature)
633
+
634
+ signature = ps_sig.unblind(blinded_signature, t)
635
+ if debug:
636
+ print("Signature: ", signature)
637
+
638
+ verification_res = ps_sig.verify(messages, pk, signature)
639
+ if verification_res:
640
+ print("Verification is successful")
641
+ else:
642
+ print("Error! This signature is not valid on this message")
643
+ else:
644
+ print("Error! Proof of knowledge verification error")
645
+ print("***********************************************************************************************************")
646
+
647
+
648
+ if __name__ == "__main__":
649
+ debug = True
650
+ single_message_main(debug)
651
+ multi_message_main(debug)
652
+ blinded_single_message_main(debug)
653
+ blinded_multi_message_main(debug)
654
+ print("done")