I decided the VRF outputs needed to be non-malleable because our support for HDKD permits transforming a VRF output from one subkey into an output for another subkey.
I've addressed this by adding six method with names involving malleable for users who want the malleability, but this looks suboptimal. Instead, we might provide a wrapper trait around SigningTranscript that addresses the malleability concern by default, but provide a variant that avoids doing so.
pub trait VRFSigningTranscript {
type T: SigningTranscript;
fn transcript(self) -> T;
}
impl<T> VRFSigningTranscript for T where T: SigningTranscript {
type T = T;
fn transcript(self, publickey: &PublicKey) {
publickey.make_transcript_nonmalleable(&mut self)
self
}
}
/// .. scary warnings ..
pub struct Malleable<T: SigningTranscript>(pub T);
impl<T> VRFSigningTranscript for Malleable<T> where T: SigningTranscript {
type T = T;
fn transcript(self) { self.0 }
}
I decided the VRF outputs needed to be non-malleable because our support for HDKD permits transforming a VRF output from one subkey into an output for another subkey.
I've addressed this by adding six method with names involving
malleable
for users who want the malleability, but this looks suboptimal. Instead, we might provide a wrapper trait aroundSigningTranscript
that addresses the malleability concern by default, but provide a variant that avoids doing so.