Skip to content

'static lifetime bound on label has unclear semantics #16

@cmlsharp

Description

@cmlsharp

Several transcript methods take label: &'static [u8], however the semantics of this are somewhat unclear. From what I can surmise, the purpose of this is to require/suggest that the label be a compile time constant, however this is not explicitly documented on the functions that accept a label parameter. This perhaps would not be necessary if label: &'static [u8] actually enforced that label was known at compile time, but it does not (see Box::leak), hence explicit documentation seems important.

Alternatively it is possible to actually enforce that label is a compile time constant. The ideal way would be once adt_const_params is stabilized, the function signature for e.g. append_message could look like fn append_messsage<const LABEL: &[u8]>(&mut self, message: &[u8]). Until then, another way would be to introduce a Label type with an unsafe constructor and a macro for constructing it. Something like:

#[derive(...)]
pub struct Label(&'static [u8]);
impl Label {
    /// # SAFETY: label should be a compile time constant
    pub unsafe fn new_unchecked(label: &'static [u8]) {
        Label(label)
    }
}
// AsRef and Deref impls here

#[macro_export]
macro_rules! label {
    ($label: expr) => {{
        // enforce that label is known at compile time
        const LABEL_MUST_BE_CONST: &[u8] = $label;
        unsafe { $crate::Label::new_unchecked(LABEL_MUST_BE_CONST) }
    }};
}

// ...

let mut transcript = Transcript::new(label!(b"my_protocol"));

This would of course be a breaking change. If there is interest in changing the documentation or adopting this approach for the next version of merlin I am happy to submit a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions