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,169 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Thread safety tests for ZKP proof implementations.
|
|
3
|
+
|
|
4
|
+
Tests verify that:
|
|
5
|
+
1. Non-interactive proof methods are thread-safe
|
|
6
|
+
2. Thread-safe wrappers work correctly for interactive proofs
|
|
7
|
+
3. Concurrent proof generation/verification works correctly
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import unittest
|
|
11
|
+
import threading
|
|
12
|
+
import time
|
|
13
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
14
|
+
|
|
15
|
+
from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
|
|
16
|
+
from charm.zkp_compiler.schnorr_proof import SchnorrProof
|
|
17
|
+
from charm.zkp_compiler.dleq_proof import DLEQProof
|
|
18
|
+
from charm.zkp_compiler.representation_proof import RepresentationProof
|
|
19
|
+
from charm.zkp_compiler.thread_safe import ThreadSafeProver, ThreadSafeVerifier
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestNonInteractiveThreadSafety(unittest.TestCase):
|
|
23
|
+
"""Test that non-interactive proof methods are thread-safe."""
|
|
24
|
+
|
|
25
|
+
def setUp(self):
|
|
26
|
+
"""Set up test fixtures."""
|
|
27
|
+
self.group = PairingGroup('BN254')
|
|
28
|
+
self.num_threads = 10
|
|
29
|
+
self.proofs_per_thread = 5
|
|
30
|
+
|
|
31
|
+
def test_schnorr_concurrent_prove_verify(self):
|
|
32
|
+
"""Test concurrent Schnorr proof generation and verification."""
|
|
33
|
+
results = []
|
|
34
|
+
errors = []
|
|
35
|
+
|
|
36
|
+
def prove_and_verify():
|
|
37
|
+
try:
|
|
38
|
+
g = self.group.random(G1)
|
|
39
|
+
x = self.group.random(ZR)
|
|
40
|
+
h = g ** x
|
|
41
|
+
|
|
42
|
+
for _ in range(self.proofs_per_thread):
|
|
43
|
+
proof = SchnorrProof.prove_non_interactive(self.group, g, h, x)
|
|
44
|
+
valid = SchnorrProof.verify_non_interactive(self.group, g, h, proof)
|
|
45
|
+
results.append(valid)
|
|
46
|
+
except Exception as e:
|
|
47
|
+
errors.append(str(e))
|
|
48
|
+
|
|
49
|
+
threads = [threading.Thread(target=prove_and_verify) for _ in range(self.num_threads)]
|
|
50
|
+
for t in threads:
|
|
51
|
+
t.start()
|
|
52
|
+
for t in threads:
|
|
53
|
+
t.join()
|
|
54
|
+
|
|
55
|
+
self.assertEqual(len(errors), 0, f"Errors occurred: {errors}")
|
|
56
|
+
self.assertEqual(len(results), self.num_threads * self.proofs_per_thread)
|
|
57
|
+
self.assertTrue(all(results), "All proofs should verify")
|
|
58
|
+
|
|
59
|
+
def test_dleq_concurrent_prove_verify(self):
|
|
60
|
+
"""Test concurrent DLEQ proof generation and verification."""
|
|
61
|
+
results = []
|
|
62
|
+
errors = []
|
|
63
|
+
|
|
64
|
+
def prove_and_verify():
|
|
65
|
+
try:
|
|
66
|
+
g1 = self.group.random(G1)
|
|
67
|
+
g2 = self.group.random(G1)
|
|
68
|
+
x = self.group.random(ZR)
|
|
69
|
+
h1 = g1 ** x
|
|
70
|
+
h2 = g2 ** x
|
|
71
|
+
|
|
72
|
+
for _ in range(self.proofs_per_thread):
|
|
73
|
+
proof = DLEQProof.prove_non_interactive(self.group, g1, h1, g2, h2, x)
|
|
74
|
+
valid = DLEQProof.verify_non_interactive(self.group, g1, h1, g2, h2, proof)
|
|
75
|
+
results.append(valid)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
errors.append(str(e))
|
|
78
|
+
|
|
79
|
+
threads = [threading.Thread(target=prove_and_verify) for _ in range(self.num_threads)]
|
|
80
|
+
for t in threads:
|
|
81
|
+
t.start()
|
|
82
|
+
for t in threads:
|
|
83
|
+
t.join()
|
|
84
|
+
|
|
85
|
+
self.assertEqual(len(errors), 0, f"Errors occurred: {errors}")
|
|
86
|
+
self.assertEqual(len(results), self.num_threads * self.proofs_per_thread)
|
|
87
|
+
self.assertTrue(all(results), "All proofs should verify")
|
|
88
|
+
|
|
89
|
+
def test_representation_concurrent_prove_verify(self):
|
|
90
|
+
"""Test concurrent Representation proof generation and verification."""
|
|
91
|
+
results = []
|
|
92
|
+
errors = []
|
|
93
|
+
|
|
94
|
+
def prove_and_verify():
|
|
95
|
+
try:
|
|
96
|
+
g1 = self.group.random(G1)
|
|
97
|
+
g2 = self.group.random(G1)
|
|
98
|
+
x1 = self.group.random(ZR)
|
|
99
|
+
x2 = self.group.random(ZR)
|
|
100
|
+
h = (g1 ** x1) * (g2 ** x2)
|
|
101
|
+
|
|
102
|
+
for _ in range(self.proofs_per_thread):
|
|
103
|
+
proof = RepresentationProof.prove_non_interactive(
|
|
104
|
+
self.group, [g1, g2], h, [x1, x2]
|
|
105
|
+
)
|
|
106
|
+
valid = RepresentationProof.verify_non_interactive(
|
|
107
|
+
self.group, [g1, g2], h, proof
|
|
108
|
+
)
|
|
109
|
+
results.append(valid)
|
|
110
|
+
except Exception as e:
|
|
111
|
+
errors.append(str(e))
|
|
112
|
+
|
|
113
|
+
threads = [threading.Thread(target=prove_and_verify) for _ in range(self.num_threads)]
|
|
114
|
+
for t in threads:
|
|
115
|
+
t.start()
|
|
116
|
+
for t in threads:
|
|
117
|
+
t.join()
|
|
118
|
+
|
|
119
|
+
self.assertEqual(len(errors), 0, f"Errors occurred: {errors}")
|
|
120
|
+
self.assertEqual(len(results), self.num_threads * self.proofs_per_thread)
|
|
121
|
+
self.assertTrue(all(results), "All proofs should verify")
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class TestThreadSafeWrappers(unittest.TestCase):
|
|
125
|
+
"""Test thread-safe wrappers for interactive proofs."""
|
|
126
|
+
|
|
127
|
+
def setUp(self):
|
|
128
|
+
"""Set up test fixtures."""
|
|
129
|
+
self.group = PairingGroup('BN254')
|
|
130
|
+
|
|
131
|
+
def test_thread_safe_prover_context_manager(self):
|
|
132
|
+
"""Test ThreadSafeProver as context manager."""
|
|
133
|
+
x = self.group.random(ZR)
|
|
134
|
+
g = self.group.random(G1)
|
|
135
|
+
h = g ** x
|
|
136
|
+
|
|
137
|
+
prover = ThreadSafeProver(SchnorrProof.Prover(x, self.group))
|
|
138
|
+
verifier = SchnorrProof.Verifier(self.group)
|
|
139
|
+
|
|
140
|
+
with prover:
|
|
141
|
+
commitment = prover.create_commitment(g)
|
|
142
|
+
challenge = verifier.create_challenge()
|
|
143
|
+
response = prover.create_response(challenge)
|
|
144
|
+
|
|
145
|
+
result = verifier.verify(g, h, commitment, response)
|
|
146
|
+
self.assertTrue(result)
|
|
147
|
+
|
|
148
|
+
def test_thread_safe_verifier_context_manager(self):
|
|
149
|
+
"""Test ThreadSafeVerifier as context manager."""
|
|
150
|
+
x = self.group.random(ZR)
|
|
151
|
+
g = self.group.random(G1)
|
|
152
|
+
h = g ** x
|
|
153
|
+
|
|
154
|
+
prover = SchnorrProof.Prover(x, self.group)
|
|
155
|
+
verifier = ThreadSafeVerifier(SchnorrProof.Verifier(self.group))
|
|
156
|
+
|
|
157
|
+
commitment = prover.create_commitment(g)
|
|
158
|
+
|
|
159
|
+
with verifier:
|
|
160
|
+
challenge = verifier.create_challenge()
|
|
161
|
+
response = prover.create_response(challenge)
|
|
162
|
+
result = verifier.verify(g, h, commitment, response)
|
|
163
|
+
|
|
164
|
+
self.assertTrue(result)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
if __name__ == "__main__":
|
|
168
|
+
unittest.main()
|
|
169
|
+
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for the ZK statement parser.
|
|
3
|
+
|
|
4
|
+
Tests cover parsing of ZK statements, structure extraction, and error handling.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import unittest
|
|
8
|
+
from charm.zkp_compiler.zkparser import ZKParser
|
|
9
|
+
from charm.toolbox.zknode import BinNode
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestZKParser(unittest.TestCase):
|
|
13
|
+
"""Tests for ZK statement parser."""
|
|
14
|
+
|
|
15
|
+
def setUp(self):
|
|
16
|
+
self.parser = ZKParser()
|
|
17
|
+
|
|
18
|
+
def test_parse_simple_statement(self):
|
|
19
|
+
"""Test parsing 'h = g^x'."""
|
|
20
|
+
result = self.parser.parse("h = g^x")
|
|
21
|
+
self.assertIsNotNone(result)
|
|
22
|
+
self.assertEqual(result.type, BinNode(4).EQ) # EQ node
|
|
23
|
+
|
|
24
|
+
def test_parse_extracts_correct_structure(self):
|
|
25
|
+
"""Test that parsed tree has correct structure."""
|
|
26
|
+
result = self.parser.parse("h = g^x")
|
|
27
|
+
# h = g^x means: EQ(h, EXP(g, x))
|
|
28
|
+
# Left side is the variable name (string)
|
|
29
|
+
self.assertEqual(result.getLeft().upper(), 'H')
|
|
30
|
+
# Right side is the exponentiation BinNode
|
|
31
|
+
right = result.getRight()
|
|
32
|
+
self.assertEqual(right.type, BinNode(3).EXP)
|
|
33
|
+
|
|
34
|
+
def test_parse_multi_exponent_and(self):
|
|
35
|
+
"""Test parsing 'h = g^x AND j = g^y'.
|
|
36
|
+
|
|
37
|
+
Note: The ZKParser processes this but may return an EQ node
|
|
38
|
+
as the root depending on how AND is handled in the grammar.
|
|
39
|
+
This tests that the parse succeeds and returns a BinNode.
|
|
40
|
+
"""
|
|
41
|
+
result = self.parser.parse("h = g^x AND j = g^y")
|
|
42
|
+
self.assertIsNotNone(result)
|
|
43
|
+
self.assertIsInstance(result, BinNode)
|
|
44
|
+
# The parser may return EQ (4) at the root level for this grammar
|
|
45
|
+
# We just verify it's a valid BinNode type
|
|
46
|
+
self.assertIn(result.type, [BinNode(2).AND, BinNode(4).EQ])
|
|
47
|
+
|
|
48
|
+
def test_parse_preserves_variable_names(self):
|
|
49
|
+
"""Test that variable names are preserved (uppercased)."""
|
|
50
|
+
result = self.parser.parse("h = g^x")
|
|
51
|
+
# The left of EQ should be 'H'
|
|
52
|
+
self.assertEqual(result.getLeft().upper(), 'H')
|
|
53
|
+
|
|
54
|
+
def test_parse_empty_string_fails(self):
|
|
55
|
+
"""Test that empty string raises exception."""
|
|
56
|
+
with self.assertRaises(Exception):
|
|
57
|
+
self.parser.parse("")
|
|
58
|
+
|
|
59
|
+
def test_parse_invalid_syntax_fails(self):
|
|
60
|
+
"""Test that completely unparseable syntax raises exception.
|
|
61
|
+
|
|
62
|
+
Note: The parser is lenient and may accept partial matches.
|
|
63
|
+
We test with symbols that cannot match any grammar rules.
|
|
64
|
+
"""
|
|
65
|
+
with self.assertRaises(Exception):
|
|
66
|
+
# Use symbols that cannot be parsed at all
|
|
67
|
+
self.parser.parse("@@@ ### $$$")
|
|
68
|
+
|
|
69
|
+
def test_node_structure_access(self):
|
|
70
|
+
"""Test that we can access node structure correctly."""
|
|
71
|
+
result = self.parser.parse("h = g^x")
|
|
72
|
+
# Right side is a BinNode (EXP node)
|
|
73
|
+
right = result.getRight()
|
|
74
|
+
self.assertIsInstance(right, BinNode)
|
|
75
|
+
# Check that we can access the EXP node's children
|
|
76
|
+
# The EXP node has left='G' and right='X' as strings
|
|
77
|
+
self.assertIsNotNone(right.getLeft())
|
|
78
|
+
self.assertIsNotNone(right.getRight())
|
|
79
|
+
|
|
80
|
+
def test_result_is_binnode(self):
|
|
81
|
+
"""Test that parser returns a BinNode."""
|
|
82
|
+
result = self.parser.parse("h = g^x")
|
|
83
|
+
self.assertIsInstance(result, BinNode)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class TestZKParserMultiCharVariables(unittest.TestCase):
|
|
87
|
+
"""Tests for multi-character variable name support (new in v0.61)."""
|
|
88
|
+
|
|
89
|
+
def setUp(self):
|
|
90
|
+
self.parser = ZKParser()
|
|
91
|
+
|
|
92
|
+
def test_parse_numbered_variables(self):
|
|
93
|
+
"""Test parsing with numbered variables like x1, g1, h1."""
|
|
94
|
+
result = self.parser.parse("h1 = g1^x1")
|
|
95
|
+
self.assertIsNotNone(result)
|
|
96
|
+
self.assertIsInstance(result, BinNode)
|
|
97
|
+
self.assertEqual(result.type, BinNode(4).EQ)
|
|
98
|
+
|
|
99
|
+
def test_parse_descriptive_variable_names(self):
|
|
100
|
+
"""Test parsing with descriptive variable names."""
|
|
101
|
+
result = self.parser.parse("commitment = generator^secret")
|
|
102
|
+
self.assertIsNotNone(result)
|
|
103
|
+
self.assertIsInstance(result, BinNode)
|
|
104
|
+
self.assertEqual(result.type, BinNode(4).EQ)
|
|
105
|
+
|
|
106
|
+
def test_parse_greek_letter_names(self):
|
|
107
|
+
"""Test parsing with Greek letter-style names."""
|
|
108
|
+
result = self.parser.parse("gamma = alpha^beta")
|
|
109
|
+
self.assertIsNotNone(result)
|
|
110
|
+
self.assertIsInstance(result, BinNode)
|
|
111
|
+
|
|
112
|
+
def test_parse_mixed_length_variables(self):
|
|
113
|
+
"""Test parsing with mixed single and multi-char variables."""
|
|
114
|
+
result = self.parser.parse("h = generator^x")
|
|
115
|
+
self.assertIsNotNone(result)
|
|
116
|
+
self.assertIsInstance(result, BinNode)
|
|
117
|
+
|
|
118
|
+
def test_parse_complex_multi_char_statement(self):
|
|
119
|
+
"""Test parsing complex statement with multi-char variables."""
|
|
120
|
+
result = self.parser.parse("pk1 = g^sk1 AND pk2 = g^sk2")
|
|
121
|
+
self.assertIsNotNone(result)
|
|
122
|
+
self.assertIsInstance(result, BinNode)
|
|
123
|
+
|
|
124
|
+
def test_multi_char_preserves_variable_names(self):
|
|
125
|
+
"""Test that multi-char variable names are preserved."""
|
|
126
|
+
result = self.parser.parse("commitment = generator^secret")
|
|
127
|
+
# The left of EQ should be 'COMMITMENT' (uppercased)
|
|
128
|
+
self.assertEqual(result.getLeft().upper(), 'COMMITMENT')
|
|
129
|
+
|
|
130
|
+
def test_backwards_compatible_single_char(self):
|
|
131
|
+
"""Test that single-char variables still work (backwards compatibility)."""
|
|
132
|
+
result = self.parser.parse("h = g^x")
|
|
133
|
+
self.assertIsNotNone(result)
|
|
134
|
+
self.assertEqual(result.getLeft().upper(), 'H')
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
if __name__ == "__main__":
|
|
138
|
+
unittest.main()
|
|
139
|
+
|
charm/toolbox/ABEnc.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
''' Base class for attribute-based encryption
|
|
2
|
+
|
|
3
|
+
Notes: This class implements an interface for a standard attribute-based encryption scheme.
|
|
4
|
+
|
|
5
|
+
A public key attribute-based encryption scheme consists of four algorithms:
|
|
6
|
+
(setup, keygen, encrypt, decrypt).
|
|
7
|
+
'''
|
|
8
|
+
from charm.toolbox.schemebase import *
|
|
9
|
+
|
|
10
|
+
class ABEnc(SchemeBase):
|
|
11
|
+
def __init__(self):
|
|
12
|
+
SchemeBase.__init__(self)
|
|
13
|
+
SchemeBase._setProperty(self, scheme='ABEnc')
|
|
14
|
+
self.baseSecDefs = Enum('IND_AB_CPA', 'IND_AB_CCA', 'sIND_AB_CPA', 'sIND_AB_CCA')
|
|
15
|
+
|
|
16
|
+
def setup(self):
|
|
17
|
+
raise NotImplementedError
|
|
18
|
+
|
|
19
|
+
def keygen(self, pk, mk, object):
|
|
20
|
+
raise NotImplementedError
|
|
21
|
+
|
|
22
|
+
def encrypt(self, pk, M, object):
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
|
|
25
|
+
def decrypt(self, pk, sk, ct):
|
|
26
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from charm.toolbox.schemebase import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ABEncMultiAuth(SchemeBase):
|
|
5
|
+
"""
|
|
6
|
+
Base class for attribute-based encryption multi-authority
|
|
7
|
+
|
|
8
|
+
Notes: This class implements an interface for a standard attribute-based encryption scheme.
|
|
9
|
+
|
|
10
|
+
A public key attribute-based encryption scheme consists of four algorithms:
|
|
11
|
+
(setup, authsetup, keygen, encrypt, decrypt).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
SchemeBase.__init__(self)
|
|
16
|
+
SchemeBase._setProperty(self, scheme='ABEncMultiAuth')
|
|
17
|
+
self.baseSecDefs = None
|
|
18
|
+
|
|
19
|
+
def setup(self):
|
|
20
|
+
"""
|
|
21
|
+
Setup this multi-authority attribute based encryption scheme.
|
|
22
|
+
:return: The result of the central setup, for example some global parameters.
|
|
23
|
+
"""
|
|
24
|
+
raise NotImplementedError
|
|
25
|
+
|
|
26
|
+
def authsetup(self, gp, object):
|
|
27
|
+
"""
|
|
28
|
+
Setup an authority.
|
|
29
|
+
:param gp: The global parameters of the scheme.
|
|
30
|
+
:param object: Additional required arguments, for example a list of attributes or a name.
|
|
31
|
+
:return: The result of the authority setup.
|
|
32
|
+
"""
|
|
33
|
+
raise NotImplementedError
|
|
34
|
+
|
|
35
|
+
def keygen(self, gp, sk, gid, object):
|
|
36
|
+
"""
|
|
37
|
+
Generate user secret keys for attributes from a single authority.
|
|
38
|
+
:param gp: The global parameters of the scheme.
|
|
39
|
+
:param sk: The secret keys of the attribute authority.
|
|
40
|
+
:param gid: Global identifier for the user.
|
|
41
|
+
:param object: An attribute, list of attributes or access structure, depending on the scheme.
|
|
42
|
+
:return: The secret keys for the user for the given attributes/access structure.
|
|
43
|
+
"""
|
|
44
|
+
raise NotImplementedError
|
|
45
|
+
|
|
46
|
+
def encrypt(self, gp, pk, m, object):
|
|
47
|
+
"""
|
|
48
|
+
Encrypt a message.
|
|
49
|
+
:param gp: The global parameters of the scheme.
|
|
50
|
+
:param pk: The public keys of all relevant authorities.
|
|
51
|
+
:param m: The message to encrypt.
|
|
52
|
+
:param object: An access policy or a set of attributes to use.
|
|
53
|
+
:return: The encrypted message.
|
|
54
|
+
"""
|
|
55
|
+
raise NotImplementedError
|
|
56
|
+
|
|
57
|
+
def decrypt(self, gp, sk, ct):
|
|
58
|
+
"""
|
|
59
|
+
Decrypt a ciphertext.
|
|
60
|
+
:param gp: The global parameters of the scheme.
|
|
61
|
+
:param sk: The secret keys of the user.
|
|
62
|
+
:param ct: The ciphertext to decrypt.
|
|
63
|
+
:return: The plaintext.
|
|
64
|
+
:raise Exception: Raised when the attributes do not satisfy the access policy.
|
|
65
|
+
"""
|
|
66
|
+
raise NotImplementedError
|