Skip to content

Instantly share code, notes, and snippets.

@davxy
Last active December 30, 2024 07:53
Show Gist options
  • Save davxy/c3327f799cb70a7c55087c97741fa8d9 to your computer and use it in GitHub Desktop.
Save davxy/c3327f799cb70a7c55087c97741fa8d9 to your computer and use it in GitHub Desktop.
Ring VRF
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