Last active
December 30, 2024 07:53
-
-
Save davxy/c3327f799cb70a7c55087c97741fa8d9 to your computer and use it in GitHub Desktop.
Ring VRF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn proof_fails() { | |
let ring_set: Vec<_> = (0..RING_SIZE) | |
.map(|i| Secret::from_seed(&i.to_le_bytes()).public()) | |
.collect(); | |
let prover_key_index = 3; | |
let prover = Prover::new(ring_set.clone(), prover_key_index); | |
let verifier = Verifier::new(ring_set); | |
let vrf_input_data = b"foo"; | |
let aux_data = b"bar"; | |
let input_point = vrf_input_point(vrf_input_data); | |
let output_point = prover.secret.output(input_point); | |
// Ring signature construction | |
let ring_signature = { | |
use ark_ec_vrfs::ring::Prover as _; | |
let ring_ctx = ring_context(); | |
let pts: Vec<_> = prover.ring.iter().map(|pk| pk.0).collect(); | |
let prover_key = ring_ctx.prover_key(&pts); | |
let ring_prover = ring_ctx.prover(prover_key, prover.prover_idx); | |
let ring_proof = prover | |
.secret | |
.prove(input_point, output_point, aux_data, &ring_prover); | |
RingVrfSignature { | |
output: output_point, | |
proof: ring_proof, | |
} | |
}; | |
// Ring signature verification | |
let ring_vrf_output_hash = { | |
use ark_ec_vrfs::ring::Verifier as _; | |
let ring_ctx = ring_context(); | |
let verifier_key = ring_ctx.verifier_key_from_commitment(verifier.commitment.clone()); | |
let ring_verifier = ring_ctx.verifier(verifier_key); | |
let res = Public::verify( | |
input_point, | |
output_point, | |
aux_data, | |
&ring_signature.proof, | |
&ring_verifier, | |
); | |
assert!(res.is_ok()); | |
let vrf_output_hash: [u8; 32] = ring_signature.output.hash()[..32].try_into().unwrap(); | |
vrf_output_hash | |
}; | |
// Ietf signature construction | |
let ietf_signature = { | |
use ark_ec_vrfs::ietf::Prover; | |
let ietf_proof = prover.secret.prove(input_point, output_point, aux_data); | |
IetfVrfSignature { | |
output: output_point, | |
proof: ietf_proof, | |
} | |
}; | |
// Ietf signature verification | |
let ietf_vrf_output_hash = { | |
use ark_ec_vrfs::ietf::Verifier as _; | |
let public = &verifier.ring[prover_key_index]; | |
let res = public.verify(input_point, output_point, aux_data, &ietf_signature.proof); | |
assert!(res.is_ok()); | |
let vrf_output_hash: [u8; 32] = ietf_signature.output.hash()[..32].try_into().unwrap(); | |
vrf_output_hash | |
}; | |
// Check vrf output match | |
// (quite obvious as are produced from the same output point) | |
assert_eq!(ring_vrf_output_hash, ietf_vrf_output_hash); | |
// Attempt to cheat by signing an output that is not produced by us | |
let bad_prover_key_index = prover_key_index + 1; | |
let bad_ietf_signature = { | |
use ark_ec_vrfs::ietf::Prover; | |
let secret = Secret::from_seed(&bad_prover_key_index.to_le_bytes()); | |
// NOTE: output_point has not been produced by us!!! | |
let ietf_proof = secret.prove(input_point, output_point, aux_data); | |
IetfVrfSignature { | |
output: output_point, | |
proof: ietf_proof, | |
} | |
}; | |
// Verification must fail | |
let ietf_vrf_output_hash = { | |
use ark_ec_vrfs::ietf::Verifier as _; | |
let public = &verifier.ring[bad_prover_key_index]; | |
let res = public.verify( | |
input_point, | |
output_point, | |
aux_data, | |
&bad_ietf_signature.proof, | |
); | |
// NOTE: FAILS!!! | |
assert!(res.is_err()); | |
let vrf_output_hash: [u8; 32] = ietf_signature.output.hash()[..32].try_into().unwrap(); | |
vrf_output_hash | |
}; | |
// Obviously vrf output still match (as are produced from the same output point) | |
// But signature verification failed | |
assert_eq!(ring_vrf_output_hash, ietf_vrf_output_hash); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment