Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hierarchial transcripts #9

Open
HarryR opened this issue Dec 23, 2024 · 0 comments
Open

Hierarchial transcripts #9

HarryR opened this issue Dec 23, 2024 · 0 comments

Comments

@HarryR
Copy link

HarryR commented Dec 23, 2024

It annoyed me that I can't append a transcript to a transcript, nor can I fork a transcript which I can then append (or... not append).

Either way, here's how to forking append a transcript, seems like an oversight that something like this isn't part of the library.

TL;DR the current .clone semantics don't capture tree structures, which are very useful. Forking a transcript is transcribed in both transcripts, as is appending a transcript to another one.

Really, the challenge should be bi-directional, the code below doesn't acknowledge which transcript the fork is joining when it's appended. So don't use it...

use merlin::Transcript;

pub trait TranscriptExt {
    // Proposed method to fork a transcript
    fn fork_transcript(&mut self) -> Transcript;

    // Proposed method to append another transcript
    fn append_transcript(&mut self, other: &mut Transcript);
}

impl TranscriptExt for Transcript {
    fn fork_transcript(&mut self) -> Transcript {
        // Generate a challenge to use as a label for the fork
        let mut fork_label = [0u8; 32];
        self.challenge_bytes(b"fork_label", &mut fork_label);

        // Create a new transcript with the fork label
        let mut forked_transcript = self.clone();
        forked_transcript.append_message(b"forked_from", &fork_label);

        forked_transcript
    }

    fn append_transcript(&mut self, other: &mut Transcript) {
        // Use the challenge from the previous fork as a label
        let mut append_label = [0u8; 32];
        other.challenge_bytes(b"fork_challenge", &mut append_label);

        // Append the entire transcript with this label
        self.append_message(b"appended_transcript", &append_label);
    }
}

fn main() {
    // Example usage
    let mut original_transcript = Transcript::new(b"protocol_context");
    original_transcript.append_message(b"initial_message", b"data");

    // Fork the transcript
    let mut forked_transcript = original_transcript.fork_transcript();
    forked_transcript.append_message(b"fork_specific_message", b"fork_data");

    // Append another transcript
    original_transcript.append_transcript(&mut forked_transcript);
}

So you could use something like

    fn append_transcript(&mut self, other: &mut Transcript) {
        // Generate a challenge from the receiving transcript
        let mut receiver_challenge = [0u8; 32];
        self.challenge_bytes(b"append_receiver_challenge", &mut receiver_challenge);

        // Generate a challenge from the appended transcript
        let mut appended_challenge = [0u8; 32];
        other.challenge_bytes(b"append_sender_challenge", &mut appended_challenge);

        // Append both challenges to both transcripts
        self.append_message(b"appended_transcript_receiver_challenge", &receiver_challenge);
        other.append_message(b"appended_transcript_sender_challenge", &appended_challenge);
    }

Additionally, it would be good if the challenge size was defined somewhere as a constant usize instead of hard-coding 32 everywhere

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant