2019-09-14 23:44:19 +00:00
package privacypass
import (
2021-05-05 19:03:08 +00:00
"crypto/sha512"
2021-04-09 00:55:17 +00:00
"git.openprivacy.ca/cwtch.im/tapir/persistence"
"git.openprivacy.ca/cwtch.im/tapir/primitives/core"
2020-02-06 23:54:13 +00:00
"git.openprivacy.ca/openprivacy/log"
2019-11-26 21:10:09 +00:00
"github.com/gtank/ristretto255"
"golang.org/x/crypto/sha3"
2019-09-14 23:44:19 +00:00
"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" ) )
2019-09-15 21:20:05 +00:00
if server . SpendToken ( spentToken , [ ] byte ( "Hello World" ) ) == nil {
2019-09-14 23:44:19 +00:00
t . Errorf ( "Token Should be InValid" )
}
2019-09-15 21:20:05 +00:00
if err := server . SpendToken ( spentToken , [ ] byte ( "Hello" ) ) ; err != nil {
t . Errorf ( "Token Should be Valid: %v" , err )
2019-09-14 23:44:19 +00:00
}
2019-09-15 21:20:05 +00:00
if err := server . SpendToken ( spentToken , [ ] byte ( "Hello" ) ) ; err == nil {
2019-09-14 23:44:19 +00:00
t . Errorf ( "Token Should be Spent" )
}
}
2019-11-26 21:10:09 +00:00
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.
2022-04-19 22:16:07 +00:00
signedTokens , err := server . SignBlindedTokenBatchWithConstraint ( [ ] BlindedToken { blindedToken2 } , token . t , core . NewTranscript ( "" ) )
if err != nil {
t . Fatalf ( "error signing tokens with constraints" )
}
2019-11-26 21:10:09 +00:00
transcript := core . NewTranscript ( "" )
2019-12-02 20:37:25 +00:00
// 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.
2019-11-26 21:10:09 +00:00
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 ( ) )
}
2019-09-14 23:44:19 +00:00
func TestGenerateBlindedTokenBatch ( t * testing . T ) {
2019-09-15 05:50:06 +00:00
log . SetLevel ( log . LevelDebug )
2019-09-15 21:20:05 +00:00
db := new ( persistence . BoltPersistence )
db . Open ( "tokens.db" )
2021-05-05 19:03:08 +00:00
fakeRand := sha512 . Sum512 ( [ ] byte { } )
k := ristretto255 . NewScalar ( ) . FromUniformBytes ( fakeRand [ : ] )
server := NewTokenServerFromStore ( k , db )
defer server . Close ( )
2019-09-14 23:44:19 +00:00
clientTranscript := core . NewTranscript ( "privacyPass" )
serverTranscript := core . NewTranscript ( "privacyPass" )
tokens , blindedTokens := GenerateBlindedTokenBatch ( 10 )
2022-04-19 22:16:07 +00:00
batchProof , err := server . SignBlindedTokenBatch ( blindedTokens , serverTranscript )
if err != nil {
t . Fatalf ( "error constructing signed/blinded token batch: %v" , err )
}
2019-09-14 23:44:19 +00:00
2019-09-15 21:20:05 +00:00
verified := UnblindSignedTokenBatch ( tokens , blindedTokens , batchProof . SignedTokens , server . Y , batchProof . Proof , clientTranscript )
2019-09-14 23:44:19 +00:00
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" ) )
2019-09-15 21:20:05 +00:00
if err := server . SpendToken ( spentToken , [ ] byte ( "Hello" ) ) ; err != nil {
t . Errorf ( "Token Should be Valid: %v" , err )
2019-09-14 23:44:19 +00:00
}
}
t . Logf ( "Client Transcript,: %s" , clientTranscript . OutputTranscriptToAudit ( ) )
t . Logf ( "Server Transcript,: %s" , serverTranscript . OutputTranscriptToAudit ( ) )
wrongTranscript := core . NewTranscript ( "wrongTranscript" )
2019-09-15 21:20:05 +00:00
verified = UnblindSignedTokenBatch ( tokens , blindedTokens , batchProof . SignedTokens , server . Y , batchProof . Proof , wrongTranscript )
2019-09-14 23:44:19 +00:00
if verified {
t . Errorf ( "Something went wrong, the proof passed with wrong transcript: %s" , wrongTranscript . OutputTranscriptToAudit ( ) )
}
2021-05-05 19:03:08 +00:00
2019-09-14 23:44:19 +00:00
}