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,273 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Schnorr's Zero-Knowledge Proof implementation without exec().
|
|
3
|
+
|
|
4
|
+
This module provides a direct implementation of Schnorr's ZKP protocol
|
|
5
|
+
for proving knowledge of discrete logarithm.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
|
|
11
|
+
from charm.core.engine.util import objectToBytes, bytesToObject
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Proof:
|
|
18
|
+
"""Simple container for ZKP proof data."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, commitment: Any, challenge: Any, response: Any, proof_type: str = 'schnorr') -> None:
|
|
21
|
+
"""
|
|
22
|
+
Initialize a proof.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
commitment: The prover's commitment (u = g^r)
|
|
26
|
+
challenge: The challenge value (c)
|
|
27
|
+
response: The response value (z = r + c*x)
|
|
28
|
+
proof_type: Type identifier for the proof
|
|
29
|
+
"""
|
|
30
|
+
self.commitment = commitment
|
|
31
|
+
self.challenge = challenge
|
|
32
|
+
self.response = response
|
|
33
|
+
self.proof_type = proof_type
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SchnorrProof:
|
|
37
|
+
"""
|
|
38
|
+
Schnorr's Zero-Knowledge Proof of Knowledge of Discrete Logarithm.
|
|
39
|
+
|
|
40
|
+
Proves knowledge of x such that h = g^x without revealing x.
|
|
41
|
+
|
|
42
|
+
Supports both interactive and non-interactive (Fiat-Shamir) modes.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
class Prover:
|
|
46
|
+
"""Prover for Schnorr protocol."""
|
|
47
|
+
|
|
48
|
+
def __init__(self, secret_x, group):
|
|
49
|
+
"""
|
|
50
|
+
Initialize prover with secret x.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
secret_x: The secret discrete log value
|
|
54
|
+
group: The pairing group object
|
|
55
|
+
"""
|
|
56
|
+
self._r = None # Random commitment value (private)
|
|
57
|
+
self.group = group
|
|
58
|
+
self._x = secret_x # Secret (private)
|
|
59
|
+
|
|
60
|
+
def create_commitment(self, g):
|
|
61
|
+
"""
|
|
62
|
+
Create prover's commitment: u = g^r.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
g: The generator element
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
The commitment u = g^r
|
|
69
|
+
"""
|
|
70
|
+
self._r = self.group.random(ZR)
|
|
71
|
+
u = g ** self._r
|
|
72
|
+
logger.debug("Prover created commitment")
|
|
73
|
+
return u
|
|
74
|
+
|
|
75
|
+
def create_response(self, challenge):
|
|
76
|
+
"""
|
|
77
|
+
Create response to verifier's challenge: z = r + c*x.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
challenge: The challenge value c from verifier
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The response z = r + c*x
|
|
84
|
+
"""
|
|
85
|
+
if self._r is None:
|
|
86
|
+
raise ValueError("Must call create_commitment before create_response")
|
|
87
|
+
z = self._r + challenge * self._x
|
|
88
|
+
logger.debug("Prover created response")
|
|
89
|
+
return z
|
|
90
|
+
|
|
91
|
+
class Verifier:
|
|
92
|
+
"""Verifier for Schnorr protocol."""
|
|
93
|
+
|
|
94
|
+
def __init__(self, group):
|
|
95
|
+
"""
|
|
96
|
+
Initialize verifier.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
group: The pairing group object
|
|
100
|
+
"""
|
|
101
|
+
self.group = group
|
|
102
|
+
self._c = None # Challenge (stored for verification)
|
|
103
|
+
|
|
104
|
+
def create_challenge(self):
|
|
105
|
+
"""
|
|
106
|
+
Create random challenge c.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Random challenge c in ZR
|
|
110
|
+
"""
|
|
111
|
+
self._c = self.group.random(ZR)
|
|
112
|
+
logger.debug("Verifier created challenge")
|
|
113
|
+
return self._c
|
|
114
|
+
|
|
115
|
+
def verify(self, g, h, commitment, response):
|
|
116
|
+
"""
|
|
117
|
+
Verify proof: g^z == u * h^c.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
g: The generator element
|
|
121
|
+
h: The public value h = g^x
|
|
122
|
+
commitment: The prover's commitment u
|
|
123
|
+
response: The prover's response z
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
True if proof is valid, False otherwise
|
|
127
|
+
"""
|
|
128
|
+
if self._c is None:
|
|
129
|
+
raise ValueError("Must call create_challenge before verify")
|
|
130
|
+
lhs = g ** response
|
|
131
|
+
rhs = commitment * (h ** self._c)
|
|
132
|
+
result = lhs == rhs
|
|
133
|
+
logger.debug("Verification result: %s", result)
|
|
134
|
+
return result
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def _compute_challenge_hash(cls, group, g, h, commitment):
|
|
138
|
+
"""
|
|
139
|
+
Compute Fiat-Shamir challenge as hash of public values.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
group: The pairing group
|
|
143
|
+
g: Generator
|
|
144
|
+
h: Public value h = g^x
|
|
145
|
+
commitment: The commitment u = g^r
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Challenge c as element of ZR
|
|
149
|
+
"""
|
|
150
|
+
# Serialize elements and concatenate for hashing
|
|
151
|
+
data = objectToBytes(g, group) + objectToBytes(h, group) + objectToBytes(commitment, group)
|
|
152
|
+
return group.hash(data, ZR)
|
|
153
|
+
|
|
154
|
+
@classmethod
|
|
155
|
+
def prove_non_interactive(cls, group: PairingGroup, g: Any, h: Any, x: Any) -> Proof:
|
|
156
|
+
"""
|
|
157
|
+
Generate non-interactive proof using Fiat-Shamir heuristic.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
group: The pairing group
|
|
161
|
+
g: The generator element
|
|
162
|
+
h: The public value h = g^x
|
|
163
|
+
x: The secret discrete log
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Proof object containing commitment, challenge, and response
|
|
167
|
+
"""
|
|
168
|
+
# 1. Generate random r
|
|
169
|
+
r = group.random(ZR)
|
|
170
|
+
|
|
171
|
+
# 2. Compute commitment u = g^r
|
|
172
|
+
commitment = g ** r
|
|
173
|
+
|
|
174
|
+
# 3. Compute challenge c = hash(g, h, u)
|
|
175
|
+
challenge = cls._compute_challenge_hash(group, g, h, commitment)
|
|
176
|
+
|
|
177
|
+
# 4. Compute response z = r + c*x
|
|
178
|
+
response = r + challenge * x
|
|
179
|
+
|
|
180
|
+
logger.debug("Generated non-interactive proof")
|
|
181
|
+
return Proof(commitment=commitment, challenge=challenge, response=response, proof_type='schnorr')
|
|
182
|
+
|
|
183
|
+
@classmethod
|
|
184
|
+
def verify_non_interactive(cls, group: PairingGroup, g: Any, h: Any, proof: Proof) -> bool:
|
|
185
|
+
"""
|
|
186
|
+
Verify non-interactive proof.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
group: The pairing group
|
|
190
|
+
g: The generator element
|
|
191
|
+
h: The public value h = g^x
|
|
192
|
+
proof: Proof object containing commitment, challenge, and response
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
True if proof is valid, False otherwise
|
|
196
|
+
|
|
197
|
+
Security Notes:
|
|
198
|
+
- Validates proof structure before verification
|
|
199
|
+
- Checks for identity element attacks
|
|
200
|
+
- Recomputes Fiat-Shamir challenge for consistency
|
|
201
|
+
"""
|
|
202
|
+
# Security: Validate proof structure
|
|
203
|
+
required_attrs = ['commitment', 'challenge', 'response']
|
|
204
|
+
for attr in required_attrs:
|
|
205
|
+
if not hasattr(proof, attr):
|
|
206
|
+
logger.warning("Invalid Schnorr proof structure: missing '%s'. Ensure proof was created with SchnorrProof.prove_non_interactive()", attr)
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
# Security: Check for identity element (potential attack vector)
|
|
210
|
+
# The identity element would make the verification equation trivially true
|
|
211
|
+
try:
|
|
212
|
+
identity = group.init(G1, 1)
|
|
213
|
+
if proof.commitment == identity:
|
|
214
|
+
logger.warning("Security: Schnorr proof commitment is identity element (possible attack). Proof rejected.")
|
|
215
|
+
return False
|
|
216
|
+
except Exception:
|
|
217
|
+
pass # Some groups may not support identity check
|
|
218
|
+
|
|
219
|
+
# Recompute challenge c = hash(g, h, commitment)
|
|
220
|
+
expected_challenge = cls._compute_challenge_hash(group, g, h, proof.commitment)
|
|
221
|
+
|
|
222
|
+
# Verify challenge matches
|
|
223
|
+
if expected_challenge != proof.challenge:
|
|
224
|
+
logger.debug("Challenge mismatch in non-interactive verification")
|
|
225
|
+
return False
|
|
226
|
+
|
|
227
|
+
# Check g^z == commitment * h^c
|
|
228
|
+
lhs = g ** proof.response
|
|
229
|
+
rhs = proof.commitment * (h ** proof.challenge)
|
|
230
|
+
result = lhs == rhs
|
|
231
|
+
logger.debug("Non-interactive verification result: %s", result)
|
|
232
|
+
return result
|
|
233
|
+
|
|
234
|
+
@classmethod
|
|
235
|
+
def serialize_proof(cls, proof: Proof, group: PairingGroup) -> bytes:
|
|
236
|
+
"""
|
|
237
|
+
Serialize proof to bytes using Charm utilities.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
proof: Proof object to serialize
|
|
241
|
+
group: The pairing group
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
Bytes representation of the proof
|
|
245
|
+
"""
|
|
246
|
+
proof_dict = {
|
|
247
|
+
'commitment': proof.commitment,
|
|
248
|
+
'challenge': proof.challenge,
|
|
249
|
+
'response': proof.response,
|
|
250
|
+
'proof_type': proof.proof_type
|
|
251
|
+
}
|
|
252
|
+
return objectToBytes(proof_dict, group)
|
|
253
|
+
|
|
254
|
+
@classmethod
|
|
255
|
+
def deserialize_proof(cls, data: bytes, group: PairingGroup) -> Proof:
|
|
256
|
+
"""
|
|
257
|
+
Deserialize bytes to proof.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
data: Bytes to deserialize
|
|
261
|
+
group: The pairing group
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Proof object
|
|
265
|
+
"""
|
|
266
|
+
proof_dict = bytesToObject(data, group)
|
|
267
|
+
return Proof(
|
|
268
|
+
commitment=proof_dict['commitment'],
|
|
269
|
+
challenge=proof_dict['challenge'],
|
|
270
|
+
response=proof_dict['response'],
|
|
271
|
+
proof_type=proof_dict.get('proof_type', 'schnorr')
|
|
272
|
+
)
|
|
273
|
+
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Thread-safe wrappers for ZKP proof classes.
|
|
3
|
+
|
|
4
|
+
This module provides thread-safe versions of the ZKP proof classes for use
|
|
5
|
+
in multi-threaded applications. The non-interactive proof methods are already
|
|
6
|
+
thread-safe (they use only local variables), but the interactive Prover and
|
|
7
|
+
Verifier classes maintain state that requires synchronization.
|
|
8
|
+
|
|
9
|
+
Thread Safety Analysis:
|
|
10
|
+
=======================
|
|
11
|
+
|
|
12
|
+
1. Non-Interactive Methods (ALREADY THREAD-SAFE):
|
|
13
|
+
- SchnorrProof.prove_non_interactive()
|
|
14
|
+
- SchnorrProof.verify_non_interactive()
|
|
15
|
+
- DLEQProof.prove_non_interactive()
|
|
16
|
+
- DLEQProof.verify_non_interactive()
|
|
17
|
+
- RepresentationProof.prove_non_interactive()
|
|
18
|
+
- RepresentationProof.verify_non_interactive()
|
|
19
|
+
|
|
20
|
+
These methods use only local variables and class methods, so they are
|
|
21
|
+
inherently thread-safe. Multiple threads can call them concurrently.
|
|
22
|
+
|
|
23
|
+
2. Interactive Classes (REQUIRE SYNCHRONIZATION):
|
|
24
|
+
- SchnorrProof.Prover / SchnorrProof.Verifier
|
|
25
|
+
- DLEQProof.Prover / DLEQProof.Verifier
|
|
26
|
+
- RepresentationProof.Prover / RepresentationProof.Verifier
|
|
27
|
+
|
|
28
|
+
These classes maintain internal state (_r, _c, etc.) that must not be
|
|
29
|
+
accessed concurrently. Each thread should create its own Prover/Verifier
|
|
30
|
+
instance, OR use the thread-safe wrappers provided here.
|
|
31
|
+
|
|
32
|
+
Usage:
|
|
33
|
+
# For non-interactive proofs, just use the regular classes:
|
|
34
|
+
proof = SchnorrProof.prove_non_interactive(group, g, h, x) # Thread-safe
|
|
35
|
+
|
|
36
|
+
# For interactive proofs in multi-threaded code, use thread-safe wrappers:
|
|
37
|
+
prover = ThreadSafeProver(SchnorrProof.Prover(x, group))
|
|
38
|
+
with prover:
|
|
39
|
+
commitment = prover.create_commitment(g)
|
|
40
|
+
response = prover.create_response(challenge)
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
import threading
|
|
44
|
+
from contextlib import contextmanager
|
|
45
|
+
from functools import wraps
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ThreadSafeProver:
|
|
49
|
+
"""
|
|
50
|
+
Thread-safe wrapper for interactive Prover classes.
|
|
51
|
+
|
|
52
|
+
Wraps a Prover instance with a lock to ensure thread-safe access.
|
|
53
|
+
Use as a context manager for automatic lock management.
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
prover = ThreadSafeProver(SchnorrProof.Prover(x, group))
|
|
57
|
+
with prover:
|
|
58
|
+
commitment = prover.create_commitment(g)
|
|
59
|
+
response = prover.create_response(challenge)
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, prover):
|
|
63
|
+
"""
|
|
64
|
+
Initialize thread-safe prover wrapper.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
prover: The underlying Prover instance to wrap
|
|
68
|
+
"""
|
|
69
|
+
self._prover = prover
|
|
70
|
+
self._lock = threading.RLock()
|
|
71
|
+
|
|
72
|
+
def __enter__(self):
|
|
73
|
+
"""Acquire lock when entering context."""
|
|
74
|
+
self._lock.acquire()
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
78
|
+
"""Release lock when exiting context."""
|
|
79
|
+
self._lock.release()
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
def create_commitment(self, *args, **kwargs):
|
|
83
|
+
"""Thread-safe commitment creation."""
|
|
84
|
+
with self._lock:
|
|
85
|
+
return self._prover.create_commitment(*args, **kwargs)
|
|
86
|
+
|
|
87
|
+
def create_response(self, *args, **kwargs):
|
|
88
|
+
"""Thread-safe response creation."""
|
|
89
|
+
with self._lock:
|
|
90
|
+
return self._prover.create_response(*args, **kwargs)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class ThreadSafeVerifier:
|
|
94
|
+
"""
|
|
95
|
+
Thread-safe wrapper for interactive Verifier classes.
|
|
96
|
+
|
|
97
|
+
Wraps a Verifier instance with a lock to ensure thread-safe access.
|
|
98
|
+
Use as a context manager for automatic lock management.
|
|
99
|
+
|
|
100
|
+
Example:
|
|
101
|
+
verifier = ThreadSafeVerifier(SchnorrProof.Verifier(group))
|
|
102
|
+
with verifier:
|
|
103
|
+
challenge = verifier.create_challenge()
|
|
104
|
+
result = verifier.verify(g, h, commitment, response)
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
def __init__(self, verifier):
|
|
108
|
+
"""
|
|
109
|
+
Initialize thread-safe verifier wrapper.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
verifier: The underlying Verifier instance to wrap
|
|
113
|
+
"""
|
|
114
|
+
self._verifier = verifier
|
|
115
|
+
self._lock = threading.RLock()
|
|
116
|
+
|
|
117
|
+
def __enter__(self):
|
|
118
|
+
"""Acquire lock when entering context."""
|
|
119
|
+
self._lock.acquire()
|
|
120
|
+
return self
|
|
121
|
+
|
|
122
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
123
|
+
"""Release lock when exiting context."""
|
|
124
|
+
self._lock.release()
|
|
125
|
+
return False
|
|
126
|
+
|
|
127
|
+
def create_challenge(self, *args, **kwargs):
|
|
128
|
+
"""Thread-safe challenge creation."""
|
|
129
|
+
with self._lock:
|
|
130
|
+
return self._verifier.create_challenge(*args, **kwargs)
|
|
131
|
+
|
|
132
|
+
def verify(self, *args, **kwargs):
|
|
133
|
+
"""Thread-safe verification."""
|
|
134
|
+
with self._lock:
|
|
135
|
+
return self._verifier.verify(*args, **kwargs)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def thread_safe_proof(func):
|
|
139
|
+
"""
|
|
140
|
+
Decorator to make a proof function thread-safe.
|
|
141
|
+
|
|
142
|
+
This is mainly for documentation purposes since the non-interactive
|
|
143
|
+
proof methods are already thread-safe by design.
|
|
144
|
+
"""
|
|
145
|
+
@wraps(func)
|
|
146
|
+
def wrapper(*args, **kwargs):
|
|
147
|
+
return func(*args, **kwargs)
|
|
148
|
+
wrapper._thread_safe = True
|
|
149
|
+
return wrapper
|
|
150
|
+
|