Amend sign with token constraint api to use []byte instead of token #9

Manually merged
erinn merged 1 commits from transcript into master 3 years ago
  1. 8
  2. 4
  3. 9


@ -19,6 +19,11 @@ type Token struct {
W *ristretto.Element
// GetT returns the underlying bytes for token for use in constraint proofs.
func (t Token) GetT() []byte {
return t.t
// BlindedToken encapsulates a Blinded Token
type BlindedToken struct {
P *ristretto.Element
@ -53,7 +58,6 @@ func (t *Token) GenBlindedToken() BlindedToken {
Ht := sha3.Sum512(t.t)
log.Debugf("token: %x", Ht)
T := new(ristretto.Element).FromUniformBytes(Ht[:])
P := new(ristretto.Element).ScalarMult(t.r, T)
return BlindedToken{P}
@ -103,7 +107,7 @@ func verifyBatchProof(dleq DLEQProof, Y *ristretto.Element, blindedTokens []Blin
func UnblindSignedTokenBatch(tokens []*Token, blindedTokens []BlindedToken, signedTokens []SignedToken, Y *ristretto.Element, proof DLEQProof, transcript *core.Transcript) bool {
verified := verifyBatchProof(proof, Y, blindedTokens, signedTokens, transcript)
if !verified {
log.Debugf("Failed to unblind tokens: %v", transcript.OutputTranscriptToAudit())
return false
for i, t := range tokens {


@ -55,8 +55,10 @@ func TestToken_ConstrainToToken(t *testing.T) {
// Constraint forces T = kW to be part of the batch proof
// And because the batch proof must prove that *all* inputs share the same key and also checks the servers public key
// We get a consistency check for almost free.
signedTokens := server.SignBlindedTokenBatchWithConstraint([]BlindedToken{blindedToken2}, *token, core.NewTranscript(""))
signedTokens := server.SignBlindedTokenBatchWithConstraint([]BlindedToken{blindedToken2}, token.t, core.NewTranscript(""))
transcript := core.NewTranscript("")
// NOTE: For this to work token.t and token.W need to be obtain by the client from known source e.g. a public message board.
t.Logf("Result of constaint proof %v", UnblindSignedTokenBatch([]*Token{token2}, []BlindedToken{blindedToken2, {P: T}}, append(signedTokens.SignedTokens, SignedToken{token.W}), server.Y, signedTokens.Proof, transcript))


@ -82,18 +82,19 @@ func (ts *TokenServer) SignBlindedTokenBatch(blindedTokens []BlindedToken, trans
return SignedBatchWithProof{signedTokens, ts.constructBatchProof(blindedTokens, signedTokens, transcript)}
// SignBlindedTokenBatchWithConstraint signs a batch of blinded tokens under a given transcript given a contraint that the tokens must be signed
// SignBlindedTokenBatchWithConstraint signs a batch of blinded tokens under a given transcript given a constraint that the tokens must be signed
// by the same public key as an existing token
func (ts *TokenServer) SignBlindedTokenBatchWithConstraint(blindedTokens []BlindedToken, token Token, transcript *core.Transcript) SignedBatchWithProof {
func (ts *TokenServer) SignBlindedTokenBatchWithConstraint(blindedTokens []BlindedToken, constraintToken []byte, transcript *core.Transcript) SignedBatchWithProof {
var signedTokens []SignedToken
for _, bt := range blindedTokens {
signedTokens = append(signedTokens, ts.SignBlindedToken(bt))
Ht := sha3.Sum512(token.t)
Ht := sha3.Sum512(constraintToken)
T := new(ristretto.Element).FromUniformBytes(Ht[:])
// W == kT
W := new(ristretto.Element).ScalarMult(ts.k, T)
blindedTokens = append(blindedTokens, BlindedToken{P: T})
return SignedBatchWithProof{signedTokens, ts.constructBatchProof(blindedTokens, append(signedTokens, SignedToken{Q: token.W}), transcript)}
return SignedBatchWithProof{signedTokens, ts.constructBatchProof(blindedTokens, append(signedTokens, SignedToken{Q: W}), transcript)}
// constructBatchProof construct a batch proof that all the signed tokens have been signed correctly