package applications import ( "encoding/json" "git.openprivacy.ca/cwtch.im/tapir" "git.openprivacy.ca/cwtch.im/tapir/primitives/privacypass" "git.openprivacy.ca/openprivacy/log" ) // TokenApplication provides Tokens for PoW type TokenApplication struct { TranscriptApp TokenService *privacypass.TokenServer Tokens []*privacypass.Token } // HasTokensCapability is granted once the client has obtained signed tokens const HasTokensCapability = tapir.Capability("HasTokensCapability") const numTokens = 10 // NewInstance should always return a new instantiation of the application. func (tokenapp *TokenApplication) NewInstance() tapir.Application { app := new(TokenApplication) app.TokenService = tokenapp.TokenService return app } // Init is run when the connection is first started. func (tokenapp *TokenApplication) Init(connection tapir.Connection) { tokenapp.Transcript().NewProtocol("token-app") log.Debugf(tokenapp.Transcript().OutputTranscriptToAudit()) if connection.IsOutbound() { tokens, blinded := privacypass.GenerateBlindedTokenBatch(numTokens) data, _ := json.Marshal(blinded) connection.Send(data) var signedBatch privacypass.SignedBatchWithProof err := json.Unmarshal(connection.Expect(), &signedBatch) if err == nil { verified := privacypass.UnblindSignedTokenBatch(tokens, blinded, signedBatch.SignedTokens, tokenapp.TokenService.Y, signedBatch.Proof, tokenapp.Transcript()) if verified { log.Debugf("Successfully obtained signed tokens") tokenapp.Tokens = tokens connection.SetCapability(HasTokensCapability) return } // This will close the connection by default and no tokens will be available. // This usecase can be checked by the existing WaitForCapabilityOrClose() function using the HasTokensCapability // If the connection closes without the HasTokensCapability then the error can be handled by whatever client needs it log.Debugf("Failed to verify signed token batch") } return } // We are the server var blinded []privacypass.BlindedToken err := json.Unmarshal(connection.Expect(), &blinded) if err == nil { batchProof, err := tokenapp.TokenService.SignBlindedTokenBatch(blinded, tokenapp.Transcript()) if err != nil { return } log.Debugf(tokenapp.Transcript().OutputTranscriptToAudit()) data, _ := json.Marshal(batchProof) connection.Send(data) return } }