package privacypass import ( "cwtch.im/tapir/persistence" "cwtch.im/tapir/primitives/core" "git.openprivacy.ca/openprivacy/libricochet-go/log" "github.com/gtank/ristretto255" "golang.org/x/crypto/sha3" "testing" ) func TestToken_SpendToken(t *testing.T) { server := NewTokenServer() token := new(Token) blindedToken := token.GenBlindedToken() signedToken := server.SignBlindedToken(blindedToken) token.unblindSignedToken(signedToken) spentToken := token.SpendToken([]byte("Hello")) if server.SpendToken(spentToken, []byte("Hello World")) == nil { t.Errorf("Token Should be InValid") } if err := server.SpendToken(spentToken, []byte("Hello")); err != nil { t.Errorf("Token Should be Valid: %v", err) } if err := server.SpendToken(spentToken, []byte("Hello")); err == nil { t.Errorf("Token Should be Spent") } } func TestToken_ConstrainToToken(t *testing.T) { server := NewTokenServer() token := new(Token) blindedToken := token.GenBlindedToken() signedToken := server.SignBlindedToken(blindedToken) token.unblindSignedToken(signedToken) spentToken := token.SpendToken([]byte("Hello")) if server.SpendToken(spentToken, []byte("Hello World")) == nil { t.Errorf("Token Should be InValid") } token2 := new(Token) blindedToken2 := token2.GenBlindedToken() Ht := sha3.Sum512(token.t) T := new(ristretto255.Element).FromUniformBytes(Ht[:]) // 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.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()) } func TestGenerateBlindedTokenBatch(t *testing.T) { log.SetLevel(log.LevelDebug) db := new(persistence.BoltPersistence) db.Open("tokens.db") defer db.Close() server := NewTokenServerFromStore(db) clientTranscript := core.NewTranscript("privacyPass") serverTranscript := core.NewTranscript("privacyPass") tokens, blindedTokens := GenerateBlindedTokenBatch(10) batchProof := server.SignBlindedTokenBatch(blindedTokens, serverTranscript) verified := UnblindSignedTokenBatch(tokens, blindedTokens, batchProof.SignedTokens, server.Y, batchProof.Proof, clientTranscript) if !verified { t.Errorf("Something went wrong, the proof did not pass") } // Attempt to Spend All the tokens for _, token := range tokens { spentToken := token.SpendToken([]byte("Hello")) if err := server.SpendToken(spentToken, []byte("Hello")); err != nil { t.Errorf("Token Should be Valid: %v", err) } } t.Logf("Client Transcript,: %s", clientTranscript.OutputTranscriptToAudit()) t.Logf("Server Transcript,: %s", serverTranscript.OutputTranscriptToAudit()) wrongTranscript := core.NewTranscript("wrongTranscript") verified = UnblindSignedTokenBatch(tokens, blindedTokens, batchProof.SignedTokens, server.Y, batchProof.Proof, wrongTranscript) if verified { t.Errorf("Something went wrong, the proof passed with wrong transcript: %s", wrongTranscript.OutputTranscriptToAudit()) } }