diff --git a/primitives/privacypass/token.go b/primitives/privacypass/token.go index 04de7ae..70ac785 100644 --- a/primitives/privacypass/token.go +++ b/primitives/privacypass/token.go @@ -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 { t.r.FromUniformBytes(b) 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(transcript.OutputTranscriptToAudit()) + log.Debugf("Failed to unblind tokens: %v", transcript.OutputTranscriptToAudit()) return false } for i, t := range tokens { diff --git a/primitives/privacypass/token_test.go b/primitives/privacypass/token_test.go index 18b68bb..cd15b09 100644 --- a/primitives/privacypass/token_test.go +++ b/primitives/privacypass/token_test.go @@ -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)) t.Log(transcript.OutputTranscriptToAudit()) } diff --git a/primitives/privacypass/tokenserver.go b/primitives/privacypass/tokenserver.go index a4f32a7..c5036d2 100644 --- a/primitives/privacypass/tokenserver.go +++ b/primitives/privacypass/tokenserver.go @@ -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