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,248 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for batch verification implementation.
|
|
3
|
+
|
|
4
|
+
Tests cover:
|
|
5
|
+
- Batch verification of Schnorr proofs
|
|
6
|
+
- Batch verification of DLEQ proofs
|
|
7
|
+
- BatchVerifier class functionality
|
|
8
|
+
- Performance comparison with individual verification
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import unittest
|
|
12
|
+
import time
|
|
13
|
+
from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
|
|
14
|
+
from charm.zkp_compiler.schnorr_proof import SchnorrProof, Proof
|
|
15
|
+
from charm.zkp_compiler.dleq_proof import DLEQProof, DLEQProofData
|
|
16
|
+
from charm.zkp_compiler.batch_verify import BatchVerifier, batch_verify_schnorr, batch_verify_dleq
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestBatchVerifySchnorr(unittest.TestCase):
|
|
20
|
+
"""Tests for batch verification of Schnorr proofs."""
|
|
21
|
+
|
|
22
|
+
def setUp(self):
|
|
23
|
+
"""Set up test fixtures."""
|
|
24
|
+
self.group = PairingGroup('BN254')
|
|
25
|
+
self.g = self.group.random(G1)
|
|
26
|
+
|
|
27
|
+
def _create_valid_schnorr_proof(self):
|
|
28
|
+
"""Helper to create a valid Schnorr proof."""
|
|
29
|
+
x = self.group.random(ZR)
|
|
30
|
+
h = self.g ** x
|
|
31
|
+
proof = SchnorrProof.prove_non_interactive(self.group, self.g, h, x)
|
|
32
|
+
return {'g': self.g, 'h': h, 'proof': proof}
|
|
33
|
+
|
|
34
|
+
def _create_invalid_schnorr_proof(self):
|
|
35
|
+
"""Helper to create an invalid Schnorr proof (wrong secret)."""
|
|
36
|
+
x = self.group.random(ZR)
|
|
37
|
+
wrong_x = self.group.random(ZR)
|
|
38
|
+
h = self.g ** x
|
|
39
|
+
proof = SchnorrProof.prove_non_interactive(self.group, self.g, h, wrong_x)
|
|
40
|
+
return {'g': self.g, 'h': h, 'proof': proof}
|
|
41
|
+
|
|
42
|
+
def test_batch_verify_all_valid(self):
|
|
43
|
+
"""Test that all valid proofs pass batch verification."""
|
|
44
|
+
proofs_data = [self._create_valid_schnorr_proof() for _ in range(5)]
|
|
45
|
+
result = batch_verify_schnorr(self.group, proofs_data)
|
|
46
|
+
self.assertTrue(result)
|
|
47
|
+
|
|
48
|
+
def test_batch_verify_one_invalid(self):
|
|
49
|
+
"""Test that one invalid proof fails entire batch."""
|
|
50
|
+
proofs_data = [self._create_valid_schnorr_proof() for _ in range(4)]
|
|
51
|
+
proofs_data.append(self._create_invalid_schnorr_proof())
|
|
52
|
+
result = batch_verify_schnorr(self.group, proofs_data)
|
|
53
|
+
self.assertFalse(result)
|
|
54
|
+
|
|
55
|
+
def test_batch_verify_empty(self):
|
|
56
|
+
"""Test that empty batch returns True (vacuously true)."""
|
|
57
|
+
result = batch_verify_schnorr(self.group, [])
|
|
58
|
+
self.assertTrue(result)
|
|
59
|
+
|
|
60
|
+
def test_batch_verify_single(self):
|
|
61
|
+
"""Test that single proof batch works."""
|
|
62
|
+
proofs_data = [self._create_valid_schnorr_proof()]
|
|
63
|
+
result = batch_verify_schnorr(self.group, proofs_data)
|
|
64
|
+
self.assertTrue(result)
|
|
65
|
+
|
|
66
|
+
def test_batch_verify_many(self):
|
|
67
|
+
"""Test that 10+ proofs batch works."""
|
|
68
|
+
proofs_data = [self._create_valid_schnorr_proof() for _ in range(12)]
|
|
69
|
+
result = batch_verify_schnorr(self.group, proofs_data)
|
|
70
|
+
self.assertTrue(result)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class TestBatchVerifyDLEQ(unittest.TestCase):
|
|
74
|
+
"""Tests for batch verification of DLEQ proofs."""
|
|
75
|
+
|
|
76
|
+
def setUp(self):
|
|
77
|
+
"""Set up test fixtures."""
|
|
78
|
+
self.group = PairingGroup('BN254')
|
|
79
|
+
self.g1 = self.group.random(G1)
|
|
80
|
+
self.g2 = self.group.random(G1)
|
|
81
|
+
|
|
82
|
+
def _create_valid_dleq_proof(self):
|
|
83
|
+
"""Helper to create a valid DLEQ proof."""
|
|
84
|
+
x = self.group.random(ZR)
|
|
85
|
+
h1 = self.g1 ** x
|
|
86
|
+
h2 = self.g2 ** x
|
|
87
|
+
proof = DLEQProof.prove_non_interactive(self.group, self.g1, h1, self.g2, h2, x)
|
|
88
|
+
return {'g1': self.g1, 'h1': h1, 'g2': self.g2, 'h2': h2, 'proof': proof}
|
|
89
|
+
|
|
90
|
+
def _create_invalid_dleq_proof(self):
|
|
91
|
+
"""Helper to create an invalid DLEQ proof (wrong secret)."""
|
|
92
|
+
x = self.group.random(ZR)
|
|
93
|
+
wrong_x = self.group.random(ZR)
|
|
94
|
+
h1 = self.g1 ** x
|
|
95
|
+
h2 = self.g2 ** x
|
|
96
|
+
proof = DLEQProof.prove_non_interactive(self.group, self.g1, h1, self.g2, h2, wrong_x)
|
|
97
|
+
return {'g1': self.g1, 'h1': h1, 'g2': self.g2, 'h2': h2, 'proof': proof}
|
|
98
|
+
|
|
99
|
+
def test_batch_verify_all_valid(self):
|
|
100
|
+
"""Test that all valid DLEQ proofs pass batch verification."""
|
|
101
|
+
proofs_data = [self._create_valid_dleq_proof() for _ in range(5)]
|
|
102
|
+
result = batch_verify_dleq(self.group, proofs_data)
|
|
103
|
+
self.assertTrue(result)
|
|
104
|
+
|
|
105
|
+
def test_batch_verify_one_invalid(self):
|
|
106
|
+
"""Test that one invalid DLEQ proof fails entire batch."""
|
|
107
|
+
proofs_data = [self._create_valid_dleq_proof() for _ in range(4)]
|
|
108
|
+
proofs_data.append(self._create_invalid_dleq_proof())
|
|
109
|
+
result = batch_verify_dleq(self.group, proofs_data)
|
|
110
|
+
self.assertFalse(result)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class TestBatchVerifierClass(unittest.TestCase):
|
|
114
|
+
"""Tests for BatchVerifier class functionality."""
|
|
115
|
+
|
|
116
|
+
def setUp(self):
|
|
117
|
+
"""Set up test fixtures."""
|
|
118
|
+
self.group = PairingGroup('BN254')
|
|
119
|
+
self.g = self.group.random(G1)
|
|
120
|
+
self.g1 = self.group.random(G1)
|
|
121
|
+
self.g2 = self.group.random(G1)
|
|
122
|
+
|
|
123
|
+
def test_add_and_verify_schnorr(self):
|
|
124
|
+
"""Test adding Schnorr proofs and verifying."""
|
|
125
|
+
verifier = BatchVerifier(self.group)
|
|
126
|
+
|
|
127
|
+
for _ in range(3):
|
|
128
|
+
x = self.group.random(ZR)
|
|
129
|
+
h = self.g ** x
|
|
130
|
+
proof = SchnorrProof.prove_non_interactive(self.group, self.g, h, x)
|
|
131
|
+
verifier.add_schnorr_proof(self.g, h, proof)
|
|
132
|
+
|
|
133
|
+
result = verifier.verify_all()
|
|
134
|
+
self.assertTrue(result)
|
|
135
|
+
|
|
136
|
+
def test_add_and_verify_dleq(self):
|
|
137
|
+
"""Test adding DLEQ proofs and verifying."""
|
|
138
|
+
verifier = BatchVerifier(self.group)
|
|
139
|
+
|
|
140
|
+
for _ in range(3):
|
|
141
|
+
x = self.group.random(ZR)
|
|
142
|
+
h1 = self.g1 ** x
|
|
143
|
+
h2 = self.g2 ** x
|
|
144
|
+
proof = DLEQProof.prove_non_interactive(self.group, self.g1, h1, self.g2, h2, x)
|
|
145
|
+
verifier.add_dleq_proof(self.g1, h1, self.g2, h2, proof)
|
|
146
|
+
|
|
147
|
+
result = verifier.verify_all()
|
|
148
|
+
self.assertTrue(result)
|
|
149
|
+
|
|
150
|
+
def test_mixed_proof_types(self):
|
|
151
|
+
"""Test mixing Schnorr and DLEQ proofs in same batch."""
|
|
152
|
+
verifier = BatchVerifier(self.group)
|
|
153
|
+
|
|
154
|
+
# Add Schnorr proofs
|
|
155
|
+
for _ in range(2):
|
|
156
|
+
x = self.group.random(ZR)
|
|
157
|
+
h = self.g ** x
|
|
158
|
+
proof = SchnorrProof.prove_non_interactive(self.group, self.g, h, x)
|
|
159
|
+
verifier.add_schnorr_proof(self.g, h, proof)
|
|
160
|
+
|
|
161
|
+
# Add DLEQ proofs
|
|
162
|
+
for _ in range(2):
|
|
163
|
+
x = self.group.random(ZR)
|
|
164
|
+
h1 = self.g1 ** x
|
|
165
|
+
h2 = self.g2 ** x
|
|
166
|
+
proof = DLEQProof.prove_non_interactive(self.group, self.g1, h1, self.g2, h2, x)
|
|
167
|
+
verifier.add_dleq_proof(self.g1, h1, self.g2, h2, proof)
|
|
168
|
+
|
|
169
|
+
result = verifier.verify_all()
|
|
170
|
+
self.assertTrue(result)
|
|
171
|
+
|
|
172
|
+
def test_clear_batch(self):
|
|
173
|
+
"""Test clearing and reusing verifier."""
|
|
174
|
+
verifier = BatchVerifier(self.group)
|
|
175
|
+
|
|
176
|
+
# Add a valid proof
|
|
177
|
+
x = self.group.random(ZR)
|
|
178
|
+
h = self.g ** x
|
|
179
|
+
proof = SchnorrProof.prove_non_interactive(self.group, self.g, h, x)
|
|
180
|
+
verifier.add_schnorr_proof(self.g, h, proof)
|
|
181
|
+
|
|
182
|
+
# Verify first batch
|
|
183
|
+
self.assertTrue(verifier.verify_all())
|
|
184
|
+
|
|
185
|
+
# Clear the verifier
|
|
186
|
+
verifier.clear()
|
|
187
|
+
|
|
188
|
+
# Add new proofs
|
|
189
|
+
for _ in range(2):
|
|
190
|
+
x = self.group.random(ZR)
|
|
191
|
+
h = self.g ** x
|
|
192
|
+
proof = SchnorrProof.prove_non_interactive(self.group, self.g, h, x)
|
|
193
|
+
verifier.add_schnorr_proof(self.g, h, proof)
|
|
194
|
+
|
|
195
|
+
# Verify second batch
|
|
196
|
+
result = verifier.verify_all()
|
|
197
|
+
self.assertTrue(result)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class TestBatchVerifyPerformance(unittest.TestCase):
|
|
201
|
+
"""Tests for batch verification performance."""
|
|
202
|
+
|
|
203
|
+
def setUp(self):
|
|
204
|
+
"""Set up test fixtures."""
|
|
205
|
+
self.group = PairingGroup('BN254')
|
|
206
|
+
self.g = self.group.random(G1)
|
|
207
|
+
|
|
208
|
+
def test_batch_faster_than_individual(self):
|
|
209
|
+
"""Test that batch verification is not slower than individual verification."""
|
|
210
|
+
num_proofs = 10
|
|
211
|
+
proofs_data = []
|
|
212
|
+
|
|
213
|
+
# Generate proofs
|
|
214
|
+
for _ in range(num_proofs):
|
|
215
|
+
x = self.group.random(ZR)
|
|
216
|
+
h = self.g ** x
|
|
217
|
+
proof = SchnorrProof.prove_non_interactive(self.group, self.g, h, x)
|
|
218
|
+
proofs_data.append({'g': self.g, 'h': h, 'proof': proof})
|
|
219
|
+
|
|
220
|
+
# Time individual verification
|
|
221
|
+
start_individual = time.time()
|
|
222
|
+
for data in proofs_data:
|
|
223
|
+
SchnorrProof.verify_non_interactive(
|
|
224
|
+
self.group, data['g'], data['h'], data['proof']
|
|
225
|
+
)
|
|
226
|
+
time_individual = time.time() - start_individual
|
|
227
|
+
|
|
228
|
+
# Time batch verification
|
|
229
|
+
start_batch = time.time()
|
|
230
|
+
result = batch_verify_schnorr(self.group, proofs_data)
|
|
231
|
+
time_batch = time.time() - start_batch
|
|
232
|
+
|
|
233
|
+
# Batch verification should work
|
|
234
|
+
self.assertTrue(result)
|
|
235
|
+
|
|
236
|
+
# Batch should ideally be faster (or at least not significantly slower)
|
|
237
|
+
# Allow generous tolerance for timing variations in CI environments
|
|
238
|
+
# We just check that batch works, not strict performance guarantees
|
|
239
|
+
# as performance may vary based on system load
|
|
240
|
+
# Using 3x multiplier to account for CI timing variability
|
|
241
|
+
self.assertLessEqual(time_batch, time_individual * 3 + 0.01,
|
|
242
|
+
f"Batch ({time_batch:.4f}s) should not be significantly "
|
|
243
|
+
f"slower than individual ({time_individual:.4f}s)")
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
if __name__ == "__main__":
|
|
247
|
+
unittest.main()
|
|
248
|
+
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for DLEQ (Discrete Log Equality) ZK proof implementation.
|
|
3
|
+
|
|
4
|
+
Tests cover:
|
|
5
|
+
- Interactive proof protocol
|
|
6
|
+
- Non-interactive (Fiat-Shamir) proof
|
|
7
|
+
- Serialization and deserialization
|
|
8
|
+
- Different pairing groups
|
|
9
|
+
- Edge cases and error handling
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import unittest
|
|
13
|
+
from charm.toolbox.pairinggroup import PairingGroup, ZR, G1
|
|
14
|
+
from charm.zkp_compiler.dleq_proof import DLEQProof, DLEQProofData
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TestDLEQProofInteractive(unittest.TestCase):
|
|
18
|
+
"""Tests for interactive DLEQ protocol."""
|
|
19
|
+
|
|
20
|
+
def setUp(self):
|
|
21
|
+
"""Set up test fixtures."""
|
|
22
|
+
self.group = PairingGroup('BN254')
|
|
23
|
+
self.g1 = self.group.random(G1)
|
|
24
|
+
self.g2 = self.group.random(G1)
|
|
25
|
+
self.x = self.group.random(ZR)
|
|
26
|
+
self.h1 = self.g1 ** self.x
|
|
27
|
+
self.h2 = self.g2 ** self.x
|
|
28
|
+
|
|
29
|
+
def test_prove_and_verify_interactive(self):
|
|
30
|
+
"""Test complete interactive proof cycle."""
|
|
31
|
+
# Create prover and verifier
|
|
32
|
+
prover = DLEQProof.Prover(self.x, self.group)
|
|
33
|
+
verifier = DLEQProof.Verifier(self.group)
|
|
34
|
+
|
|
35
|
+
# Step 1: Prover creates commitments
|
|
36
|
+
commitment1, commitment2 = prover.create_commitment(self.g1, self.g2)
|
|
37
|
+
self.assertIsNotNone(commitment1)
|
|
38
|
+
self.assertIsNotNone(commitment2)
|
|
39
|
+
|
|
40
|
+
# Step 2: Verifier creates challenge
|
|
41
|
+
challenge = verifier.create_challenge()
|
|
42
|
+
self.assertIsNotNone(challenge)
|
|
43
|
+
|
|
44
|
+
# Step 3: Prover creates response
|
|
45
|
+
response = prover.create_response(challenge)
|
|
46
|
+
self.assertIsNotNone(response)
|
|
47
|
+
|
|
48
|
+
# Step 4: Verifier verifies
|
|
49
|
+
result = verifier.verify(
|
|
50
|
+
self.g1, self.h1, self.g2, self.h2, commitment1, commitment2, response
|
|
51
|
+
)
|
|
52
|
+
self.assertTrue(result)
|
|
53
|
+
|
|
54
|
+
def test_invalid_proof_fails_interactive(self):
|
|
55
|
+
"""Test that wrong secret fails verification."""
|
|
56
|
+
wrong_x = self.group.random(ZR)
|
|
57
|
+
prover = DLEQProof.Prover(wrong_x, self.group)
|
|
58
|
+
verifier = DLEQProof.Verifier(self.group)
|
|
59
|
+
|
|
60
|
+
commitment1, commitment2 = prover.create_commitment(self.g1, self.g2)
|
|
61
|
+
challenge = verifier.create_challenge()
|
|
62
|
+
response = prover.create_response(challenge)
|
|
63
|
+
|
|
64
|
+
# Should fail because wrong secret
|
|
65
|
+
result = verifier.verify(
|
|
66
|
+
self.g1, self.h1, self.g2, self.h2, commitment1, commitment2, response
|
|
67
|
+
)
|
|
68
|
+
self.assertFalse(result)
|
|
69
|
+
|
|
70
|
+
def test_prover_commitment_before_response(self):
|
|
71
|
+
"""Test that prover must create commitment before response."""
|
|
72
|
+
prover = DLEQProof.Prover(self.x, self.group)
|
|
73
|
+
|
|
74
|
+
# Try to create response without commitment
|
|
75
|
+
with self.assertRaises(ValueError):
|
|
76
|
+
prover.create_response(self.group.random(ZR))
|
|
77
|
+
|
|
78
|
+
def test_different_exponents_fail(self):
|
|
79
|
+
"""Test that using different x for h1 and h2 should fail."""
|
|
80
|
+
x1 = self.group.random(ZR)
|
|
81
|
+
x2 = self.group.random(ZR)
|
|
82
|
+
h1_wrong = self.g1 ** x1
|
|
83
|
+
h2_wrong = self.g2 ** x2
|
|
84
|
+
|
|
85
|
+
# Prover knows x1 but tries to prove h1 = g1^x1 AND h2 = g2^x1
|
|
86
|
+
# But h2 = g2^x2 (not g2^x1), so verification should fail
|
|
87
|
+
prover = DLEQProof.Prover(x1, self.group)
|
|
88
|
+
verifier = DLEQProof.Verifier(self.group)
|
|
89
|
+
|
|
90
|
+
commitment1, commitment2 = prover.create_commitment(self.g1, self.g2)
|
|
91
|
+
challenge = verifier.create_challenge()
|
|
92
|
+
response = prover.create_response(challenge)
|
|
93
|
+
|
|
94
|
+
result = verifier.verify(
|
|
95
|
+
self.g1, h1_wrong, self.g2, h2_wrong, commitment1, commitment2, response
|
|
96
|
+
)
|
|
97
|
+
self.assertFalse(result)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class TestDLEQProofNonInteractive(unittest.TestCase):
|
|
101
|
+
"""Tests for non-interactive (Fiat-Shamir) DLEQ proof."""
|
|
102
|
+
|
|
103
|
+
def setUp(self):
|
|
104
|
+
"""Set up test fixtures."""
|
|
105
|
+
self.group = PairingGroup('BN254')
|
|
106
|
+
self.g1 = self.group.random(G1)
|
|
107
|
+
self.g2 = self.group.random(G1)
|
|
108
|
+
self.x = self.group.random(ZR)
|
|
109
|
+
self.h1 = self.g1 ** self.x
|
|
110
|
+
self.h2 = self.g2 ** self.x
|
|
111
|
+
|
|
112
|
+
def test_non_interactive_proof_valid(self):
|
|
113
|
+
"""Test Fiat-Shamir transformed proof."""
|
|
114
|
+
proof = DLEQProof.prove_non_interactive(
|
|
115
|
+
self.group, self.g1, self.h1, self.g2, self.h2, self.x
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
self.assertIsNotNone(proof)
|
|
119
|
+
self.assertIsNotNone(proof.commitment1)
|
|
120
|
+
self.assertIsNotNone(proof.commitment2)
|
|
121
|
+
self.assertIsNotNone(proof.challenge)
|
|
122
|
+
self.assertIsNotNone(proof.response)
|
|
123
|
+
|
|
124
|
+
result = DLEQProof.verify_non_interactive(
|
|
125
|
+
self.group, self.g1, self.h1, self.g2, self.h2, proof
|
|
126
|
+
)
|
|
127
|
+
self.assertTrue(result)
|
|
128
|
+
|
|
129
|
+
def test_non_interactive_wrong_secret_fails(self):
|
|
130
|
+
"""Test that wrong secret fails non-interactive verification."""
|
|
131
|
+
wrong_x = self.group.random(ZR)
|
|
132
|
+
proof = DLEQProof.prove_non_interactive(
|
|
133
|
+
self.group, self.g1, self.h1, self.g2, self.h2, wrong_x
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
result = DLEQProof.verify_non_interactive(
|
|
137
|
+
self.group, self.g1, self.h1, self.g2, self.h2, proof
|
|
138
|
+
)
|
|
139
|
+
self.assertFalse(result)
|
|
140
|
+
|
|
141
|
+
def test_non_interactive_tampered_proof_fails(self):
|
|
142
|
+
"""Test that tampered proof fails verification."""
|
|
143
|
+
proof = DLEQProof.prove_non_interactive(
|
|
144
|
+
self.group, self.g1, self.h1, self.g2, self.h2, self.x
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# Tamper with the response
|
|
148
|
+
tampered = DLEQProofData(
|
|
149
|
+
commitment1=proof.commitment1,
|
|
150
|
+
commitment2=proof.commitment2,
|
|
151
|
+
challenge=proof.challenge,
|
|
152
|
+
response=proof.response + self.group.random(ZR),
|
|
153
|
+
proof_type=proof.proof_type
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
result = DLEQProof.verify_non_interactive(
|
|
157
|
+
self.group, self.g1, self.h1, self.g2, self.h2, tampered
|
|
158
|
+
)
|
|
159
|
+
self.assertFalse(result)
|
|
160
|
+
|
|
161
|
+
def test_proof_deterministic_verification(self):
|
|
162
|
+
"""Test that same proof verifies consistently."""
|
|
163
|
+
proof = DLEQProof.prove_non_interactive(
|
|
164
|
+
self.group, self.g1, self.h1, self.g2, self.h2, self.x
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Verify multiple times
|
|
168
|
+
for _ in range(5):
|
|
169
|
+
result = DLEQProof.verify_non_interactive(
|
|
170
|
+
self.group, self.g1, self.h1, self.g2, self.h2, proof
|
|
171
|
+
)
|
|
172
|
+
self.assertTrue(result)
|
|
173
|
+
|
|
174
|
+
def test_mismatched_bases_fail(self):
|
|
175
|
+
"""Test that h1 = g1^x but h2 = g2^y (different exponents) should fail."""
|
|
176
|
+
x = self.group.random(ZR)
|
|
177
|
+
y = self.group.random(ZR)
|
|
178
|
+
h1 = self.g1 ** x
|
|
179
|
+
h2 = self.g2 ** y
|
|
180
|
+
|
|
181
|
+
# Try to prove with x, but h2 was computed with different y
|
|
182
|
+
proof = DLEQProof.prove_non_interactive(
|
|
183
|
+
self.group, self.g1, h1, self.g2, h2, x
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
result = DLEQProof.verify_non_interactive(
|
|
187
|
+
self.group, self.g1, h1, self.g2, h2, proof
|
|
188
|
+
)
|
|
189
|
+
self.assertFalse(result)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class TestDLEQProofSerialization(unittest.TestCase):
|
|
193
|
+
"""Tests for DLEQ proof serialization."""
|
|
194
|
+
|
|
195
|
+
def setUp(self):
|
|
196
|
+
"""Set up test fixtures."""
|
|
197
|
+
self.group = PairingGroup('BN254')
|
|
198
|
+
self.g1 = self.group.random(G1)
|
|
199
|
+
self.g2 = self.group.random(G1)
|
|
200
|
+
self.x = self.group.random(ZR)
|
|
201
|
+
self.h1 = self.g1 ** self.x
|
|
202
|
+
self.h2 = self.g2 ** self.x
|
|
203
|
+
|
|
204
|
+
def test_serialization_roundtrip(self):
|
|
205
|
+
"""Test serialize and deserialize proof."""
|
|
206
|
+
proof = DLEQProof.prove_non_interactive(
|
|
207
|
+
self.group, self.g1, self.h1, self.g2, self.h2, self.x
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
# Serialize
|
|
211
|
+
serialized = DLEQProof.serialize_proof(proof, self.group)
|
|
212
|
+
self.assertIsInstance(serialized, bytes)
|
|
213
|
+
self.assertGreater(len(serialized), 0)
|
|
214
|
+
|
|
215
|
+
# Deserialize
|
|
216
|
+
deserialized = DLEQProof.deserialize_proof(serialized, self.group)
|
|
217
|
+
self.assertIsNotNone(deserialized)
|
|
218
|
+
self.assertEqual(deserialized.proof_type, proof.proof_type)
|
|
219
|
+
|
|
220
|
+
def test_serialized_proof_verifies(self):
|
|
221
|
+
"""Test that deserialized proof still verifies."""
|
|
222
|
+
proof = DLEQProof.prove_non_interactive(
|
|
223
|
+
self.group, self.g1, self.h1, self.g2, self.h2, self.x
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# Serialize and deserialize
|
|
227
|
+
serialized = DLEQProof.serialize_proof(proof, self.group)
|
|
228
|
+
deserialized = DLEQProof.deserialize_proof(serialized, self.group)
|
|
229
|
+
|
|
230
|
+
# Verify the deserialized proof
|
|
231
|
+
result = DLEQProof.verify_non_interactive(
|
|
232
|
+
self.group, self.g1, self.h1, self.g2, self.h2, deserialized
|
|
233
|
+
)
|
|
234
|
+
self.assertTrue(result)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class TestDLEQProofWithDifferentGroups(unittest.TestCase):
|
|
238
|
+
"""Test DLEQ proofs with different pairing groups."""
|
|
239
|
+
|
|
240
|
+
def test_with_bn254_group(self):
|
|
241
|
+
"""Test with BN254 pairing group."""
|
|
242
|
+
self._test_with_group('BN254')
|
|
243
|
+
|
|
244
|
+
def test_with_mnt224_group(self):
|
|
245
|
+
"""Test with MNT224 pairing group."""
|
|
246
|
+
self._test_with_group('MNT224')
|
|
247
|
+
|
|
248
|
+
def _test_with_group(self, curve_name):
|
|
249
|
+
"""Helper to test with a specific group."""
|
|
250
|
+
group = PairingGroup(curve_name)
|
|
251
|
+
g1 = group.random(G1)
|
|
252
|
+
g2 = group.random(G1)
|
|
253
|
+
x = group.random(ZR)
|
|
254
|
+
h1 = g1 ** x
|
|
255
|
+
h2 = g2 ** x
|
|
256
|
+
|
|
257
|
+
proof = DLEQProof.prove_non_interactive(group, g1, h1, g2, h2, x)
|
|
258
|
+
result = DLEQProof.verify_non_interactive(group, g1, h1, g2, h2, proof)
|
|
259
|
+
self.assertTrue(result)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
if __name__ == "__main__":
|
|
263
|
+
unittest.main()
|
|
264
|
+
|