52 lines
1.7 KiB
Go
52 lines
1.7 KiB
Go
package primitives
|
|
|
|
import (
|
|
"fmt"
|
|
"golang.org/x/crypto/sha3"
|
|
"hash"
|
|
)
|
|
|
|
// Transcript implements a transcript of a public coin argument.
|
|
//
|
|
// We have the following goals:
|
|
// - Provide a consisted transcript API for our zero knowledge protocols
|
|
// - Allow sequential proofs over a common transcript (ensuring a single proof cannot be extracted standalone)
|
|
// - produce an auditable human-readable transcript.
|
|
//
|
|
// The design of this API was inspired by Merlin: https://docs.rs/crate/merlin/
|
|
//
|
|
// At some point we might want to extend this to be compatible with Merlin transcripts, built on STROBE
|
|
type Transcript struct {
|
|
hash hash.Hash
|
|
transcript string
|
|
}
|
|
|
|
// NewTranscript creates a new Transcript with the given Label, the label should be unique to the application
|
|
func NewTranscript(label string) *Transcript {
|
|
transcript := new(Transcript)
|
|
transcript.hash = sha3.New256()
|
|
transcript.AddToTranscript("protocol", []byte(label))
|
|
return transcript
|
|
}
|
|
|
|
// AddToTranscript appends a value to the transcript with the given label
|
|
// This binds the given data to the label.
|
|
func (t *Transcript) AddToTranscript(label string, b []byte) {
|
|
op := fmt.Sprintf("%s (%d) %x;", label, len(b), b)
|
|
t.transcript = fmt.Sprintf("%v\n%v", t.transcript, op)
|
|
t.hash.Write([]byte(op))
|
|
}
|
|
|
|
// OutputTranscriptToAudit outputs a human-readable copy of the transcript so far.
|
|
func (t Transcript) OutputTranscriptToAudit() string {
|
|
return t.transcript
|
|
}
|
|
|
|
// CommitToTranscript generates a challenge based on the current transcript, it also commits the challenge to the transcript.
|
|
func (t *Transcript) CommitToTranscript(label string) []byte {
|
|
t.AddToTranscript("commit", []byte(label))
|
|
b := t.hash.Sum([]byte{})
|
|
t.AddToTranscript(label, b)
|
|
return b
|
|
}
|