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.
- charm/__init__.py +5 -0
- charm/adapters/__init__.py +0 -0
- charm/adapters/abenc_adapt_hybrid.py +90 -0
- charm/adapters/dabenc_adapt_hybrid.py +145 -0
- charm/adapters/ibenc_adapt_hybrid.py +72 -0
- charm/adapters/ibenc_adapt_identityhash.py +80 -0
- charm/adapters/kpabenc_adapt_hybrid.py +91 -0
- charm/adapters/pkenc_adapt_bchk05.py +121 -0
- charm/adapters/pkenc_adapt_chk04.py +91 -0
- charm/adapters/pkenc_adapt_hybrid.py +98 -0
- charm/adapters/pksig_adapt_naor01.py +89 -0
- charm/config.py +7 -0
- charm/core/__init__.py +0 -0
- charm/core/benchmark/benchmark_util.c +353 -0
- charm/core/benchmark/benchmark_util.h +61 -0
- charm/core/benchmark/benchmarkmodule.c +476 -0
- charm/core/benchmark/benchmarkmodule.h +162 -0
- charm/core/benchmark.cpython-313-darwin.so +0 -0
- charm/core/crypto/AES/AES.c +1464 -0
- charm/core/crypto/AES.cpython-313-darwin.so +0 -0
- charm/core/crypto/DES/DES.c +113 -0
- charm/core/crypto/DES.cpython-313-darwin.so +0 -0
- charm/core/crypto/DES3/DES3.c +26 -0
- charm/core/crypto/DES3.cpython-313-darwin.so +0 -0
- charm/core/crypto/__init__.py +0 -0
- charm/core/crypto/cryptobase/XOR.c +80 -0
- charm/core/crypto/cryptobase/_counter.c +496 -0
- charm/core/crypto/cryptobase/_counter.h +54 -0
- charm/core/crypto/cryptobase/block_template.c +900 -0
- charm/core/crypto/cryptobase/block_template.h +69 -0
- charm/core/crypto/cryptobase/cryptobasemodule.c +220 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt.h +90 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_argchk.h +44 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_cfg.h +186 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_cipher.h +941 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_custom.h +556 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_des.c +1912 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_hash.h +407 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_mac.h +496 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_macros.h +435 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_math.h +534 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_misc.h +103 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_pk.h +653 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_pkcs.h +90 -0
- charm/core/crypto/cryptobase/libtom/tomcrypt_prng.h +199 -0
- charm/core/crypto/cryptobase/stream_template.c +271 -0
- charm/core/crypto/cryptobase/strxor.c +229 -0
- charm/core/crypto/cryptobase.cpython-313-darwin.so +0 -0
- charm/core/engine/__init__.py +5 -0
- charm/core/engine/protocol.py +293 -0
- charm/core/engine/util.py +174 -0
- charm/core/math/__init__.py +0 -0
- charm/core/math/elliptic_curve/ecmodule.c +1986 -0
- charm/core/math/elliptic_curve/ecmodule.h +230 -0
- charm/core/math/elliptic_curve.cpython-313-darwin.so +0 -0
- charm/core/math/elliptic_curve.pyi +63 -0
- charm/core/math/integer/integermodule.c +2539 -0
- charm/core/math/integer/integermodule.h +145 -0
- charm/core/math/integer.cpython-313-darwin.so +0 -0
- charm/core/math/integer.pyi +76 -0
- charm/core/math/pairing/miracl/miracl_config.h +37 -0
- charm/core/math/pairing/miracl/miracl_interface.h +118 -0
- charm/core/math/pairing/miracl/miracl_interface2.h +126 -0
- charm/core/math/pairing/miracl/pairingmodule2.c +2094 -0
- charm/core/math/pairing/miracl/pairingmodule2.h +307 -0
- charm/core/math/pairing/pairingmodule.c +2230 -0
- charm/core/math/pairing/pairingmodule.h +241 -0
- charm/core/math/pairing/relic/pairingmodule3.c +1853 -0
- charm/core/math/pairing/relic/pairingmodule3.h +233 -0
- charm/core/math/pairing/relic/relic_interface.c +1337 -0
- charm/core/math/pairing/relic/relic_interface.h +217 -0
- charm/core/math/pairing/relic/test_relic.c +171 -0
- charm/core/math/pairing.cpython-313-darwin.so +0 -0
- charm/core/math/pairing.pyi +69 -0
- charm/core/utilities/base64.c +248 -0
- charm/core/utilities/base64.h +15 -0
- charm/schemes/__init__.py +0 -0
- charm/schemes/abenc/__init__.py +0 -0
- charm/schemes/abenc/abenc_accountability_jyjxgd20.py +647 -0
- charm/schemes/abenc/abenc_bsw07.py +146 -0
- charm/schemes/abenc/abenc_ca_cpabe_ar17.py +684 -0
- charm/schemes/abenc/abenc_dacmacs_yj14.py +298 -0
- charm/schemes/abenc/abenc_lsw08.py +159 -0
- charm/schemes/abenc/abenc_maabe_rw15.py +236 -0
- charm/schemes/abenc/abenc_maabe_yj14.py +297 -0
- charm/schemes/abenc/abenc_tbpre_lww14.py +309 -0
- charm/schemes/abenc/abenc_unmcpabe_yahk14.py +223 -0
- charm/schemes/abenc/abenc_waters09.py +144 -0
- charm/schemes/abenc/abenc_yct14.py +208 -0
- charm/schemes/abenc/abenc_yllc15.py +178 -0
- charm/schemes/abenc/ac17.py +248 -0
- charm/schemes/abenc/bsw07.py +141 -0
- charm/schemes/abenc/cgw15.py +277 -0
- charm/schemes/abenc/dabe_aw11.py +204 -0
- charm/schemes/abenc/dfa_fe12.py +144 -0
- charm/schemes/abenc/pk_hve08.py +179 -0
- charm/schemes/abenc/waters11.py +143 -0
- charm/schemes/aggrsign_MuSig.py +150 -0
- charm/schemes/aggrsign_bls.py +267 -0
- charm/schemes/blindsig_ps16.py +654 -0
- charm/schemes/chamhash_adm05.py +113 -0
- charm/schemes/chamhash_rsa_hw09.py +100 -0
- charm/schemes/commit/__init__.py +0 -0
- charm/schemes/commit/commit_gs08.py +77 -0
- charm/schemes/commit/commit_pedersen92.py +53 -0
- charm/schemes/encap_bchk05.py +62 -0
- charm/schemes/grpsig/__init__.py +0 -0
- charm/schemes/grpsig/groupsig_bgls04.py +114 -0
- charm/schemes/grpsig/groupsig_bgls04_var.py +115 -0
- charm/schemes/hibenc/__init__.py +0 -0
- charm/schemes/hibenc/hibenc_bb04.py +105 -0
- charm/schemes/hibenc/hibenc_lew11.py +193 -0
- charm/schemes/ibenc/__init__.py +0 -0
- charm/schemes/ibenc/clpkc_rp03.py +119 -0
- charm/schemes/ibenc/ibenc_CW13_z.py +168 -0
- charm/schemes/ibenc/ibenc_bb03.py +94 -0
- charm/schemes/ibenc/ibenc_bf01.py +121 -0
- charm/schemes/ibenc/ibenc_ckrs09.py +120 -0
- charm/schemes/ibenc/ibenc_cllww12_z.py +172 -0
- charm/schemes/ibenc/ibenc_lsw08.py +120 -0
- charm/schemes/ibenc/ibenc_sw05.py +238 -0
- charm/schemes/ibenc/ibenc_waters05.py +144 -0
- charm/schemes/ibenc/ibenc_waters05_z.py +164 -0
- charm/schemes/ibenc/ibenc_waters09.py +107 -0
- charm/schemes/ibenc/ibenc_waters09_z.py +147 -0
- charm/schemes/joye_scheme.py +106 -0
- charm/schemes/lem_scheme.py +207 -0
- charm/schemes/pk_fre_ccv11.py +107 -0
- charm/schemes/pk_vrf.py +127 -0
- charm/schemes/pkenc/__init__.py +0 -0
- charm/schemes/pkenc/pkenc_cs98.py +108 -0
- charm/schemes/pkenc/pkenc_elgamal85.py +122 -0
- charm/schemes/pkenc/pkenc_gm82.py +98 -0
- charm/schemes/pkenc/pkenc_paillier99.py +118 -0
- charm/schemes/pkenc/pkenc_rabin.py +254 -0
- charm/schemes/pkenc/pkenc_rsa.py +186 -0
- charm/schemes/pksig/__init__.py +0 -0
- charm/schemes/pksig/pksig_CW13_z.py +135 -0
- charm/schemes/pksig/pksig_bls04.py +87 -0
- charm/schemes/pksig/pksig_boyen.py +156 -0
- charm/schemes/pksig/pksig_chch.py +97 -0
- charm/schemes/pksig/pksig_chp.py +70 -0
- charm/schemes/pksig/pksig_cl03.py +150 -0
- charm/schemes/pksig/pksig_cl04.py +87 -0
- charm/schemes/pksig/pksig_cllww12_z.py +142 -0
- charm/schemes/pksig/pksig_cyh.py +132 -0
- charm/schemes/pksig/pksig_dsa.py +76 -0
- charm/schemes/pksig/pksig_ecdsa.py +71 -0
- charm/schemes/pksig/pksig_hess.py +104 -0
- charm/schemes/pksig/pksig_hw.py +110 -0
- charm/schemes/pksig/pksig_lamport.py +63 -0
- charm/schemes/pksig/pksig_ps01.py +135 -0
- charm/schemes/pksig/pksig_ps02.py +124 -0
- charm/schemes/pksig/pksig_ps03.py +119 -0
- charm/schemes/pksig/pksig_rsa_hw09.py +206 -0
- charm/schemes/pksig/pksig_schnorr91.py +77 -0
- charm/schemes/pksig/pksig_waters.py +115 -0
- charm/schemes/pksig/pksig_waters05.py +121 -0
- charm/schemes/pksig/pksig_waters09.py +121 -0
- charm/schemes/pre_mg07.py +150 -0
- charm/schemes/prenc/pre_afgh06.py +126 -0
- charm/schemes/prenc/pre_bbs98.py +123 -0
- charm/schemes/prenc/pre_nal16.py +216 -0
- charm/schemes/protocol_a01.py +272 -0
- charm/schemes/protocol_ao00.py +215 -0
- charm/schemes/protocol_cns07.py +274 -0
- charm/schemes/protocol_schnorr91.py +125 -0
- charm/schemes/sigma1.py +64 -0
- charm/schemes/sigma2.py +129 -0
- charm/schemes/sigma3.py +126 -0
- charm/schemes/threshold/__init__.py +59 -0
- charm/schemes/threshold/dkls23_dkg.py +556 -0
- charm/schemes/threshold/dkls23_presign.py +1089 -0
- charm/schemes/threshold/dkls23_sign.py +761 -0
- charm/schemes/threshold/xrpl_wallet.py +967 -0
- charm/test/__init__.py +0 -0
- charm/test/adapters/__init__.py +0 -0
- charm/test/adapters/abenc_adapt_hybrid_test.py +29 -0
- charm/test/adapters/dabenc_adapt_hybrid_test.py +56 -0
- charm/test/adapters/ibenc_adapt_hybrid_test.py +36 -0
- charm/test/adapters/ibenc_adapt_identityhash_test.py +32 -0
- charm/test/adapters/kpabenc_adapt_hybrid_test.py +30 -0
- charm/test/benchmark/abenc_yllc15_bench.py +92 -0
- charm/test/benchmark/benchmark_test.py +148 -0
- charm/test/benchmark_threshold.py +260 -0
- charm/test/conftest.py +38 -0
- charm/test/fuzz/__init__.py +1 -0
- charm/test/fuzz/conftest.py +5 -0
- charm/test/fuzz/fuzz_policy_parser.py +76 -0
- charm/test/fuzz/fuzz_serialization.py +83 -0
- charm/test/schemes/__init__.py +0 -0
- charm/test/schemes/abenc/__init__.py +0 -0
- charm/test/schemes/abenc/abenc_bsw07_test.py +39 -0
- charm/test/schemes/abenc/abenc_dacmacs_yj14_test.py +16 -0
- charm/test/schemes/abenc/abenc_lsw08_test.py +33 -0
- charm/test/schemes/abenc/abenc_maabe_yj14_test.py +16 -0
- charm/test/schemes/abenc/abenc_tbpre_lww14_test.py +16 -0
- charm/test/schemes/abenc/abenc_waters09_test.py +38 -0
- charm/test/schemes/abenc/abenc_yllc15_test.py +74 -0
- charm/test/schemes/chamhash_adm05_test.py +31 -0
- charm/test/schemes/chamhash_rsa_hw09_test.py +29 -0
- charm/test/schemes/commit/__init__.py +0 -0
- charm/test/schemes/commit/commit_gs08_test.py +24 -0
- charm/test/schemes/commit/commit_pedersen92_test.py +26 -0
- charm/test/schemes/dabe_aw11_test.py +45 -0
- charm/test/schemes/encap_bchk05_test.py +21 -0
- charm/test/schemes/grpsig/__init__.py +0 -0
- charm/test/schemes/grpsig/groupsig_bgls04_test.py +35 -0
- charm/test/schemes/grpsig/groupsig_bgls04_var_test.py +39 -0
- charm/test/schemes/hibenc/__init__.py +0 -0
- charm/test/schemes/hibenc/hibenc_bb04_test.py +28 -0
- charm/test/schemes/ibenc/__init__.py +0 -0
- charm/test/schemes/ibenc/ibenc_bb03_test.py +26 -0
- charm/test/schemes/ibenc/ibenc_bf01_test.py +24 -0
- charm/test/schemes/ibenc/ibenc_ckrs09_test.py +25 -0
- charm/test/schemes/ibenc/ibenc_lsw08_test.py +31 -0
- charm/test/schemes/ibenc/ibenc_sw05_test.py +32 -0
- charm/test/schemes/ibenc/ibenc_waters05_test.py +31 -0
- charm/test/schemes/ibenc/ibenc_waters09_test.py +27 -0
- charm/test/schemes/pk_vrf_test.py +29 -0
- charm/test/schemes/pkenc/__init__.py +0 -0
- charm/test/schemes/pkenc_test.py +255 -0
- charm/test/schemes/pksig/__init__.py +0 -0
- charm/test/schemes/pksig_test.py +376 -0
- charm/test/schemes/rsa_alg_test.py +340 -0
- charm/test/schemes/threshold_test.py +1792 -0
- charm/test/serialize/__init__.py +0 -0
- charm/test/serialize/serialize_test.py +40 -0
- charm/test/toolbox/__init__.py +0 -0
- charm/test/toolbox/conversion_test.py +30 -0
- charm/test/toolbox/ecgroup_test.py +53 -0
- charm/test/toolbox/integer_arithmetic_test.py +441 -0
- charm/test/toolbox/paddingschemes_test.py +238 -0
- charm/test/toolbox/policy_parser_stress_test.py +969 -0
- charm/test/toolbox/secretshare_test.py +28 -0
- charm/test/toolbox/symcrypto_test.py +108 -0
- charm/test/toolbox/test_policy_expression.py +16 -0
- charm/test/vectors/__init__.py +1 -0
- charm/test/vectors/test_bls_vectors.py +289 -0
- charm/test/vectors/test_pedersen_vectors.py +315 -0
- charm/test/vectors/test_schnorr_vectors.py +368 -0
- charm/test/zkp_compiler/__init__.py +9 -0
- charm/test/zkp_compiler/benchmark_zkp.py +258 -0
- charm/test/zkp_compiler/test_and_proof.py +240 -0
- charm/test/zkp_compiler/test_batch_verify.py +248 -0
- charm/test/zkp_compiler/test_dleq_proof.py +264 -0
- charm/test/zkp_compiler/test_or_proof.py +231 -0
- charm/test/zkp_compiler/test_proof_serialization.py +121 -0
- charm/test/zkp_compiler/test_range_proof.py +241 -0
- charm/test/zkp_compiler/test_representation_proof.py +325 -0
- charm/test/zkp_compiler/test_schnorr_proof.py +221 -0
- charm/test/zkp_compiler/test_thread_safety.py +169 -0
- charm/test/zkp_compiler/test_zkp_parser.py +139 -0
- charm/toolbox/ABEnc.py +26 -0
- charm/toolbox/ABEncMultiAuth.py +66 -0
- charm/toolbox/ABEnumeric.py +800 -0
- charm/toolbox/Commit.py +24 -0
- charm/toolbox/DFA.py +89 -0
- charm/toolbox/FSA.py +1254 -0
- charm/toolbox/Hash.py +39 -0
- charm/toolbox/IBEnc.py +62 -0
- charm/toolbox/IBSig.py +64 -0
- charm/toolbox/PKEnc.py +66 -0
- charm/toolbox/PKSig.py +56 -0
- charm/toolbox/PREnc.py +32 -0
- charm/toolbox/ZKProof.py +289 -0
- charm/toolbox/__init__.py +0 -0
- charm/toolbox/bitstring.py +49 -0
- charm/toolbox/broadcast.py +220 -0
- charm/toolbox/conversion.py +100 -0
- charm/toolbox/eccurve.py +149 -0
- charm/toolbox/ecgroup.py +143 -0
- charm/toolbox/enum.py +60 -0
- charm/toolbox/hash_module.py +91 -0
- charm/toolbox/integergroup.py +323 -0
- charm/toolbox/iterate.py +22 -0
- charm/toolbox/matrixops.py +76 -0
- charm/toolbox/mpc_utils.py +296 -0
- charm/toolbox/msp.py +175 -0
- charm/toolbox/mta.py +985 -0
- charm/toolbox/node.py +120 -0
- charm/toolbox/ot/__init__.py +22 -0
- charm/toolbox/ot/base_ot.py +374 -0
- charm/toolbox/ot/dpf.py +642 -0
- charm/toolbox/ot/mpfss.py +228 -0
- charm/toolbox/ot/ot_extension.py +589 -0
- charm/toolbox/ot/silent_ot.py +378 -0
- charm/toolbox/paddingschemes.py +423 -0
- charm/toolbox/paddingschemes_test.py +238 -0
- charm/toolbox/pairingcurves.py +85 -0
- charm/toolbox/pairinggroup.py +186 -0
- charm/toolbox/policy_expression_spec.py +70 -0
- charm/toolbox/policytree.py +189 -0
- charm/toolbox/reCompiler.py +346 -0
- charm/toolbox/redundancyschemes.py +65 -0
- charm/toolbox/schemebase.py +188 -0
- charm/toolbox/secretshare.py +104 -0
- charm/toolbox/secretutil.py +174 -0
- charm/toolbox/securerandom.py +73 -0
- charm/toolbox/sigmaprotocol.py +46 -0
- charm/toolbox/specialprimes.py +45 -0
- charm/toolbox/symcrypto.py +279 -0
- charm/toolbox/threshold_sharing.py +553 -0
- charm/toolbox/xmlserialize.py +94 -0
- charm/toolbox/zknode.py +105 -0
- charm/zkp_compiler/__init__.py +89 -0
- charm/zkp_compiler/and_proof.py +460 -0
- charm/zkp_compiler/batch_verify.py +324 -0
- charm/zkp_compiler/dleq_proof.py +423 -0
- charm/zkp_compiler/or_proof.py +305 -0
- charm/zkp_compiler/range_proof.py +417 -0
- charm/zkp_compiler/representation_proof.py +466 -0
- charm/zkp_compiler/schnorr_proof.py +273 -0
- charm/zkp_compiler/thread_safe.py +150 -0
- charm/zkp_compiler/zk_demo.py +489 -0
- charm/zkp_compiler/zkp_factory.py +330 -0
- charm/zkp_compiler/zkp_generator.py +370 -0
- charm/zkp_compiler/zkparser.py +269 -0
- charm_crypto_framework-0.61.1.dist-info/METADATA +337 -0
- charm_crypto_framework-0.61.1.dist-info/RECORD +323 -0
- charm_crypto_framework-0.61.1.dist-info/WHEEL +5 -0
- charm_crypto_framework-0.61.1.dist-info/licenses/LICENSE.txt +165 -0
- charm_crypto_framework-0.61.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Pointcheval-Sanders Signature (PS16) - Committed Messages**
|
|
3
|
+
|
|
4
|
+
*Authors:* D. Pointcheval, O. Sanders
|
|
5
|
+
|
|
6
|
+
| **Title:** "Short Randomizable Signatures"
|
|
7
|
+
| **Published in:** CT-RSA, 2016
|
|
8
|
+
| **Available from:** https://eprint.iacr.org/2015/525.pdf
|
|
9
|
+
| **Notes:** Section 6.1 - Signatures over committed messages.
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** signature (public key)
|
|
14
|
+
* **Setting:** bilinear groups (asymmetric)
|
|
15
|
+
* **Assumption:** PS assumption
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: Lovesh Harchandani
|
|
20
|
+
:Date: 6/2018
|
|
21
|
+
'''
|
|
22
|
+
from functools import reduce
|
|
23
|
+
|
|
24
|
+
from charm.toolbox.pairinggroup import PairingGroup, ZR, G1, G2, pair
|
|
25
|
+
|
|
26
|
+
debug = False
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class PS01:
|
|
30
|
+
"""
|
|
31
|
+
Signatures over committed messages, section 6.1 of the paper
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(self, groupObj):
|
|
35
|
+
global group
|
|
36
|
+
group = groupObj
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def keygen(num_messages=1):
|
|
40
|
+
x = group.random(ZR)
|
|
41
|
+
g1 = group.random(G1)
|
|
42
|
+
sk = {'x': x, 'X1': g1 ** x}
|
|
43
|
+
g2 = group.random(G2)
|
|
44
|
+
ys = [group.random(ZR) for _ in range(num_messages)]
|
|
45
|
+
X2 = g2 ** x
|
|
46
|
+
y1s = [g1 ** y for y in ys]
|
|
47
|
+
y2s = [g2 ** y for y in ys]
|
|
48
|
+
pk = {'X2': X2, 'Y2': y2s, 'Y1': y1s, 'g2': g2, 'g1': g1}
|
|
49
|
+
return pk, sk
|
|
50
|
+
|
|
51
|
+
def commitment(self, pk, *messages):
|
|
52
|
+
t = group.random(ZR)
|
|
53
|
+
return t, (pk['g1'] ** t) * self.product([y1 ** group.hash(m, ZR) for (y1, m) in zip(pk['Y1'], messages)])
|
|
54
|
+
|
|
55
|
+
def sign(self, sk, pk, commitment):
|
|
56
|
+
u = group.random(ZR)
|
|
57
|
+
return pk['g1'] ** u, (sk['X1'] * commitment) ** u
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def unblind_signature(t, sig):
|
|
61
|
+
s1, s2 = sig
|
|
62
|
+
return s1, (s2 / (s1 ** t))
|
|
63
|
+
|
|
64
|
+
def verify(self, pk, sig, *messages):
|
|
65
|
+
ms = [group.hash(m, ZR) for m in messages]
|
|
66
|
+
s1, s2 = sig
|
|
67
|
+
if group.init(G1) == s1:
|
|
68
|
+
return False
|
|
69
|
+
l2 = pk['X2'] * self.product([pk['Y2'][i] ** ms[i] for i in range(len(messages))])
|
|
70
|
+
return pair(s1, l2) == pair(pk['g2'], s2)
|
|
71
|
+
|
|
72
|
+
def randomize_sig(self, sig):
|
|
73
|
+
s1, s2 = sig
|
|
74
|
+
t = group.random(ZR)
|
|
75
|
+
return s1 ** t, s2 ** t
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
def product(seq):
|
|
79
|
+
return reduce(lambda x, y: x * y, seq)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def main():
|
|
83
|
+
grp = PairingGroup('MNT224')
|
|
84
|
+
ps = PS01(grp)
|
|
85
|
+
|
|
86
|
+
messages = ['Hi there', 'Not there', 'Some message ................', 'Dont know .............']
|
|
87
|
+
(pk, sk) = ps.keygen(len(messages))
|
|
88
|
+
if debug:
|
|
89
|
+
print("Keygen...")
|
|
90
|
+
print("pk :=", pk)
|
|
91
|
+
print("sk :=", sk)
|
|
92
|
+
|
|
93
|
+
t, commitment = ps.commitment(pk, *messages)
|
|
94
|
+
|
|
95
|
+
sig = ps.sign(sk, pk, commitment)
|
|
96
|
+
if debug:
|
|
97
|
+
print("Signature: ", sig)
|
|
98
|
+
|
|
99
|
+
sig = ps.unblind_signature(t, sig)
|
|
100
|
+
|
|
101
|
+
result = ps.verify(pk, sig, *messages)
|
|
102
|
+
assert result, "INVALID signature!"
|
|
103
|
+
if debug:
|
|
104
|
+
print("Successful Verification!!!")
|
|
105
|
+
|
|
106
|
+
rand_sig = ps.randomize_sig(sig)
|
|
107
|
+
assert sig != rand_sig
|
|
108
|
+
if debug:
|
|
109
|
+
print("Randomized Signature: ", rand_sig)
|
|
110
|
+
|
|
111
|
+
result = ps.verify(pk, rand_sig, *messages)
|
|
112
|
+
assert result, "INVALID signature!"
|
|
113
|
+
if debug:
|
|
114
|
+
print("Successful Verification!!!")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
debug = True
|
|
119
|
+
main()
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Hohenberger-Waters RSA Stateless Signature (HW09-RSA)**
|
|
3
|
+
|
|
4
|
+
*Authors:* S. Hohenberger, B. Waters
|
|
5
|
+
|
|
6
|
+
| **Title:** "Realizing Hash-and-Sign Signatures under Standard Assumptions"
|
|
7
|
+
| **Published in:** EUROCRYPT, 2009
|
|
8
|
+
| **Available from:** http://eprint.iacr.org/2009/028.pdf
|
|
9
|
+
| **Notes:** Section 3. Status: Needs improvement.
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** signature (public key)
|
|
14
|
+
* **Setting:** RSA
|
|
15
|
+
* **Assumption:** RSA
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: J. Ayo Akinyele, Christina Garman
|
|
20
|
+
:Date: 12/2011
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
from charm.core.math.integer import integer,random,randomBits,isPrime,gcd,bitsize,serialize
|
|
24
|
+
from charm.toolbox.PKSig import PKSig
|
|
25
|
+
from charm.schemes.chamhash_rsa_hw09 import ChamHash_HW09
|
|
26
|
+
from charm.toolbox.conversion import Conversion
|
|
27
|
+
from charm.toolbox.specialprimes import BlumWilliamsInteger
|
|
28
|
+
import hmac, hashlib, math
|
|
29
|
+
|
|
30
|
+
debug = False
|
|
31
|
+
|
|
32
|
+
def SHA1(bytes1):
|
|
33
|
+
s1 = hashlib.new('sha1') # nosec B324 - SHA1 used for historical compatibility
|
|
34
|
+
s1.update(bytes1)
|
|
35
|
+
return s1.digest()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def randomQR(n):
|
|
39
|
+
return random(n) ** 2
|
|
40
|
+
|
|
41
|
+
class LogFunction:
|
|
42
|
+
def __init__(self, base=10):
|
|
43
|
+
self.base = base
|
|
44
|
+
|
|
45
|
+
def __getitem__(self, base):
|
|
46
|
+
return LogFunction(base)
|
|
47
|
+
|
|
48
|
+
def __call__(self, val):
|
|
49
|
+
return math.log(val, self.base)
|
|
50
|
+
log = LogFunction()
|
|
51
|
+
|
|
52
|
+
class Prf:
|
|
53
|
+
def __init__(self):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def keygen(self, bits):
|
|
58
|
+
return integer(randomBits(bits))
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def eval(self, k, input1):
|
|
62
|
+
if type(k) == integer:
|
|
63
|
+
h = hmac.new(serialize(k), b'', hashlib.sha1)
|
|
64
|
+
else:
|
|
65
|
+
h = hmac.new(serialize(integer(k)), b'', hashlib.sha1)
|
|
66
|
+
|
|
67
|
+
h.update(input1)
|
|
68
|
+
return Conversion.bytes2integer(h.hexdigest())
|
|
69
|
+
|
|
70
|
+
class BlumIntegerSquareRoot:
|
|
71
|
+
def __init__(self, p, q):
|
|
72
|
+
self.raisedToThePower = 1
|
|
73
|
+
self.p = p
|
|
74
|
+
self.q = q
|
|
75
|
+
|
|
76
|
+
def pow(self, modularInt):
|
|
77
|
+
p, q = self.p, self.q
|
|
78
|
+
result = integer(modularInt) % (p * q)
|
|
79
|
+
for repeat in range(self.raisedToThePower):
|
|
80
|
+
result = result ** (((p-1)*(q-1)+4)/8)
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
def __pow__(self, power):
|
|
84
|
+
exp = BlumIntegerSquareRoot(self.p, self.q)
|
|
85
|
+
exp.raisedToThePower = power
|
|
86
|
+
return exp.pow(power)
|
|
87
|
+
|
|
88
|
+
class Sig_RSA_Stateless_HW09(PKSig):
|
|
89
|
+
"""
|
|
90
|
+
This scheme is probablistic and thus time consuming, so we skip it
|
|
91
|
+
when running doctests.
|
|
92
|
+
#doctest: +SKIP
|
|
93
|
+
|
|
94
|
+
>>> pksig = Sig_RSA_Stateless_HW09() #doctest:+SKIP
|
|
95
|
+
>>> p = integer(13075790812874903063868976368194105132206964291400106069285054021531242344673657224376055832139406140158530256050580761865568307154219348003780027259560207) #doctest:+SKIP
|
|
96
|
+
>>> q = integer(12220150399144091059083151334113293594120344494042436487743750419696868216757186059428173175925369884682105191510729093971051869295857706815002710593321543) #doctest:+SKIP
|
|
97
|
+
>>> (public_key, secret_key) = pksig.keygen(1024, p, q) #doctest:+SKIP
|
|
98
|
+
>>> msg = SHA1(b'this is the message I want to sign.') #doctest:+SKIP
|
|
99
|
+
>>> signature = pksig.sign(public_key, secret_key, msg) #doctest:+SKIP
|
|
100
|
+
>>> pksig.verify(public_key, msg, signature) #doctest:+SKIP
|
|
101
|
+
True
|
|
102
|
+
"""
|
|
103
|
+
def __init__(self, CH = ChamHash_HW09):
|
|
104
|
+
self.BWInt = BlumWilliamsInteger()
|
|
105
|
+
self.Prf = Prf()
|
|
106
|
+
self.ChameleonHash = CH()
|
|
107
|
+
|
|
108
|
+
def keygen(self, keyLength=1024, p=0, q=0):
|
|
109
|
+
# Generate a Blum-Williams integer N of 'key_length' bits with factorization p,q
|
|
110
|
+
if p == 0 or q == 0:
|
|
111
|
+
(p, q) = self.BWInt.generatePrimes(int(keyLength/2))
|
|
112
|
+
# Generate random u,h \in QR_N and a random c \in {0,1}^|N|
|
|
113
|
+
N = p * q
|
|
114
|
+
u = randomQR(N)
|
|
115
|
+
h = randomQR(N)
|
|
116
|
+
c = randomBits(keyLength)#PRNG_generate_bits(key_length)
|
|
117
|
+
|
|
118
|
+
K = self.Prf.keygen(keyLength)
|
|
119
|
+
self.state = 0
|
|
120
|
+
|
|
121
|
+
# Generate the Chameleon hash parameters. We do not need the secret params.
|
|
122
|
+
(L, secret) = self.ChameleonHash.paramgen(keyLength, p, q);
|
|
123
|
+
|
|
124
|
+
# Assemble the public and secret keys
|
|
125
|
+
pk = { 'length': keyLength, 'N': N, 'u': u, 'h': h, 'c': c, 'K': K, 'L': L }
|
|
126
|
+
sk = { 'p': p, 'q': q }
|
|
127
|
+
return (pk, sk);
|
|
128
|
+
|
|
129
|
+
def sign(self, pk, sk, message, s=0):
|
|
130
|
+
if debug: print("Sign...")
|
|
131
|
+
L, K, c, keyLength, u, h, N = pk['L'], pk['K'], pk['c'], pk['length'], pk['u'], pk['h'], pk['N']
|
|
132
|
+
p, q = sk['p'], sk['q']
|
|
133
|
+
# Use internal state counter if none was provided
|
|
134
|
+
if (s == 0):
|
|
135
|
+
s = self.state
|
|
136
|
+
self.state += 1
|
|
137
|
+
s += 1
|
|
138
|
+
|
|
139
|
+
# Hash the message using the chameleon hash under params L to obtain (x, r)
|
|
140
|
+
(x, r) = self.ChameleonHash.hash(L, message);
|
|
141
|
+
# Compute e = H_k(s) and check whether it's prime. If not, increment s and repeat.
|
|
142
|
+
phi_N = (p-1)*(q-1)
|
|
143
|
+
e = self.HW_hash(K, c, s, keyLength)
|
|
144
|
+
e1 = e % phi_N
|
|
145
|
+
e2 = e % N
|
|
146
|
+
|
|
147
|
+
while (not (isPrime(e2))) or (not gcd(e1, phi_N) == 1):
|
|
148
|
+
s += 1
|
|
149
|
+
e = self.HW_hash(K, c, s, keyLength)
|
|
150
|
+
e1 = e % phi_N
|
|
151
|
+
e2 = e % N
|
|
152
|
+
e = e1
|
|
153
|
+
|
|
154
|
+
# Compute B = SQRT(u^x * h)^ceil(log_2(s)) mod N
|
|
155
|
+
# Note that SQRT requires the factorization p, q
|
|
156
|
+
temp = ((u ** x) * h) % N
|
|
157
|
+
power = ((((p-1)*(q-1))+4)/8) ** (math.ceil(log[2](s)))
|
|
158
|
+
B = temp ** power
|
|
159
|
+
sigma1 = (B ** (e ** -1)) % N
|
|
160
|
+
|
|
161
|
+
# Update internal state counter and return sig = (sigma1, r, s)
|
|
162
|
+
self.state = s
|
|
163
|
+
return { 'sigma1':sigma1, 'r': r, 's': s, 'e':e }
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def verify(self, pk, message, sig):
|
|
167
|
+
if debug: print("\nVERIFY\n\n")
|
|
168
|
+
sigma1, r, s, e = sig['sigma1'], sig['r'], sig['s'], sig['e']
|
|
169
|
+
K, L, c, keyLength, u, h, N = pk['K'], pk['L'], pk['c'], pk['length'], pk['u'], pk['h'], pk['N']
|
|
170
|
+
|
|
171
|
+
# Make sure that 0 < s < 2^{keylength/2}, else reject the signature
|
|
172
|
+
if not (0 < s and s < (2 ** (keyLength/2))):
|
|
173
|
+
return False
|
|
174
|
+
|
|
175
|
+
# Compute e = H_k(s) and reject the signature if it's not prime
|
|
176
|
+
ei = self.HW_hash(K, c, s, keyLength) % N
|
|
177
|
+
if not isPrime(ei):
|
|
178
|
+
if debug: print("ei not prime")
|
|
179
|
+
return False
|
|
180
|
+
|
|
181
|
+
# Compute Y = sigma1^{2*ceil(log2(s))}
|
|
182
|
+
s1 = integer(2 ** (math.ceil(log[2](s))))
|
|
183
|
+
Y = (sigma1 ** s1) % N
|
|
184
|
+
|
|
185
|
+
# Hash the mesage using the chameleon hash with fixed randomness r
|
|
186
|
+
(x, r2) = self.ChameleonHash.hash(L, message, r)
|
|
187
|
+
|
|
188
|
+
lhs = (Y ** ei) % N
|
|
189
|
+
rhs = ((u ** x) * h) % N
|
|
190
|
+
if debug:
|
|
191
|
+
print("lhs =>", lhs)
|
|
192
|
+
print("rhs =>", rhs)
|
|
193
|
+
# Verify that Y^e = (u^x h) mod N. If so, accept the signature
|
|
194
|
+
if lhs == rhs:
|
|
195
|
+
return True
|
|
196
|
+
# Default: reject the signature
|
|
197
|
+
return False
|
|
198
|
+
|
|
199
|
+
def HW_hash(self, key, c, input, keyLen):
|
|
200
|
+
C = integer(c)
|
|
201
|
+
input_size = bitsize(c)
|
|
202
|
+
input_b = Conversion.IP2OS(input, input_size)
|
|
203
|
+
# Return c XOR PRF(k, input), where the output of PRF is keyLength bits
|
|
204
|
+
result = C ^ self.Prf.eval(key, input_b)
|
|
205
|
+
return result
|
|
206
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Schnorr Signature (Schnorr91)**
|
|
3
|
+
|
|
4
|
+
*Authors:* C. P. Schnorr
|
|
5
|
+
|
|
6
|
+
| **Title:** "Efficient Signature Generation by Smart Cards"
|
|
7
|
+
| **Published in:** Journal of Cryptology, 1991
|
|
8
|
+
| **Available from:** https://link.springer.com/article/10.1007/BF00196725
|
|
9
|
+
| **Notes:**
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** signature (public key)
|
|
14
|
+
* **Setting:** integer groups
|
|
15
|
+
* **Assumption:** Discrete Logarithm
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: Charm Developers
|
|
20
|
+
:Date: 2011
|
|
21
|
+
'''
|
|
22
|
+
from charm.toolbox.integergroup import IntegerGroupQ
|
|
23
|
+
from charm.toolbox.PKSig import PKSig
|
|
24
|
+
|
|
25
|
+
debug = False
|
|
26
|
+
class SchnorrSig(PKSig):
|
|
27
|
+
"""
|
|
28
|
+
>>> from charm.core.math.integer import integer
|
|
29
|
+
>>> p = integer(156816585111264668689583680968857341596876961491501655859473581156994765485015490912709775771877391134974110808285244016265856659644360836326566918061490651852930016078015163968109160397122004869749553669499102243382571334855815358562585736488447912605222780091120196023676916968821094827532746274593222577067)
|
|
30
|
+
>>> q = integer(78408292555632334344791840484428670798438480745750827929736790578497382742507745456354887885938695567487055404142622008132928329822180418163283459030745325926465008039007581984054580198561002434874776834749551121691285667427907679281292868244223956302611390045560098011838458484410547413766373137296611288533)
|
|
31
|
+
>>> pksig = SchnorrSig()
|
|
32
|
+
>>> pksig.params(p, q)
|
|
33
|
+
>>> (public_key, secret_key) = pksig.keygen()
|
|
34
|
+
>>> msg = "hello world."
|
|
35
|
+
>>> signature = pksig.sign(public_key, secret_key, msg)
|
|
36
|
+
>>> pksig.verify(public_key, signature, msg)
|
|
37
|
+
True
|
|
38
|
+
"""
|
|
39
|
+
def __init__(self):
|
|
40
|
+
PKSig.__init__(self)
|
|
41
|
+
|
|
42
|
+
def params(self, p=0, q=0, bits=1024):
|
|
43
|
+
global group
|
|
44
|
+
group = IntegerGroupQ(0)
|
|
45
|
+
if p == 0 or q == 0:
|
|
46
|
+
group.paramgen(bits)
|
|
47
|
+
else:
|
|
48
|
+
group.p, group.q, group.r = p, q, 2
|
|
49
|
+
|
|
50
|
+
def keygen(self):
|
|
51
|
+
p = group.p
|
|
52
|
+
x, g = group.random(), group.randomGen()
|
|
53
|
+
y = (g ** x)
|
|
54
|
+
return ({'y':y, 'g':g}, x)
|
|
55
|
+
|
|
56
|
+
def sign(self, pk, x, M):
|
|
57
|
+
p,q = group.p, group.q
|
|
58
|
+
k = group.random()
|
|
59
|
+
r = (pk['g'] ** k) % p
|
|
60
|
+
e = group.hash(M, r)
|
|
61
|
+
s = (k - x*e) % q
|
|
62
|
+
|
|
63
|
+
return {'e':e, 's':s }
|
|
64
|
+
|
|
65
|
+
def verify(self, pk, sig, M):
|
|
66
|
+
p = group.p
|
|
67
|
+
r = ((pk['g'] ** sig['s']) * (pk['y'] ** sig['e'])) % p
|
|
68
|
+
if debug: print("Verifying...")
|
|
69
|
+
e = group.hash(M, r)
|
|
70
|
+
if debug: print("e => %s" % e)
|
|
71
|
+
if debug: print("r => %s" % r)
|
|
72
|
+
if e == sig['e']:
|
|
73
|
+
return True
|
|
74
|
+
else:
|
|
75
|
+
return False
|
|
76
|
+
return None
|
|
77
|
+
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Waters Identity-Based Signature (Waters05)**
|
|
3
|
+
|
|
4
|
+
*Authors:* B. Waters
|
|
5
|
+
|
|
6
|
+
| **Title:** "Efficient Identity-Based Encryption Without Random Oracles"
|
|
7
|
+
| **Published in:** EUROCRYPT, 2005
|
|
8
|
+
| **Available from:** LNCS Vol. 3494, pages 320-329
|
|
9
|
+
| **Notes:**
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** signature (identity-based)
|
|
14
|
+
* **Setting:** bilinear groups (asymmetric)
|
|
15
|
+
* **Assumption:** DBDH
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: J. Ayo Akinyele
|
|
20
|
+
:Date: 11/2011
|
|
21
|
+
'''
|
|
22
|
+
from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,pair
|
|
23
|
+
from charm.toolbox.iterate import dotprod
|
|
24
|
+
from charm.toolbox.hash_module import Waters
|
|
25
|
+
|
|
26
|
+
debug = False
|
|
27
|
+
class WatersSig:
|
|
28
|
+
"""
|
|
29
|
+
>>> from charm.toolbox.pairinggroup import PairingGroup
|
|
30
|
+
>>> group = PairingGroup('SS512')
|
|
31
|
+
>>> water = WatersSig(group)
|
|
32
|
+
>>> (master_public_key, master_secret_key) = water.setup(5)
|
|
33
|
+
>>> ID = 'janedoe@email.com'
|
|
34
|
+
>>> secret_key = water.keygen(master_public_key, master_secret_key, ID)
|
|
35
|
+
>>> msg = 'please sign this new message!'
|
|
36
|
+
>>> signature = water.sign(master_public_key, secret_key, msg)
|
|
37
|
+
>>> water.verify(master_public_key, ID, msg, signature)
|
|
38
|
+
True
|
|
39
|
+
"""
|
|
40
|
+
def __init__(self, groupObj):
|
|
41
|
+
global group,lam_func
|
|
42
|
+
group = groupObj
|
|
43
|
+
lam_func = lambda i,a,b: a[i] ** b[i]
|
|
44
|
+
|
|
45
|
+
def setup(self, z, l=32):
|
|
46
|
+
global waters
|
|
47
|
+
waters = Waters(group, z, l)
|
|
48
|
+
alpha, h = group.random(ZR), group.random(G1)
|
|
49
|
+
g1, g2 = group.random(G1), group.random(G2)
|
|
50
|
+
A = pair(h, g2) ** alpha
|
|
51
|
+
y = [group.random(ZR) for i in range(z)]
|
|
52
|
+
y1t,y2t = group.random(ZR), group.random(ZR)
|
|
53
|
+
|
|
54
|
+
u1t = g1 ** y1t; u2t = g1 ** y2t
|
|
55
|
+
u = [g1 ** y[i] for i in range(z)]
|
|
56
|
+
|
|
57
|
+
u1b = g2 ** y1t; u2b = g2 ** y2t
|
|
58
|
+
ub =[g2 ** y[i] for i in range(z)]
|
|
59
|
+
|
|
60
|
+
msk = h ** alpha
|
|
61
|
+
mpk = {'g1':g1, 'g2':g2, 'A':A, 'u1t':u1t, 'u2t':u2t, 'u':u, 'u1b':u1b, 'u2b':u2b, 'ub':ub, 'z':z, 'l':l }
|
|
62
|
+
return (mpk, msk)
|
|
63
|
+
|
|
64
|
+
def keygen(self, mpk, msk, ID):
|
|
65
|
+
if debug: print("Keygen alg...")
|
|
66
|
+
k = waters.hash(ID) # return list from k1,...,kz
|
|
67
|
+
if debug: print("k =>", k)
|
|
68
|
+
r = group.random(ZR)
|
|
69
|
+
k1 = msk * ((mpk['u1t'] * dotprod(1, -1, mpk['z'], lam_func, mpk['u'], k)) ** r)
|
|
70
|
+
k2 = mpk['g1'] ** -r
|
|
71
|
+
return (k1, k2)
|
|
72
|
+
|
|
73
|
+
def sign(self, mpk, sk, M):
|
|
74
|
+
if debug: print("Sign alg...")
|
|
75
|
+
m = waters.hash(M) # return list from m1,...,mz
|
|
76
|
+
if debug: print("m =>", m)
|
|
77
|
+
(k1, k2) = sk
|
|
78
|
+
s = group.random(ZR)
|
|
79
|
+
S1 = k1 * ((mpk['u2t'] * dotprod(1, -1, mpk['z'], lam_func, mpk['u'], m)) ** s)
|
|
80
|
+
S2 = k2
|
|
81
|
+
S3 = mpk['g1'] ** -s
|
|
82
|
+
return {'S1':S1, 'S2':S2, 'S3':S3}
|
|
83
|
+
|
|
84
|
+
def verify(self, mpk, ID, M, sig):
|
|
85
|
+
if debug: print("Verify...")
|
|
86
|
+
k = waters.hash(ID)
|
|
87
|
+
m = waters.hash(M)
|
|
88
|
+
(S1, S2, S3) = sig['S1'], sig['S2'], sig['S3']
|
|
89
|
+
A, g2 = mpk['A'], mpk['g2']
|
|
90
|
+
comp1 = dotprod(1, -1, mpk['z'], lam_func, mpk['ub'], k)
|
|
91
|
+
comp2 = dotprod(1, -1, mpk['z'], lam_func, mpk['ub'], m)
|
|
92
|
+
lhs = (pair(S1, g2) * pair(S2, mpk['u1b'] * comp1) * pair(S3, mpk['u2b'] * comp2))
|
|
93
|
+
#if ((pair(S1, g2) * pair(S2, mpk['u1b'] * comp1) * pair(S3, mpk['u2b'] * comp2)) == A):
|
|
94
|
+
if lhs == A:
|
|
95
|
+
return True
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
def main():
|
|
99
|
+
groupObj = PairingGroup('SS512')
|
|
100
|
+
wat = WatersSig(groupObj)
|
|
101
|
+
(master_public_key, master_secret_key) = wat.setup(5)
|
|
102
|
+
ID = 'janedoe@email.com'
|
|
103
|
+
secret_key = wat.keygen(master_public_key, master_secret_key, ID)
|
|
104
|
+
msg = 'please sign this new message!'
|
|
105
|
+
|
|
106
|
+
sig = wat.sign(master_public_key, secret_key, msg)
|
|
107
|
+
|
|
108
|
+
assert wat.verify(master_public_key, ID, msg, sig), "invalid signature"
|
|
109
|
+
if debug: print("Successful Verification!")
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
debug = True
|
|
113
|
+
main()
|
|
114
|
+
|
|
115
|
+
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
'''
|
|
2
|
+
**Naccache Identity-Based Signature (N04)**
|
|
3
|
+
|
|
4
|
+
*Authors:* D. Naccache
|
|
5
|
+
|
|
6
|
+
| **Title:** "Secure and Practical Identity-Based Encryption"
|
|
7
|
+
| **Published in:** IET Information Security, 2005
|
|
8
|
+
| **Available from:** http://eprint.iacr.org/2005/369.pdf
|
|
9
|
+
| **Notes:** Section 4. Optimized with pre-computed pairings and swapped g1/g2.
|
|
10
|
+
|
|
11
|
+
.. rubric:: Scheme Properties
|
|
12
|
+
|
|
13
|
+
* **Type:** signature (identity-based)
|
|
14
|
+
* **Setting:** bilinear groups (asymmetric)
|
|
15
|
+
* **Assumption:** DBDH
|
|
16
|
+
|
|
17
|
+
.. rubric:: Implementation
|
|
18
|
+
|
|
19
|
+
:Authors: Gary Belvin (original), Fan Zhang (improvements)
|
|
20
|
+
:Date: 06/2011 (original), 3/2013 (improvements)
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
|
|
24
|
+
from charm.toolbox.PKSig import PKSig
|
|
25
|
+
from charm.toolbox.enum import Enum
|
|
26
|
+
from charm.toolbox.hash_module import Waters
|
|
27
|
+
import math
|
|
28
|
+
|
|
29
|
+
debug = False
|
|
30
|
+
class IBE_N04_Sig(PKSig):
|
|
31
|
+
"""
|
|
32
|
+
>>> from charm.toolbox.pairinggroup import PairingGroup
|
|
33
|
+
>>> group = PairingGroup('SS512')
|
|
34
|
+
>>> waters = Waters(group)
|
|
35
|
+
>>> ibe = IBE_N04_Sig(group)
|
|
36
|
+
>>> (public_key, secret_key) = ibe.keygen()
|
|
37
|
+
>>> ID = "bob@example.com"
|
|
38
|
+
>>> msg = waters.hash("This is a test.")
|
|
39
|
+
>>> signature = ibe.sign(public_key, secret_key, msg)
|
|
40
|
+
>>> ibe.verify(public_key, msg, signature)
|
|
41
|
+
True
|
|
42
|
+
"""
|
|
43
|
+
"""Implementation of David Naccahe Identity Based Encryption"""
|
|
44
|
+
def __init__(self, groupObj):
|
|
45
|
+
PKSig.__init__(self)
|
|
46
|
+
#PKSig.setProperty(self, secdef='IND_ID_CPA', assumption='DBDH', secmodel='Standard')
|
|
47
|
+
#, other={'id':ZR}
|
|
48
|
+
#message_space=[GT, 'KEM']
|
|
49
|
+
global group
|
|
50
|
+
group = groupObj
|
|
51
|
+
|
|
52
|
+
def keygen(self, l=32):
|
|
53
|
+
"""l is the security parameter
|
|
54
|
+
with l = 32, and the hash function at 256 bits = n * l with n = 8"""
|
|
55
|
+
global waters
|
|
56
|
+
g = group.random(G2) # generator for group G of prime order p
|
|
57
|
+
|
|
58
|
+
#hLen = sha1_len * 8
|
|
59
|
+
#int(math.floor(hLen / l))
|
|
60
|
+
sha2_byte_len = 32
|
|
61
|
+
hLen = sha2_byte_len * 8
|
|
62
|
+
n = int(math.floor(hLen / l))
|
|
63
|
+
waters = Waters(group, n, l, 'sha256')
|
|
64
|
+
|
|
65
|
+
alpha = group.random(ZR) #from Zp
|
|
66
|
+
g2 = g ** alpha
|
|
67
|
+
g1 = group.random(G1)
|
|
68
|
+
u = group.random(ZR)
|
|
69
|
+
uprime = g ** u
|
|
70
|
+
U_z = [group.random(ZR) for x in range(n)]
|
|
71
|
+
U = [g ** x for x in U_z]
|
|
72
|
+
|
|
73
|
+
pk = {'g':g, 'g1':g1, 'g2': g2, 'uPrime':uprime, 'U': U,
|
|
74
|
+
'n':n, 'l':l, 'egg': pair(g1, g2) }
|
|
75
|
+
|
|
76
|
+
mk = {'g1^alpha':g1 ** alpha, 'U_z':U_z, 'u':u} #master secret
|
|
77
|
+
if debug:
|
|
78
|
+
print(mk)
|
|
79
|
+
|
|
80
|
+
return (pk, mk)
|
|
81
|
+
|
|
82
|
+
def sign(self, pk, sk, m):
|
|
83
|
+
"""v = (v1, .., vn) is an identity"""
|
|
84
|
+
r = group.random(ZR)
|
|
85
|
+
u = sk['u']
|
|
86
|
+
for i in range(pk['n']):
|
|
87
|
+
u += sk['U_z'][i] * m[i]
|
|
88
|
+
|
|
89
|
+
d1 = sk['g1^alpha'] * (pk['g1'] ** (u * r))
|
|
90
|
+
d2 = pk['g1'] ** r
|
|
91
|
+
return {'d1': d1, 'd2':d2}
|
|
92
|
+
|
|
93
|
+
def verify(self, pk, msg, sig):
|
|
94
|
+
c3 = pk['uPrime']
|
|
95
|
+
for i in range(pk['n']):
|
|
96
|
+
c3 *= pk['U'][i] ** msg[i]
|
|
97
|
+
|
|
98
|
+
return pk['egg'] == (pair(sig['d1'], pk['g']) / pair(sig['d2'], c3))
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def main():
|
|
102
|
+
groupObj = PairingGroup('SS512')
|
|
103
|
+
ibe = IBE_N04_Sig(groupObj)
|
|
104
|
+
waters = Waters(group)
|
|
105
|
+
(pk, sk) = ibe.keygen()
|
|
106
|
+
|
|
107
|
+
# represents public identity
|
|
108
|
+
M = "bob@example.com"
|
|
109
|
+
msg = waters.hash("This is a test.")
|
|
110
|
+
sig = ibe.sign(pk, sk, msg)
|
|
111
|
+
if debug:
|
|
112
|
+
print("original msg => '%s'" % M)
|
|
113
|
+
print("msg => '%s'" % msg)
|
|
114
|
+
print("sig => '%s'" % sig)
|
|
115
|
+
|
|
116
|
+
assert ibe.verify(pk, msg, sig), "Failed verification!"
|
|
117
|
+
if debug: print("Successful Verification!!! msg => '%s'" % msg)
|
|
118
|
+
|
|
119
|
+
if __name__ == '__main__':
|
|
120
|
+
debug = True
|
|
121
|
+
main()
|