Draft: draft-davidson-pp-protocol

Commentary: I just fixed them all ;)
A common problem on the internet is providing an effective mechanism
for servers to derive trust from the clients that it interacts with,
without hampering the accessibility of honest clients.  Typically,
this can be done by providing some sort of authorization challenge to
the client.  A client providing a correct solution to the challenge
can be provided with a cookie.  This cookie can be presented the next
time it interacts with the server.  The resurfacing of this cookie
allows the server to see that the client passed the authorization
check in the past.  Consequently, the server can re-authorize the
client again immediately, without the need for the client to complete
a new challenge.
In scenarios where clients need to identify themselves, the
authorization challenge usually take the form of some sort of login
procedure.  Otherwise, the server may just want to verify that the
client demonstrates some particular facet of behavior (such as being
human).  Such cases may only require a lightweight form of challenge
(such as completing a CAPTCHA).
In both cases, if a server issues cookies on successful completion of
challenges, then the client can use this cookie to bypass future
challenges for the lifetime of the cookie.  The downside of this
approach is that it provides the server with the ability to link all
of the client's interactions that it witnesses.  In these situations,
the client's effective privacy is dramatically reduced.
A common problem on the Internet is providing an effective mechanism
for servers to derive trust from clients they interact with, without
hampering the accessibility of honest clients.  Typically, this can
be done by providing some sort of authorization challenge to the
client.  A client that correctly solves the challenge can be provided
with a cookie.  This cookie can be presented the next time the client
interacts with the server.  The resurfacing of this cookie allows the
server to see that the client passed the authorization check in the
past.  Consequently, the server can re-authorize the client again
immediately, without the need for the client to solve a new
challenge.
In scenarios where clients need to identify themselves, the
authorization challenge usually takes the form of some sort of login
procedure.  Otherwise, the server may just want to verify that the
client demonstrates some particular facet of behavior (such as, for
example, being human).  Such cases may only require a lightweight
form of challenge (such as completing a CAPTCHA).
In both cases, if a server issues cookies on successful completion of
challenges, the client can use this cookie to bypass future
challenges presented during the lifetime of the cookie.  The downside
of this approach is that it provides the server with the ability to
link all of the client's interactions it witnesses.  In these
situations, the client's effective privacy is dramatically reduced.
The Internet performance company Cloudflare has already implemented
server-side support for an initial version of the Privacy Pass
protocol PPSRV, and client-side implementations also exist PPEXT.
More recently, a number of applications have been built upon the
protocol, or slight variants of it; see: TRUST, OpenPrivacy,
PrivateStorage.  The protocol can be instantiated using a
cryptographic primitive known as a verifiable oblivious pseudorandom
function (VOPRF) for implementing the authorization mechanism.  Such
VOPRF protocols can be implemented already in prime-order groups, and
constructions are currently being drafted in separate standardization
processes I-D.irtf-cfrg-voprf.
The Privacy Pass protocol is split into three stages.  The first
stage, initialisation, produces the global server configuration that
is broadcast to (and stored by) all clients.  The "issuance" phase
provides the client with unlinkable tokens that can be used to
initiate re-authorization with the server in the future.  The
redemption phase allows the client to redeem a given re-authorization
token with the server that it interacted with during the issuance
phase.  In addition, the protocol must satisfy two cryptographic
security requirements known as "unlinkability" and "unforgeability".
The Internet performance company Cloudflare has already implemented
server-side support for an initial version of the Privacy Pass
protocol PPSRV, and a client-side implementations is also available
PPEXT.  More recently, a number of applications have been built upon
the protocol, or upon slight variants of it; see: TRUST, OpenPrivacy,
PrivateStorage.  The protocol can be instantiated using a
cryptographic primitive known as a verifiable oblivious pseudorandom
function (VOPRF) for implementing the authorization mechanism.  Such
VOPRF protocols can be implemented over prime-order groups, and
constructions are currently being drafted in separate standardization
processes I-D.irtf-cfrg-voprf.
The Privacy Pass protocol is split into three stages.  The first
stage, initialisation, produces the global server configuration that
is broadcast to (and stored by) all clients.  The second stage, the
"issuance" phase provides the client with unlinkable tokens that can
be used to initiate re-authorization with the server in the future.
The third stage, the redemption phase, allows the client to redeem a
given re-authorization token with the server that it interacted with
during the issuance phase.  The protocol must satisfy two
cryptographic security requirements known as "unlinkability" and
"unforgeability".
Key: The secret key used by the Server for authorizing client
data.
Commitment: Alternative name for Server's public key corresponding
to the secret key that they hold.
Key: The secret key used by the Server for authorizing client data
(typically denoted key).
We make only a few minimal assumptions about the environment that the
clients and servers that support the Privacy Pass protocol.
We assume that the client has access to a global directory of the
current configurations used by all Privacy Pass servers.
We make only a few minimal assumptions about the environment of the
clients and servers supporting the Privacy Pass protocol.
We assume that the client has access to a global directory of the
current public parts of the configurations used by all servers.
The following data structures are used throughout the Privacy Pass
protocol and written in the TLS presentation language RFC8446.  It is
intended that any of these data structures can be written into
widely-adopted encoding schemes such as those detailed in TLS
RFC8446, CBOR RFC7049, and JSON RFC7159.
The following data structures are used throughout the Privacy Pass
protocol and are written in the TLS presentation language RFC8446.
It is intended that any of these data structures can be written into
widely-adopted encoding schemes such as those detailed in TLS
RFC8446, CBOR RFC7049, and JSON RFC7159.
The "ServerUpdate" struct contains the public information related to
the creation of a new "ServerConfig" message.  This is sent either
directly to clients, or indirectly via an update process.
The "ServerUpdate" struct contains the public information related to
a new "ServerConfig" message received from a server.  This is sent
either directly to clients, or indirectly via an update process.
The "ClientIssuanceInput" struct describes the data that is generated
by the client, that is necessary in sending to and processing
issuance data received from the server.
The "IssuanceMessage" struct corresponds to the message that the
client sends to the server during the issuance phase of the protocol
(issuance-phase).
In the above, "issue_element" is a vector of length "n", where "n" is
some value that must satisfy "n =< m" for "m = max_evals" that is
specified in the "ServerConfig".
The "IssuanceResponse" struct describes the data that returned by the
server, derived from the issuance message that is sent by the client.
The value of "n" is determined by the length of the
"ClientIssuanceElement" vector in the "IssuanceMessage" struct.  The
internal data types are described below.
The "RedemptionToken" struct contains the data required to generate
the client message in the redemption phase of the Privacy Pass
protocol.  This data is generated in the issuance phase of the
protocol, after receiving the "IssuanceResponse" message.
The "ClientIssuanceInput" struct describes the data that is generated
by the client, that is necessary for sending to and for processing
issuance data received from the server.
The "ClientIssuanceMessage" struct corresponds to the message that
the client sends to the server during the issuance phase of the
protocol (issuance-phase).
In the above struct, the "issue_element" variable is a vector of
length "n", where "n" is some value that must satisfy "n =< m" for "m
= max_evals", as specified in "ServerConfig".
The "ServerIssuanceResponse" struct describes the data returned by
the server that is derived from the issuance message sent by the
client.
The "RedemptionToken" struct contains the data required to generate
the client message in the redemption phase of the Privacy Pass
protocol.  This data is generated in the issuance phase of the
protocol, after receiving the "ServerIssuanceResponse" message.
The "RedemptionResponse" struct corresponds a boolean value
indicating whether the "RedemptionMessage" sent by the client is
valid, along with any associated data.
The following functions wrap the core of the functionality required
in the Privacy Pass protocol.  For each of the descriptions, we
essentially provide the function signature, leaving the actual
contents to be provided by specific instantiations or extensions.
Run by the Privacy Pass server to generate its configuration.  The
key-pair used in the server configuration are generated fresh on each
invocation.
"cfg": A "ServerConfig" struct (pp-srv-cfg-struct).
The "ServerRedemptionResponse" struct corresponds to a boolean value
that indicates whether the "ClientRedemptionMessage" sent by the
client is valid.  It can also contain any associated data.
The following functions wrap the core of the functionality required
in the Privacy Pass protocol.  For each of the descriptions, we
essentially provide the function signature, leaving the actual
contents to be defined by specific instantiations or extensions of
the protocol.
Run by the server to generate its configuration.  The key-pair used
in the server configuration is generated fresh on each invocation.
"s_cfg": A "ServerConfig" struct (pp-srv-cfg-struct).
Run by the Privacy Pass client to generate its configuration.  The
input public key "pub_key" in the client configuration MUST
correspond to a valid server public key.
"cfg": A "ClientConfig" struct (pp-cli-cfg-struct).
Run by the client to generate its configuration.  The input public
key "pub_key" in the client configuration MUST correspond to a valid
server's public key.
"cli_cfg": A "ClientConfig" struct (pp-cli-cfg-struct).
"issuance_message": A "IssuanceMessage" struct.
"issuance_message": A "ClientIssuanceMessage" struct.
"tokens": A vector of "RedemptionToken" structs, length equal to
the length of the "ServerEvaluation" vector in the
"IssuanceResponse" struct.
"tokens": A vector of "RedemptionToken" structs, which length is
equal to the length of the "ServerEvaluation" vector in the
"ServerIssuanceResponse" struct.
"response": A "RedemptionResponse" struct.
"ERR_MAX_EVALS": Client attempted to invoke server issuance with
number of inputs that is larger than server-specified max_evals
value.
"ERR_PROOF_VALIDATION": Client unable to verify proof that is part
of the server response.
"ERR_DOUBLE_SPEND": Indicates that a client has attempted to
redeem a token that has already been used for authorization.
In this document, we wan to provide a client (C) with the capability
to authenticate itself in a lightweight manner to a server (S).  The
authorization mechanism should not reveal to the server anything
about the client; in addition, the client should not be able to forge
valid credentials in situations where it does not possess any.  These
requirements are covered in sec-requirements.
"response": A "ServerRedemptionResponse" struct.
"ERR_MAX_EVALS": Error occurred when a client attempted to invoke
server issuance with a number of inputs that is larger than
server-specified max_evals value.
"ERR_PROOF_VALIDATION": Error occurred when a client attempted to
verify the proof that is part of the server's response.
"ERR_DOUBLE_SPEND": Error occurred when a client has attempted to
redeem a token that has already been used for authorization.
In this document, we want to provide a client (C) with the capability
to authenticate itself in a lightweight manner to a server (S).  The
authorization mechanism should not reveal to the server anything
about the client; in addition, the client should not be able to forge
valid credentials in situations where it does not possess any.  These
requirements are covered in sec-requirements.
In the initialisation phase, the server generates the configuration
that it will use for future instantiations of the protocol.  It MUST
broadcast the configuration that it generates, along with the public
key, so that clients are aware of which configuration to use when
interacting with the server.
In situations where the number of clients are small, it could do this
by sending the data to the client directly.  But in situations where
there is a large number of clients, the best way of doing is likely
to be via posting this information to a public bulletin board.  We
assume that the server only has a single configuration in place at
any one time.  There are privacy restrictions related to this that
are described in more detail in the architectural document draft-
davidson-pp-architecture.
In the following (and as above), we will assume that the server "S"
is uniquely identifiable by an internal attribute "id".  We assume
the same internal attribute exists for the public key
"s_cfg.pub_key".  This can be obtained, for example, by hashing the
contents of the object - either the name or underlying contained
bytes - using a collision-resistant hash function, such as SHA256.
In the initialisation phase, the server generates the configuration
that it will use for future instantiations of the protocol.  It MUST
broadcast the generated configuration, along with the public key, so
that clients are aware of which configuration to use when interacting
with the server.
In situations where the number of clients are small, a server
performs this action by sending the data to the client directly.  But
in situations where there is a large number of clients, the best way
of doing this is likely to be via posting this information in a
public bulletin board.  We assume that the server only has a single
configuration in place at any one time.  There are privacy
restrictions related to this that are described in more detail in the
architectural document draft-davidson-pp-architecture.
In the following (and as above), we will assume that the server "S"
is uniquely identifiable by an internal attribute "s_id".  We assume
the same internal attribute exists for the public key
"s_cfg.pub_key".  This id for the public key can be obtained, for
example, by hashing the contents of the object -either the name or
underlying contained bytes - using a collision-resistant hash
function, such as SHA-256.
In the diagram above, the client MUST know the supported server
configuration before it interacts with the Privacy Pass API.  The
client input "store" is used for appending redemption tokens that are
linked to the server id "S.id".
In the diagram above, the client MUST know the supported server
configuration before it interacts with the Privacy Pass API.  The
client input "store" is used for appending redemption tokens that are
linked to the server id "S.s_id".
To protect against clients that attempt to spend a value "data" more
than once, the server uses an index, "ds_idx", to collect valid
inputs and then check against in future protocols.  Since this store
needs to only be optimized for storage and querying, a structure such
as a Bloom filter suffices.  Importantly, the server MUST only eject
this storage after a key rotation occurs since all previous client
data will be rendered obsolete after such an event.
To protect against clients that attempt to spend a value "msg.data"
more than once, the server uses an index, "ds_idx", to collect valid
inputs and then check against it in future sessions.  Since this
store needs to only be optimized for storage and querying, a
structure such as a Bloom filter suffices.  Importantly, the server
MUST only eject this storage after a key rotation occurs since all
previous client data will be rendered obsolete after such an event.
The adversary runs "PP_Server_Setup" and generates a key-pair "(k,
pk)".
The adversary runs "PP_Server_Setup" and generates a key-pair
"(key, pub_key)".
When the adversary wants it stops the issuance phase, and a random
number "l" is picked from "1..Q".
When the adversary wants, it stops the issuance phase, and a
random number "l" is picked from "1..Q".
A server is created that runs "PP_Server_Setup" and broadcasts the
"ServerUpdate" message "update".
The adversary runs "PP_Client_Setup" on "update".
A server is created that runs "PP_Server_Setup" and broadcasts the
"ServerUpdate" message "s_update".
The adversary runs "PP_Client_Setup" on "s_update".
The VOPRF ciphersuite I-D.irtf-cfrg-voprf that is used determines the
member functions and prime-order group used by the protocol.  We
detail a number of specific conventions here that we use for
interacting with the specific ciphersuite.
The VOPRF ciphersuite I-D.irtf-cfrg-voprf used determines the member
functions and prime-order group used by the protocol.  We detail a
number of specific conventions here that we use for interacting with
the specific ciphersuite.
Note that the existing security proofs do not leverage the VOPRF
primitive as a black-box in the security reductions.  Instead it
relies on the underlying operations in a non-black-box manner.
Hence, an explicit reduction from the generic VOPRF primitive to the
Privacy Pass protocol would strengthen these security guarantees.
Note that the existing security proofs do not leverage the VOPRF
primitive as a black-box in the security reductions.  Instead, it
relies on the underlying operations in a non-black-box manner.
Hence, an explicit reduction from the generic VOPRF primitive to the
Privacy Pass protocol would strengthen these security guarantees.
The client should call the "CLIENT_REDEEM" interface with
"server_id", "ciphersuite", "public_key", "token" and auxilary
data of "additional_data" storing the resulting "data" and "tag".
The client should call the "CLIENT_REDEEM" interface with
"server_id", "ciphersuite", "public_key", "token" and auxiliary
data of "additional_data" storing the resulting "data" and "tag".