use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
use super::types::{
BlindSignatureScheme, CommitmentScheme, GarbledGate, MPCProtocol, MpcShare, OTVariant,
ObliviousTransfer, PaillierHomomorphic, PedersenCommitment, PedersenParams, SchnorrParams,
SecretSharing, ShamirSS, ShamirSecretSharingExtended, ZKProofSystem,
};
pub fn app(f: Expr, a: Expr) -> Expr {
Expr::App(Box::new(f), Box::new(a))
}
pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
app(app(f, a), b)
}
pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
app(app2(f, a, b), c)
}
pub fn cst(s: &str) -> Expr {
Expr::Const(Name::str(s), vec![])
}
pub fn prop() -> Expr {
Expr::Sort(Level::zero())
}
pub fn type0() -> Expr {
Expr::Sort(Level::succ(Level::zero()))
}
pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
}
pub fn arrow(a: Expr, b: Expr) -> Expr {
pi(BinderInfo::Default, "_", a, b)
}
pub fn nat_ty() -> Expr {
cst("Nat")
}
pub fn bool_ty() -> Expr {
cst("Bool")
}
pub fn list_nat() -> Expr {
app(cst("List"), nat_ty())
}
pub fn msg_ty() -> Expr {
list_nat()
}
pub fn dy_message_ty() -> Expr {
type0()
}
pub fn dy_principal_ty() -> Expr {
type0()
}
pub fn dy_knowledge_ty() -> Expr {
arrow(
dy_principal_ty(),
arrow(app(cst("List"), dy_message_ty()), type0()),
)
}
pub fn dy_derivable_ty() -> Expr {
arrow(
app(cst("List"), dy_message_ty()),
arrow(dy_message_ty(), prop()),
)
}
pub fn dy_attack_ty() -> Expr {
arrow(cst("Protocol"), prop())
}
pub fn dy_intruder_ty() -> Expr {
type0()
}
pub fn confidentiality_ty() -> Expr {
arrow(
cst("Protocol"),
arrow(dy_principal_ty(), arrow(msg_ty(), prop())),
)
}
pub fn integrity_ty() -> Expr {
arrow(cst("Protocol"), arrow(msg_ty(), prop()))
}
pub fn authentication_ty() -> Expr {
arrow(
cst("Protocol"),
arrow(dy_principal_ty(), arrow(dy_principal_ty(), prop())),
)
}
pub fn non_repudiation_ty() -> Expr {
arrow(
cst("Protocol"),
arrow(dy_principal_ty(), arrow(msg_ty(), prop())),
)
}
pub fn fresh_nonce_ty() -> Expr {
arrow(msg_ty(), prop())
}
pub fn protocol_compose_ty() -> Expr {
arrow(cst("Protocol"), arrow(cst("Protocol"), cst("Protocol")))
}
pub fn protocol_parallel_ty() -> Expr {
arrow(cst("Protocol"), arrow(cst("Protocol"), cst("Protocol")))
}
pub fn security_preserved_composition_ty() -> Expr {
arrow(cst("Protocol"), arrow(cst("Protocol"), prop()))
}
pub fn sigma_protocol_ty() -> Expr {
type0()
}
pub fn sigma_commitment_ty() -> Expr {
arrow(sigma_protocol_ty(), type0())
}
pub fn sigma_challenge_ty() -> Expr {
arrow(sigma_protocol_ty(), type0())
}
pub fn sigma_response_ty() -> Expr {
arrow(sigma_protocol_ty(), type0())
}
pub fn sigma_completeness_ty() -> Expr {
arrow(sigma_protocol_ty(), prop())
}
pub fn sigma_special_soundness_ty() -> Expr {
arrow(sigma_protocol_ty(), prop())
}
pub fn sigma_hvzk_ty() -> Expr {
arrow(sigma_protocol_ty(), prop())
}
pub fn zk_proof_ty() -> Expr {
type0()
}
pub fn zk_completeness_ty() -> Expr {
arrow(zk_proof_ty(), prop())
}
pub fn zk_soundness_ty() -> Expr {
arrow(zk_proof_ty(), prop())
}
pub fn zk_zero_knowledge_ty() -> Expr {
arrow(zk_proof_ty(), prop())
}
pub fn nizk_ty() -> Expr {
type0()
}
pub fn fiat_shamir_transform_ty() -> Expr {
arrow(sigma_protocol_ty(), nizk_ty())
}
pub fn zk_snark_ty() -> Expr {
type0()
}
pub fn snark_succinctness_ty() -> Expr {
arrow(zk_snark_ty(), prop())
}
pub fn commitment_scheme_ty() -> Expr {
type0()
}
pub fn commit_hiding_ty() -> Expr {
arrow(commitment_scheme_ty(), prop())
}
pub fn commit_binding_ty() -> Expr {
arrow(commitment_scheme_ty(), prop())
}
pub fn pedersen_commitment_ty() -> Expr {
commitment_scheme_ty()
}
pub fn oblivious_transfer_ty() -> Expr {
type0()
}
pub fn ot_receiver_privacy_ty() -> Expr {
arrow(oblivious_transfer_ty(), prop())
}
pub fn ot_sender_privacy_ty() -> Expr {
arrow(oblivious_transfer_ty(), prop())
}
pub fn ot_extension_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn shamir_secret_sharing_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn secret_sharing_threshold_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn secret_sharing_privacy_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn mpc_protocol_ty() -> Expr {
type0()
}
pub fn mpc_semi_honest_security_ty() -> Expr {
arrow(mpc_protocol_ty(), prop())
}
pub fn mpc_malicious_security_ty() -> Expr {
arrow(mpc_protocol_ty(), prop())
}
pub fn garbled_circuit_ty() -> Expr {
type0()
}
pub fn garbled_circuit_correctness_ty() -> Expr {
arrow(garbled_circuit_ty(), prop())
}
pub fn garbled_circuit_security_ty() -> Expr {
arrow(garbled_circuit_ty(), prop())
}
pub fn ideal_functionality_ty() -> Expr {
type0()
}
pub fn uc_secure_ty() -> Expr {
arrow(mpc_protocol_ty(), arrow(ideal_functionality_ty(), prop()))
}
pub fn uc_composition_theorem_ty() -> Expr {
prop()
}
pub fn hybrid_model_ty() -> Expr {
arrow(ideal_functionality_ty(), type0())
}
pub fn uc_simulator_ty() -> Expr {
arrow(mpc_protocol_ty(), arrow(ideal_functionality_ty(), type0()))
}
pub fn uc_environment_ty() -> Expr {
type0()
}
pub fn uc_indistinguishable_ty() -> Expr {
arrow(mpc_protocol_ty(), arrow(ideal_functionality_ty(), prop()))
}
pub fn gmw_protocol_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn gmw_malicious_secure_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn ot_extension_correctness_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn yao_garbled_privacy_ty() -> Expr {
arrow(garbled_circuit_ty(), prop())
}
pub fn kzg_commitment_ty() -> Expr {
type0()
}
pub fn kzg_binding_ty() -> Expr {
arrow(kzg_commitment_ty(), prop())
}
pub fn vector_commitment_ty() -> Expr {
type0()
}
pub fn vector_commitment_position_binding_ty() -> Expr {
arrow(vector_commitment_ty(), prop())
}
pub fn groth16_proof_ty() -> Expr {
type0()
}
pub fn groth16_soundness_ty() -> Expr {
arrow(groth16_proof_ty(), prop())
}
pub fn plonk_proof_ty() -> Expr {
type0()
}
pub fn plonk_universal_setup_ty() -> Expr {
arrow(plonk_proof_ty(), prop())
}
pub fn fri_protocol_ty() -> Expr {
type0()
}
pub fn fri_soundness_ty() -> Expr {
arrow(fri_protocol_ty(), prop())
}
pub fn stark_proof_ty() -> Expr {
type0()
}
pub fn stark_transparency_ty() -> Expr {
arrow(stark_proof_ty(), prop())
}
pub fn threshold_signature_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), type0()))
}
pub fn threshold_sig_unforgeability_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn distributed_key_gen_ty() -> Expr {
arrow(nat_ty(), type0())
}
pub fn dkg_secrecy_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn blind_signature_ty() -> Expr {
type0()
}
pub fn blindness_property_ty() -> Expr {
arrow(blind_signature_ty(), prop())
}
pub fn blind_sig_unforgeability_ty() -> Expr {
arrow(blind_signature_ty(), prop())
}
pub fn ring_signature_ty() -> Expr {
type0()
}
pub fn ring_sig_anonymity_ty() -> Expr {
arrow(ring_signature_ty(), prop())
}
pub fn linkability_property_ty() -> Expr {
arrow(ring_signature_ty(), prop())
}
pub fn group_signature_ty() -> Expr {
type0()
}
pub fn group_sig_anonymity_ty() -> Expr {
arrow(group_signature_ty(), prop())
}
pub fn group_sig_unlinkability_ty() -> Expr {
arrow(group_signature_ty(), prop())
}
pub fn group_sig_openability_ty() -> Expr {
arrow(group_signature_ty(), prop())
}
pub fn anonymous_credential_ty() -> Expr {
type0()
}
pub fn credential_unlinkability_ty() -> Expr {
arrow(anonymous_credential_ty(), prop())
}
pub fn selective_disclosure_ty() -> Expr {
arrow(anonymous_credential_ty(), prop())
}
pub fn private_set_intersection_ty() -> Expr {
type0()
}
pub fn psi_correctness_ty() -> Expr {
arrow(private_set_intersection_ty(), prop())
}
pub fn psi_privacy_ty() -> Expr {
arrow(private_set_intersection_ty(), prop())
}
pub fn e_voting_scheme_ty() -> Expr {
type0()
}
pub fn voting_verifiability_ty() -> Expr {
arrow(e_voting_scheme_ty(), prop())
}
pub fn voting_ballot_privacy_ty() -> Expr {
arrow(e_voting_scheme_ty(), prop())
}
pub fn mix_net_security_ty() -> Expr {
arrow(type0(), prop())
}
pub fn ake_protocol_ty() -> Expr {
type0()
}
pub fn ake_forward_secrecy_ty() -> Expr {
arrow(ake_protocol_ty(), prop())
}
pub fn ake_mutual_auth_ty() -> Expr {
arrow(ake_protocol_ty(), prop())
}
pub fn signal_protocol_security_ty() -> Expr {
arrow(ake_protocol_ty(), prop())
}
pub fn mpc_with_abort_ty() -> Expr {
arrow(mpc_protocol_ty(), prop())
}
pub fn fair_mpc_ty() -> Expr {
arrow(mpc_protocol_ty(), prop())
}
pub fn guaranteed_output_ty() -> Expr {
arrow(mpc_protocol_ty(), prop())
}
pub fn consensus_protocol_ty() -> Expr {
type0()
}
pub fn consensus_consistency_ty() -> Expr {
arrow(consensus_protocol_ty(), prop())
}
pub fn consensus_liveness_ty() -> Expr {
arrow(consensus_protocol_ty(), prop())
}
pub fn nakamoto_consensus_ty() -> Expr {
consensus_protocol_ty()
}
pub fn ml_kem_scheme_ty() -> Expr {
type0()
}
pub fn ml_kem_ind_cca2_ty() -> Expr {
arrow(ml_kem_scheme_ty(), prop())
}
pub fn ml_dsa_scheme_ty() -> Expr {
type0()
}
pub fn ml_dsa_euf_cma_ty() -> Expr {
arrow(ml_dsa_scheme_ty(), prop())
}
pub fn sphincs_plus_scheme_ty() -> Expr {
type0()
}
pub fn sphincs_plus_minimal_assumptions_ty() -> Expr {
arrow(sphincs_plus_scheme_ty(), prop())
}
pub fn homomorphic_encryption_ty() -> Expr {
type0()
}
pub fn phe_security_ty() -> Expr {
arrow(homomorphic_encryption_ty(), prop())
}
pub fn fhe_bootstrapping_ty() -> Expr {
arrow(homomorphic_encryption_ty(), prop())
}
pub fn build_cryptographic_protocols_env(env: &mut Environment) -> Result<(), String> {
let axioms: &[(&str, Expr)] = &[
("Proto.DYMessage", dy_message_ty()),
("Proto.DYPrincipal", dy_principal_ty()),
("Proto.DYKnowledge", dy_knowledge_ty()),
("Proto.DYDerivable", dy_derivable_ty()),
("Proto.DYAttack", dy_attack_ty()),
("Proto.DYIntruder", dy_intruder_ty()),
("Proto.Protocol", type0()),
("Proto.Confidentiality", confidentiality_ty()),
("Proto.Integrity", integrity_ty()),
("Proto.Authentication", authentication_ty()),
("Proto.NonRepudiation", non_repudiation_ty()),
("Proto.FreshNonce", fresh_nonce_ty()),
("Proto.ProtocolCompose", protocol_compose_ty()),
("Proto.ProtocolParallel", protocol_parallel_ty()),
(
"Proto.SecurityPreservedUnderComposition",
security_preserved_composition_ty(),
),
("Proto.SigmaProtocol", sigma_protocol_ty()),
("Proto.SigmaCommitment", sigma_commitment_ty()),
("Proto.SigmaChallenge", sigma_challenge_ty()),
("Proto.SigmaResponse", sigma_response_ty()),
("Proto.SigmaCompleteness", sigma_completeness_ty()),
("Proto.SigmaSpecialSoundness", sigma_special_soundness_ty()),
("Proto.SigmaHVZK", sigma_hvzk_ty()),
("Proto.ZKProof", zk_proof_ty()),
("Proto.ZKCompleteness", zk_completeness_ty()),
("Proto.ZKSoundness", zk_soundness_ty()),
("Proto.ZKZeroKnowledge", zk_zero_knowledge_ty()),
("Proto.NIZK", nizk_ty()),
("Proto.FiatShamirTransform", fiat_shamir_transform_ty()),
("Proto.ZKSnark", zk_snark_ty()),
("Proto.SnarkSuccinctness", snark_succinctness_ty()),
("Proto.CommitmentScheme", commitment_scheme_ty()),
("Proto.CommitHiding", commit_hiding_ty()),
("Proto.CommitBinding", commit_binding_ty()),
("Proto.ObliviousTransfer", oblivious_transfer_ty()),
("Proto.OTReceiverPrivacy", ot_receiver_privacy_ty()),
("Proto.OTSenderPrivacy", ot_sender_privacy_ty()),
("Proto.OTExtension", ot_extension_ty()),
("Proto.ShamirSecretSharing", shamir_secret_sharing_ty()),
(
"Proto.SecretSharingThreshold",
secret_sharing_threshold_ty(),
),
(
"Proto.SecretSharingPerfectPrivacy",
secret_sharing_privacy_ty(),
),
("Proto.MPCProtocol", mpc_protocol_ty()),
("Proto.MPCSemiHonestSecurity", mpc_semi_honest_security_ty()),
("Proto.MPCMaliciousSecurity", mpc_malicious_security_ty()),
("Proto.GarbledCircuit", garbled_circuit_ty()),
(
"Proto.GarbledCircuitCorrectness",
garbled_circuit_correctness_ty(),
),
(
"Proto.GarbledCircuitSecurity",
garbled_circuit_security_ty(),
),
("Proto.IdealFunctionality", ideal_functionality_ty()),
("Proto.UCSecure", uc_secure_ty()),
("Proto.UCCompositionTheorem", uc_composition_theorem_ty()),
("Proto.HybridModel", hybrid_model_ty()),
("Proto.UCSimulator", uc_simulator_ty()),
("Proto.UCEnvironment", uc_environment_ty()),
("Proto.UCIndistinguishable", uc_indistinguishable_ty()),
("Proto.GMWProtocol", gmw_protocol_ty()),
("Proto.GMWMaliciousSecure", gmw_malicious_secure_ty()),
(
"Proto.OTExtensionCorrectness",
ot_extension_correctness_ty(),
),
("Proto.YaoGarbledCircuitPrivacy", yao_garbled_privacy_ty()),
("Proto.KZGCommitment", kzg_commitment_ty()),
("Proto.KZGBinding", kzg_binding_ty()),
("Proto.VectorCommitment", vector_commitment_ty()),
(
"Proto.VectorCommitmentPositionBinding",
vector_commitment_position_binding_ty(),
),
("Proto.Groth16Proof", groth16_proof_ty()),
("Proto.Groth16Soundness", groth16_soundness_ty()),
("Proto.PlonkProof", plonk_proof_ty()),
("Proto.PlonkUniversalSetup", plonk_universal_setup_ty()),
("Proto.FRIProtocol", fri_protocol_ty()),
("Proto.FRISoundness", fri_soundness_ty()),
("Proto.StarkProof", stark_proof_ty()),
("Proto.StarkTransparency", stark_transparency_ty()),
("Proto.ThresholdSignature", threshold_signature_ty()),
(
"Proto.ThresholdSignatureUnforgeability",
threshold_sig_unforgeability_ty(),
),
("Proto.DistributedKeyGeneration", distributed_key_gen_ty()),
("Proto.DKGSecrecy", dkg_secrecy_ty()),
("Proto.BlindSignature", blind_signature_ty()),
("Proto.BlindnessProperty", blindness_property_ty()),
(
"Proto.BlindSignatureUnforgeability",
blind_sig_unforgeability_ty(),
),
("Proto.RingSignature", ring_signature_ty()),
("Proto.RingSignatureAnonymity", ring_sig_anonymity_ty()),
("Proto.LinkabilityProperty", linkability_property_ty()),
("Proto.GroupSignature", group_signature_ty()),
("Proto.GroupSigAnonymity", group_sig_anonymity_ty()),
("Proto.GroupSigUnlinkability", group_sig_unlinkability_ty()),
("Proto.GroupSigOpenability", group_sig_openability_ty()),
("Proto.AnonymousCredential", anonymous_credential_ty()),
(
"Proto.CredentialUnlinkability",
credential_unlinkability_ty(),
),
("Proto.SelectiveDisclosure", selective_disclosure_ty()),
(
"Proto.PrivateSetIntersection",
private_set_intersection_ty(),
),
("Proto.PSICorrectness", psi_correctness_ty()),
("Proto.PSIPrivacy", psi_privacy_ty()),
("Proto.EVotingScheme", e_voting_scheme_ty()),
("Proto.VotingVerifiability", voting_verifiability_ty()),
("Proto.VotingBallotPrivacy", voting_ballot_privacy_ty()),
("Proto.MixNetSecurity", mix_net_security_ty()),
("Proto.AKEProtocol", ake_protocol_ty()),
("Proto.AKEForwardSecrecy", ake_forward_secrecy_ty()),
("Proto.AKEMutualAuthentication", ake_mutual_auth_ty()),
(
"Proto.SignalProtocolSecurity",
signal_protocol_security_ty(),
),
("Proto.MPCWithAbort", mpc_with_abort_ty()),
("Proto.FairMPC", fair_mpc_ty()),
("Proto.GuaranteedOutput", guaranteed_output_ty()),
("Proto.ConsensusProtocol", consensus_protocol_ty()),
("Proto.ConsensusConsistency", consensus_consistency_ty()),
("Proto.ConsensusLiveness", consensus_liveness_ty()),
("Proto.MLKEMScheme", ml_kem_scheme_ty()),
("Proto.MLKEMInd_CCA2", ml_kem_ind_cca2_ty()),
("Proto.MLDSAScheme", ml_dsa_scheme_ty()),
("Proto.MLDSAEUFCMA", ml_dsa_euf_cma_ty()),
("Proto.SPHINCSPlusScheme", sphincs_plus_scheme_ty()),
(
"Proto.SPHINCSPlusMinimalAssumptions",
sphincs_plus_minimal_assumptions_ty(),
),
("Proto.HomomorphicEncryption", homomorphic_encryption_ty()),
("Proto.PHESecurity", phe_security_ty()),
("Proto.FHEBootstrapping", fhe_bootstrapping_ty()),
];
for (name, ty) in axioms {
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty: ty.clone(),
})
.ok();
}
Ok(())
}
pub fn mod_exp(mut base: u64, mut exp: u64, m: u64) -> u64 {
if m == 1 {
return 0;
}
let mut result: u128 = 1;
let mut b = base as u128 % m as u128;
while exp > 0 {
if exp & 1 == 1 {
result = result * b % m as u128;
}
exp >>= 1;
b = b * b % m as u128;
}
base = result as u64;
base
}
pub fn ext_gcd(a: i64, b: i64) -> (i64, i64, i64) {
if b == 0 {
return (a, 1, 0);
}
let (g, x1, y1) = ext_gcd(b, a % b);
(g, y1, x1 - (a / b) * y1)
}
pub fn mod_inv(a: u64, m: u64) -> Option<u64> {
let (g, x, _) = ext_gcd(a as i64, m as i64);
if g != 1 {
return None;
}
Some(((x % m as i64 + m as i64) % m as i64) as u64)
}
pub fn toy_encrypt(key_a: u64, key_b: u64, plaintext: u64) -> u64 {
let key = key_a
.wrapping_mul(0x9e3779b97f4a7c15)
.wrapping_add(key_b.wrapping_mul(0x6c62272e07bb0142));
plaintext ^ key
}
pub fn tiny_paillier() -> PaillierHomomorphic {
let p: u64 = 7;
let q: u64 = 13;
let n = p * q;
let n_sq = (n as u128) * (n as u128);
let g = n + 1;
let lambda = 12u64;
let mu = 38u64;
PaillierHomomorphic {
n,
n_sq,
g,
lambda,
mu,
}
}
#[cfg(test)]
mod tests {
use super::*;
use oxilean_kernel::Environment;
#[test]
fn test_build_env() {
let mut env = Environment::new();
let result = build_cryptographic_protocols_env(&mut env);
assert!(
result.is_ok(),
"build_cryptographic_protocols_env failed: {:?}",
result
);
}
#[test]
fn test_schnorr_proof() {
let params = SchnorrParams { p: 23, q: 11, g: 2 };
let secret_x = 5u64;
let y = mod_exp(params.g, secret_x, params.p);
assert_eq!(y, 9);
let r = 7u64;
let challenge = 3u64;
let transcript = params.prove(secret_x, r, challenge);
assert!(
params.verify(&transcript, y),
"Schnorr verification failed for valid proof"
);
}
#[test]
fn test_schnorr_invalid_witness() {
let params = SchnorrParams { p: 23, q: 11, g: 2 };
let secret_x = 5u64;
let wrong_x = 6u64;
let y = mod_exp(params.g, secret_x, params.p);
let r = 7u64;
let challenge = 3u64;
let bad_transcript = params.prove(wrong_x, r, challenge);
assert!(
!params.verify(&bad_transcript, y),
"Schnorr should reject proof with wrong witness"
);
}
#[test]
fn test_pedersen_commitment() {
let params = PedersenParams {
p: 23,
q: 11,
g: 2,
h: 3,
};
let m = 4u64;
let r = 6u64;
let c = params.commit(m, r);
assert!(
params.verify(c, m, r),
"Pedersen commitment should verify correctly"
);
assert!(
!params.verify(c, m + 1, r),
"Different message should not verify"
);
}
#[test]
fn test_pedersen_homomorphic() {
let params = PedersenParams {
p: 23,
q: 11,
g: 2,
h: 3,
};
let (m1, r1) = (2u64, 3u64);
let (m2, r2) = (1u64, 4u64);
let c1 = params.commit(m1, r1);
let c2 = params.commit(m2, r2);
let c_sum = params.add_commitments(c1, c2);
let c_direct = params.commit((m1 + m2) % params.q, (r1 + r2) % params.q);
assert_eq!(c_sum, c_direct, "Pedersen commitment should be homomorphic");
}
#[test]
fn test_shamir_secret_sharing() {
let ss = ShamirSS { p: 97, t: 3, n: 5 };
let secret = 42u64;
let coeffs = [7u64, 13u64];
let shares = ss.split(secret, &coeffs);
assert_eq!(shares.len(), 5, "Should produce 5 shares");
let reconstructed = ss.reconstruct(&shares[..3]);
assert_eq!(
reconstructed, secret,
"Reconstructed secret should match original"
);
let reconstructed2 = ss.reconstruct(&shares[2..5]);
assert_eq!(
reconstructed2, secret,
"Any t shares should reconstruct secret"
);
}
#[test]
fn test_mpc_xor_share() {
let s0 = MpcShare {
party: 0,
share: true,
};
let s1 = MpcShare {
party: 1,
share: false,
};
assert!(
MpcShare::reconstruct(&s0, &s1),
"XOR shares should reconstruct to true"
);
let a0 = MpcShare {
party: 0,
share: true,
};
let b0 = MpcShare {
party: 0,
share: false,
};
let result = MpcShare::xor_gate(&a0, &b0);
assert!(
result.share,
"XOR(true, false) share for party 0 should be true"
);
}
#[test]
fn test_dy_derivable_axiom_registered() {
let mut env = Environment::new();
build_cryptographic_protocols_env(&mut env)
.expect("build_cryptographic_protocols_env should succeed");
assert!(
env.get(&Name::str("Proto.DYDerivable")).is_some(),
"Proto.DYDerivable should be registered"
);
assert!(
env.get(&Name::str("Proto.UCCompositionTheorem")).is_some(),
"Proto.UCCompositionTheorem should be registered"
);
}
#[test]
fn test_uc_composition_is_prop() {
let ty = uc_composition_theorem_ty();
assert_eq!(ty, prop(), "UC composition theorem should have type Prop");
}
#[test]
fn test_new_axioms_registered() {
let mut env = Environment::new();
build_cryptographic_protocols_env(&mut env)
.expect("build_cryptographic_protocols_env should succeed");
assert!(env.get(&Name::str("Proto.UCSimulator")).is_some());
assert!(env.get(&Name::str("Proto.UCEnvironment")).is_some());
assert!(env.get(&Name::str("Proto.UCIndistinguishable")).is_some());
assert!(env.get(&Name::str("Proto.Groth16Proof")).is_some());
assert!(env.get(&Name::str("Proto.PlonkProof")).is_some());
assert!(env.get(&Name::str("Proto.FRIProtocol")).is_some());
assert!(env.get(&Name::str("Proto.StarkProof")).is_some());
assert!(env.get(&Name::str("Proto.MLKEMScheme")).is_some());
assert!(env.get(&Name::str("Proto.MLDSAScheme")).is_some());
assert!(env.get(&Name::str("Proto.SPHINCSPlusScheme")).is_some());
assert!(env.get(&Name::str("Proto.RingSignature")).is_some());
assert!(env.get(&Name::str("Proto.GroupSignature")).is_some());
assert!(env.get(&Name::str("Proto.BlindSignature")).is_some());
assert!(env.get(&Name::str("Proto.AnonymousCredential")).is_some());
assert!(env
.get(&Name::str("Proto.PrivateSetIntersection"))
.is_some());
assert!(env.get(&Name::str("Proto.EVotingScheme")).is_some());
assert!(env.get(&Name::str("Proto.ConsensusProtocol")).is_some());
assert!(env.get(&Name::str("Proto.HomomorphicEncryption")).is_some());
assert!(env.get(&Name::str("Proto.FHEBootstrapping")).is_some());
}
#[test]
fn test_pedersen_commitment_struct() {
let pc = PedersenCommitment {
p: 23,
q: 11,
g: 2,
h: 3,
};
let m = 3u64;
let r = 5u64;
let c = pc.commit(m, r);
assert!(
pc.verify(c, m, r),
"PedersenCommitment verify should succeed"
);
assert!(
!pc.verify(c, m + 1, r),
"PedersenCommitment verify should fail for wrong m"
);
}
#[test]
fn test_pedersen_commitment_batch() {
let pc = PedersenCommitment {
p: 23,
q: 11,
g: 2,
h: 3,
};
let pairs = [(1u64, 2u64), (3u64, 4u64), (5u64, 6u64)];
let commitments = pc.batch_commit(&pairs);
assert_eq!(commitments.len(), 3);
for (i, &(m, r)) in pairs.iter().enumerate() {
assert!(pc.verify(commitments[i], m, r));
}
}
#[test]
fn test_pedersen_commitment_homomorphic() {
let pc = PedersenCommitment {
p: 23,
q: 11,
g: 2,
h: 3,
};
let (m1, r1) = (2u64, 3u64);
let (m2, r2) = (1u64, 4u64);
let c1 = pc.commit(m1, r1);
let c2 = pc.commit(m2, r2);
let c_add = pc.add(c1, c2);
let c_direct = pc.commit((m1 + m2) % pc.q, (r1 + r2) % pc.q);
assert_eq!(c_add, c_direct, "Homomorphic add should be correct");
}
#[test]
fn test_shamir_extended_share_reconstruct() {
let ss = ShamirSecretSharingExtended { p: 97, t: 3, n: 5 };
let secret = 42u64;
let coeffs = [7u64, 13u64];
let shares = ss.share(secret, &coeffs);
assert_eq!(shares.len(), 5);
let reconstructed = ss.reconstruct(&shares[..3]);
assert_eq!(
reconstructed, secret,
"Extended Shamir reconstruction should match secret"
);
let reconstructed2 = ss.reconstruct(&shares[2..5]);
assert_eq!(
reconstructed2, secret,
"Any t shares should reconstruct the secret"
);
}
#[test]
fn test_garbled_and_gate() {
let labels_a = [10u64, 20u64];
let labels_b = [30u64, 40u64];
let labels_out = [50u64, 60u64];
let gate = GarbledGate::garble_and(labels_a, labels_b, labels_out);
let out = gate
.evaluate(labels_a[0], labels_b[0])
.expect("evaluate should succeed");
assert!(!gate.is_output_one(out), "AND(0,0) should be 0");
let out = gate
.evaluate(labels_a[1], labels_b[1])
.expect("evaluate should succeed");
assert!(gate.is_output_one(out), "AND(1,1) should be 1");
let out = gate
.evaluate(labels_a[1], labels_b[0])
.expect("evaluate should succeed");
assert!(!gate.is_output_one(out), "AND(1,0) should be 0");
}
#[test]
fn test_garbled_or_gate() {
let labels_a = [100u64, 200u64];
let labels_b = [300u64, 400u64];
let labels_out = [500u64, 600u64];
let gate = GarbledGate::garble_or(labels_a, labels_b, labels_out);
let out = gate
.evaluate(labels_a[0], labels_b[0])
.expect("evaluate should succeed");
assert!(!gate.is_output_one(out), "OR(0,0) should be 0");
let out = gate
.evaluate(labels_a[0], labels_b[1])
.expect("evaluate should succeed");
assert!(gate.is_output_one(out), "OR(0,1) should be 1");
let out = gate
.evaluate(labels_a[1], labels_b[0])
.expect("evaluate should succeed");
assert!(gate.is_output_one(out), "OR(1,0) should be 1");
}
#[test]
fn test_paillier_homomorphic_encrypt_decrypt() {
let ph = tiny_paillier();
let m = 7u64;
let r = 2u64;
let c = ph.encrypt(m, r);
let decrypted = ph.decrypt(c);
assert_eq!(
decrypted,
m % ph.n,
"Paillier decrypt should recover plaintext"
);
}
#[test]
fn test_paillier_homomorphic_add() {
let ph = tiny_paillier();
let m1 = 3u64;
let m2 = 4u64;
let c1 = ph.encrypt(m1, 2);
let c2 = ph.encrypt(m2, 3);
let c_sum = ph.add_ciphertexts(c1, c2);
let decrypted = ph.decrypt(c_sum);
assert_eq!(
decrypted,
(m1 + m2) % ph.n,
"Homomorphic Paillier add should recover sum"
);
}
#[test]
fn test_blind_signature_full_protocol() {
let bs = BlindSignatureScheme { n: 55, e: 3, d: 27 };
let m = 7u64;
let r = 8u64;
let blinded = bs.blind(m, r);
let s_prime = bs.sign_blinded(blinded);
let s = bs.unblind(s_prime, r);
assert!(
bs.verify(m, s),
"Blind signature verification should succeed after unblinding"
);
}
#[test]
fn test_stark_and_groth16_are_type0() {
assert_eq!(stark_proof_ty(), type0(), "StarkProof should be Type");
assert_eq!(groth16_proof_ty(), type0(), "Groth16Proof should be Type");
}
#[test]
fn test_consensus_liveness_is_prop() {
let ty = consensus_liveness_ty();
assert_ne!(ty, type0(), "ConsensusLiveness should not be Type");
}
}
#[cfg(test)]
mod tests_crypto_extra {
use super::*;
#[test]
fn test_zk_proof_systems() {
let groth = ZKProofSystem::groth16();
assert!(groth.is_non_interactive());
assert!(groth.is_succinct());
let plonk = ZKProofSystem::plonk();
assert!(plonk.is_non_interactive());
let schnorr = ZKProofSystem::schnorr();
assert!(!schnorr.is_non_interactive());
}
#[test]
fn test_commitment_scheme() {
let ped = CommitmentScheme::pedersen();
assert!(ped.is_perfectly_hiding);
assert!(ped.is_homomorphic);
let sha = CommitmentScheme::sha256_hash();
assert!(!sha.is_homomorphic);
}
#[test]
fn test_oblivious_transfer() {
let ot = ObliviousTransfer::new(OTVariant::OneOutOfTwo, 128);
assert!(ot.is_fundamental());
assert_eq!(ot.n_messages(), 2);
let ot_n = ObliviousTransfer::new(OTVariant::OneOutOfN(10), 128);
assert_eq!(ot_n.n_messages(), 10);
}
#[test]
fn test_mpc_protocol() {
let bgw = MPCProtocol::bgw(4, 1);
assert!(bgw.is_optimal_corruption_threshold());
assert!(bgw.is_secure_against_majority_corruption());
}
#[test]
fn test_secret_sharing() {
let ss = SecretSharing::shamir_2_of_3();
assert_eq!(ss.threshold, 2);
assert_eq!(ss.n_shares, 3);
assert!(ss.is_perfect());
assert_eq!(ss.min_shares_needed(), 2);
}
}