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,267 @@
1
+ '''
2
+ **BLS Multi-Signatures (BLS)**
3
+
4
+ *Authors:* Dan Boneh, Manu Drijvers, Gregory Neven
5
+
6
+ | **Title:** "BLS Multi-Signatures With Public-Key Aggregation"
7
+ | **Available from:** https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html
8
+ | **Notes:** Includes both vulnerable and rogue-public-key-resistant aggregation methods
9
+
10
+ .. rubric:: Scheme Properties
11
+
12
+ * **Type:** aggregate signature
13
+ * **Setting:** bilinear groups (asymmetric)
14
+ * **Assumption:** CDH in G1
15
+
16
+ .. rubric:: Implementation
17
+
18
+ :Authors: Lovesh Harchandani
19
+ :Date: 5/2018
20
+ '''
21
+
22
+ from functools import reduce
23
+
24
+ from charm.toolbox.pairinggroup import PairingGroup, ZR, G1, G2, pair
25
+ from charm.core.engine.util import objectToBytes
26
+
27
+ debug = False
28
+
29
+
30
+ class BLSAggregation:
31
+ def __init__(self, groupObj):
32
+ global group
33
+ group = groupObj
34
+
35
+ def keygen(self, g, secparam=None):
36
+ x = group.random()
37
+ g_x = g ** x
38
+ pk = {'g^x': g_x, 'g': g, 'identity': str(g_x), 'secparam': secparam}
39
+ sk = {'x': x}
40
+ return pk, sk
41
+
42
+ def sign(self, x, message):
43
+ M = self.dump(message)
44
+ if debug:
45
+ print("Message => '%s'" % M)
46
+ return group.hash(M, G1) ** x
47
+
48
+ def verify(self, pk, sig, message):
49
+ M = self.dump(message)
50
+ h = group.hash(M, G1)
51
+ return pair(pk['g'], sig) == pair(h, pk['g^x'])
52
+
53
+ def aggregate_sigs_vulnerable(self, signatures):
54
+ """
55
+ This method of aggregation is vulnerable to rogue public key attack
56
+ """
57
+ return self.product(signatures)
58
+
59
+ def verify_aggregate_sig_vulnerable(self, message, aggregate_sig, public_keys):
60
+ # This method of verification is vulnerable to rogue public key attack
61
+ g = self.check_and_return_same_generator_in_public_keys(public_keys)
62
+ M = self.dump(message)
63
+ h = group.hash(M, G1)
64
+ combined_pk = self.product([pk['g^x'] for pk in public_keys])
65
+ return pair(g, aggregate_sig) == pair(combined_pk, h)
66
+
67
+ def aggregate_sigs_safe(self, pubkey_signatures):
68
+ # This method of aggregation is resistant to rogue public key attack
69
+ sigs = []
70
+ all_pubkeys = [i[0] for i in pubkey_signatures]
71
+ for pk, sig in pubkey_signatures:
72
+ e = sig ** self.hash_keys(pk, all_pubkeys)
73
+ sigs.append(e)
74
+
75
+ return self.product(sigs)
76
+
77
+ def verify_aggregate_sig_safe(self, message, aggregate_sig, public_keys):
78
+ # This method of verification is resistant to rogue public key attack
79
+ g = self.check_and_return_same_generator_in_public_keys(public_keys)
80
+ aggregated_pk = self.aggregate_pub_key(public_keys)
81
+ M = self.dump(message)
82
+ h = group.hash(M, G1)
83
+ return pair(g, aggregate_sig) == pair(aggregated_pk, h)
84
+
85
+ @staticmethod
86
+ def product(seq):
87
+ return reduce(lambda x, y: x * y, seq)
88
+
89
+ @staticmethod
90
+ def dump(obj):
91
+ return objectToBytes(obj, group)
92
+
93
+ @staticmethod
94
+ def check_and_return_same_generator_in_public_keys(public_keys):
95
+ gs = {pk['g'] for pk in public_keys}
96
+ assert len(gs) == 1, 'All public keys should have same generator'
97
+ return next(iter(gs))
98
+
99
+ @staticmethod
100
+ def hash_keys(pk, all_pks):
101
+ acc = BLSAggregation.dump(pk['g^x'])
102
+ for p in all_pks:
103
+ acc += BLSAggregation.dump(p['g^x'])
104
+ return group.hash(acc, ZR)
105
+
106
+ @staticmethod
107
+ def aggregate_pub_key(pks):
108
+ r = []
109
+ for pk in pks:
110
+ h = BLSAggregation.hash_keys(pk, pks)
111
+ r.append(pk['g^x'] ** h)
112
+ return BLSAggregation.product(r)
113
+
114
+
115
+ def vulnerable():
116
+ groupObj = PairingGroup('MNT224')
117
+
118
+ m = {'a': "hello world!!!", 'b': "test message"}
119
+ bls = BLSAggregation(groupObj)
120
+ g = group.random(G2)
121
+
122
+ pk1, sk1 = bls.keygen(g)
123
+ pk2, sk2 = bls.keygen(g)
124
+ pk3, sk3 = bls.keygen(g)
125
+
126
+ sig1 = bls.sign(sk1['x'], m)
127
+ sig2 = bls.sign(sk2['x'], m)
128
+ sig3 = bls.sign(sk3['x'], m)
129
+
130
+ if debug:
131
+ print("Message: '%s'" % m)
132
+ print("Signature1: '%s'" % sig1)
133
+ print("Signature2: '%s'" % sig2)
134
+ print("Signature3: '%s'" % sig3)
135
+
136
+ assert bls.verify(pk1, sig1, m), 'Failure!!!'
137
+ assert bls.verify(pk2, sig2, m), 'Failure!!!'
138
+ assert bls.verify(pk3, sig3, m), 'Failure!!!'
139
+
140
+ if debug:
141
+ print('VERIFICATION SUCCESS!!!')
142
+
143
+ aggregate_sig = bls.aggregate_sigs_vulnerable([sig1, sig2, sig3])
144
+ if debug:
145
+ print("Aggregate signature: '%s'" % aggregate_sig)
146
+
147
+ assert bls.verify_aggregate_sig_vulnerable(m, aggregate_sig, [pk1, pk2, pk3]), \
148
+ 'Failure!!!'
149
+
150
+ if debug:
151
+ print('AGGREGATION VERIFICATION SUCCESS!!!')
152
+
153
+ assert not bls.verify_aggregate_sig_vulnerable(m, aggregate_sig, [pk1, pk2])
154
+
155
+ if debug:
156
+ print('AGGREGATION VERIFICATION SUCCESS AGAIN!!!')
157
+
158
+
159
+ def demo_rogue_public_key_attack():
160
+ # Attack mentioned here https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html
161
+ groupObj = PairingGroup('MNT224')
162
+
163
+ m = {'a': "hello world!!!", 'b': "test message"}
164
+ bls = BLSAggregation(groupObj)
165
+ g = group.random(G2)
166
+
167
+ pk0, sk0 = bls.keygen(g)
168
+ pk1, sk1 = bls.keygen(g)
169
+
170
+ # Construct the attacker's public key (pk2) as `g^beta * (pk1*pk2)^-1`,
171
+ # i.e inverse of the product of all public keys that the attacker wants
172
+ # to forge the multi-sig over
173
+ pk_inverse = 1 / (BLSAggregation.product([pk0['g^x'], pk1['g^x']]))
174
+ beta = group.random()
175
+ pk2, _ = bls.keygen(g)
176
+ pk2['g^x'] = (g ** beta) * pk_inverse
177
+
178
+ M = BLSAggregation.dump(m)
179
+ h = group.hash(M, G1)
180
+ fake_aggregate_sig = h ** beta
181
+ assert bls.verify_aggregate_sig_vulnerable(m, fake_aggregate_sig, [pk0, pk1, pk2]), \
182
+ 'Failure!!!'
183
+
184
+ if debug:
185
+ print('ROGUE PUBLIC KEY ATTACK SUCCESS!!!')
186
+
187
+
188
+ def safe():
189
+ groupObj = PairingGroup('MNT224')
190
+
191
+ m = {'a': "hello world!!!", 'b': "test message"}
192
+ bls = BLSAggregation(groupObj)
193
+ g = group.random(G2)
194
+
195
+ pk1, sk1 = bls.keygen(g)
196
+ pk2, sk2 = bls.keygen(g)
197
+ pk3, sk3 = bls.keygen(g)
198
+
199
+ sig1 = bls.sign(sk1['x'], m)
200
+ sig2 = bls.sign(sk2['x'], m)
201
+ sig3 = bls.sign(sk3['x'], m)
202
+
203
+ if debug:
204
+ print("Message: '%s'" % m)
205
+ print("Signature1: '%s'" % sig1)
206
+ print("Signature2: '%s'" % sig2)
207
+ print("Signature3: '%s'" % sig3)
208
+
209
+ assert bls.verify(pk1, sig1, m), 'Failure!!!'
210
+ assert bls.verify(pk2, sig2, m), 'Failure!!!'
211
+ assert bls.verify(pk3, sig3, m), 'Failure!!!'
212
+
213
+ if debug:
214
+ print('VERIFICATION SUCCESS!!!')
215
+
216
+ aggregate_sig = bls.aggregate_sigs_safe([(pk1, sig1), (pk2, sig2),
217
+ (pk3, sig3)])
218
+ if debug:
219
+ print("Aggregate signature: '%s'" % aggregate_sig)
220
+
221
+ assert bls.verify_aggregate_sig_safe(m, aggregate_sig, [pk1, pk2, pk3]), \
222
+ 'Failure!!!'
223
+
224
+ if debug:
225
+ print('NEW AGGREGATION VERIFICATION SUCCESS!!!')
226
+
227
+ assert not bls.verify_aggregate_sig_safe(m, aggregate_sig, [pk1, pk2])
228
+
229
+ if debug:
230
+ print('NEW AGGREGATION VERIFICATION SUCCESS AGAIN!!!')
231
+
232
+
233
+ def defend_rogue_public_key_attack():
234
+ # Defence mentioned here https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html
235
+ groupObj = PairingGroup('MNT224')
236
+
237
+ m = {'a': "hello world!!!", 'b': "test message"}
238
+ bls = BLSAggregation(groupObj)
239
+ g = group.random(G2)
240
+
241
+ pk0, sk0 = bls.keygen(g)
242
+ pk1, sk1 = bls.keygen(g)
243
+
244
+ # Construct the attacker's public key (pk2) as `g^beta * (pk1*pk2)^-1`,
245
+ # i.e inverse of the product of all public keys that the attacker wants
246
+ # to forge the multi-sig over
247
+ pk_inverse = 1 / (BLSAggregation.product([pk0['g^x'], pk1['g^x']]))
248
+ beta = group.random()
249
+ pk2, _ = bls.keygen(g)
250
+ pk2['g^x'] = (g ** beta) * pk_inverse
251
+
252
+ M = BLSAggregation.dump(m)
253
+ h = group.hash(M, G1)
254
+ fake_aggregate_sig = h ** beta
255
+ assert not bls.verify_aggregate_sig_safe(m, fake_aggregate_sig, [pk0, pk1, pk2]), \
256
+ 'Failure!!!'
257
+
258
+ if debug:
259
+ print('ROGUE PUBLIC KEY ATTACK DEFENDED!!!')
260
+
261
+
262
+ if __name__ == "__main__":
263
+ debug = True
264
+ vulnerable()
265
+ demo_rogue_public_key_attack()
266
+ safe()
267
+ defend_rogue_public_key_attack()