107 lines
3.6 KiB
Go
107 lines
3.6 KiB
Go
package privacypass
|
|
|
|
import (
|
|
"crypto/sha512"
|
|
"git.openprivacy.ca/cwtch.im/tapir/persistence"
|
|
"git.openprivacy.ca/cwtch.im/tapir/primitives/core"
|
|
"git.openprivacy.ca/openprivacy/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")
|
|
|
|
fakeRand := sha512.Sum512([]byte{})
|
|
k := ristretto255.NewScalar().FromUniformBytes(fakeRand[:])
|
|
server := NewTokenServerFromStore(k, db)
|
|
defer server.Close()
|
|
|
|
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())
|
|
}
|
|
|
|
}
|