| // Copyright 2023 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| syntax = "proto3"; |
| |
| package anonymous_tokens; |
| |
| message Timestamp { |
| int64 seconds = 1; |
| int32 nanos = 2; |
| } |
| |
| // Different use cases for the Anonymous Tokens service. |
| // Next ID: 11 |
| enum AnonymousTokensUseCase { |
| // Test use cases here. |
| ANONYMOUS_TOKENS_USE_CASE_UNDEFINED = 0; |
| TEST_USE_CASE = 1; |
| TEST_USE_CASE_2 = 2; |
| TEST_USE_CASE_3 = 4; |
| TEST_USE_CASE_4 = 5; |
| TEST_USE_CASE_5 = 6; |
| TEST_USE_CASE_6 = 9; |
| |
| PROVABLY_PRIVATE_NETWORK = 3; |
| CHROME_IP_BLINDING = 7; |
| NOCTOGRAM_PPISSUER = 8; |
| CHROME_IP_BLINDING_DARKLAUNCH = 10; |
| } |
| |
| // An enum describing different types of available hash functions. |
| enum HashType { |
| AT_HASH_TYPE_UNDEFINED = 0; |
| AT_TEST_HASH_TYPE = 1; |
| AT_HASH_TYPE_SHA256 = 2; |
| AT_HASH_TYPE_SHA384 = 3; |
| // Add more hash types if necessary. |
| } |
| |
| // An enum describing different types of hash functions that can be used by the |
| // mask generation function. |
| enum MaskGenFunction { |
| AT_MGF_UNDEFINED = 0; |
| AT_TEST_MGF = 1; |
| AT_MGF_SHA256 = 2; |
| AT_MGF_SHA384 = 3; |
| // Add more hash types if necessary. |
| } |
| |
| // An enum describing different types of message masking. |
| enum MessageMaskType { |
| AT_MESSAGE_MASK_TYPE_UNDEFINED = 0; |
| AT_MESSAGE_MASK_XOR = 1; |
| AT_MESSAGE_MASK_CONCAT = 2; |
| AT_MESSAGE_MASK_NO_MASK = 3; |
| } |
| |
| // Proto representation for RSA private key. |
| message RSAPrivateKey { |
| // Modulus. |
| bytes n = 1; |
| // Public exponent. |
| bytes e = 2; |
| // Private exponent. |
| bytes d = 3; |
| // The prime factor p of n. |
| bytes p = 4; |
| // The prime factor q of n. |
| bytes q = 5; |
| // d mod (p - 1). |
| bytes dp = 6; |
| // d mod (q - 1). |
| bytes dq = 7; |
| // Chinese Remainder Theorem coefficient q^(-1) mod p. |
| bytes crt = 8; |
| } |
| |
| // Proto representation for RSA public key. |
| message RSAPublicKey { |
| // Modulus. |
| bytes n = 1; |
| // Public exponent. |
| bytes e = 2; |
| } |
| |
| // Next ID: 13 |
| message RSABlindSignaturePublicKey { |
| // Use case associated with this public key. |
| bytes use_case = 9; |
| |
| // Version number of public key. |
| int64 key_version = 1; |
| |
| // Serialization of the public key. |
| bytes serialized_public_key = 2; |
| |
| // Timestamp of expiration. |
| // |
| // Note that we will not return keys whose expiration times are in the past. |
| Timestamp expiration_time = 3; |
| |
| // Key becomes valid at key_validity_start_time. |
| Timestamp key_validity_start_time = 8; |
| |
| // Hash function used in computing hash of the signing message |
| // (see https://tools.ietf.org/html/rfc8017#section-9.1.1) |
| HashType sig_hash_type = 4; |
| |
| // Hash function used in MGF1 (a mask generation function based on a |
| // hash function) (see https://tools.ietf.org/html/rfc8017#appendix-B.2.1). |
| MaskGenFunction mask_gen_function = 5; |
| |
| // Length in bytes of the salt (see |
| // https://tools.ietf.org/html/rfc8017#section-9.1.1) |
| int64 salt_length = 6; |
| |
| // Key size: bytes of RSA key. |
| int64 key_size = 7; |
| |
| // Type of masking of message (see https://eprint.iacr.org/2022/895.pdf). |
| MessageMaskType message_mask_type = 10; |
| |
| // Length of message mask in bytes. |
| int64 message_mask_size = 11; |
| |
| // Conveys whether public metadata support is enabled and RSA blind signatures |
| // with public metadata protocol should be used. If false, standard RSA blind |
| // signatures are used and all public metadata inputs are ignored. |
| bool public_metadata_support = 12; |
| } |
| |
| message AnonymousTokensPublicKeysGetRequest { |
| // Use case associated with this request. |
| // |
| // Returns an error if the token type does not support public key verification |
| // for the requested use_case. |
| bytes use_case = 1; |
| |
| // Key version associated with this request. |
| // |
| // Returns an error if the token type does not support public key verification |
| // for the requested use_case and key_version combination. |
| // |
| // If unset, all valid possibilities for the key are returned. |
| int64 key_version = 2; |
| |
| // Public key that becomes valid at or before this requested time and not |
| // after. More explicitly, we need the requested key to be valid at the |
| // requested key_validity_start_time. |
| // |
| // If unset it will be set to current time. |
| Timestamp key_validity_start_time = 3 |
| ; |
| |
| // Public key that is definitely not valid after this particular time. If |
| // unset / null, only keys that are indefinitely valid are returned. |
| // |
| // Note: It is possible that the key becomes invalid before this time. But the |
| // key should not be valid after this time. |
| Timestamp key_validity_end_time = 4 |
| ; |
| } |
| |
| message AnonymousTokensPublicKeysGetResponse { |
| // List of currently valid RSA public keys. |
| repeated RSABlindSignaturePublicKey rsa_public_keys = 1; |
| } |
| |
| message AnonymousTokensSignRequest { |
| // Next ID: 6 |
| message BlindedToken { |
| // Use case associated with this request. |
| bytes use_case = 1; |
| |
| // Version of key used to sign and generate the token. |
| int64 key_version = 2; |
| |
| // Public metadata to be tied to the `blinded message` (serialized_token). |
| // |
| // The length of public metadata must be at most 2^32 bytes. |
| bytes public_metadata = 4; |
| |
| // This value is disregarded for standard blind RSA signatures. |
| // |
| // For the public metadata protocol, if this value is set to false, the |
| // final public exponent is derived by using the RSA public exponent, the |
| // RSA modulus and the public metadata. If this value is set to true, only |
| // the RSA modulus and the public metadata will be used. |
| bool do_not_use_rsa_public_exponent = 5; |
| |
| // Serialization of the token. |
| bytes serialized_token = 3; |
| } |
| |
| // Token(s) that have been blinded by the user, not yet signed |
| repeated BlindedToken blinded_tokens = 1; |
| } |
| |
| message AnonymousTokensSignResponse { |
| // Next ID: 7 |
| message AnonymousToken { |
| // Use case associated with this anonymous token. |
| bytes use_case = 1; |
| |
| // Version of key used to sign and generate the token. |
| int64 key_version = 2; |
| |
| // Public metadata tied to the input (serialized_blinded_message) and the |
| // `blinded` signature (serialized_token). |
| // |
| // The length of public metadata must fit in 4 bytes. |
| bytes public_metadata = 4; |
| |
| // This value is disregarded for standard blind RSA signatures. |
| // |
| // For the public metadata protocol, if this value is set to false, the |
| // final public exponent is derived by using the RSA public exponent, the |
| // RSA modulus and the public metadata. If this value is set to true, only |
| // the RSA modulus and the public metadata will be used. |
| bool do_not_use_rsa_public_exponent = 6; |
| |
| // The serialized_token in BlindedToken in the AnonymousTokensSignRequest. |
| bytes serialized_blinded_message = 5; |
| |
| // Serialization of the signed token. This will have to be `unblinded` by |
| // the user before it can be used / redeemed. |
| bytes serialized_token = 3; |
| } |
| |
| // Returned anonymous token(s) |
| repeated AnonymousToken anonymous_tokens = 1; |
| } |
| |
| message AnonymousTokensRedemptionRequest { |
| // Next ID: 7 |
| message AnonymousTokenToRedeem { |
| // Use case associated with this anonymous token that needs to be redeemed. |
| bytes use_case = 1; |
| |
| // Version of key associated with this anonymous token that needs to be |
| // redeemed. |
| int64 key_version = 2; |
| |
| // Public metadata to be used for redeeming the signature |
| // (serialized_unblinded_token). |
| // |
| // The length of public metadata must fit in 4 bytes. |
| bytes public_metadata = 4; |
| |
| // Serialization of the unblinded anonymous token that needs to be redeemed. |
| bytes serialized_unblinded_token = 3; |
| |
| // Plaintext input message to verify the signature for. |
| bytes plaintext_message = 5; |
| |
| // Nonce used to mask plaintext message before cryptographic verification. |
| bytes message_mask = 6; |
| } |
| |
| // One or more anonymous tokens to redeem. |
| repeated AnonymousTokenToRedeem anonymous_tokens_to_redeem = 1; |
| } |
| |
| message AnonymousTokensRedemptionResponse { |
| // Next ID: 9 |
| message AnonymousTokenRedemptionResult { |
| // Use case associated with this redeemed anonymous token. |
| bytes use_case = 3; |
| |
| // Version of key associated with this redeemed anonymous token. |
| int64 key_version = 4; |
| |
| // Public metadata used for verifying the signature |
| // (serialized_unblinded_token). |
| // |
| // The length of public metadata must fit in 4 bytes. |
| bytes public_metadata = 5; |
| |
| // Serialization of this redeemed unblinded anonymous token. |
| bytes serialized_unblinded_token = 6; |
| |
| // Unblinded input message that the signature was verified against. |
| bytes plaintext_message = 7; |
| |
| // Nonce used to mask plaintext message before cryptographic verification. |
| bytes message_mask = 8; |
| |
| // Returns true if and only if the anonymous token was redeemed |
| // successfully i.e. token was cryptographically verified, all relevant |
| // state in the server was updated successfully and the token was not |
| // redeemed already. |
| // |
| bool verified = 1; |
| |
| // Returns true if and only if the anonymous token has already been |
| // redeemed. |
| bool double_spent = 2; |
| } |
| |
| // Redemption response for requested anonymous tokens. |
| repeated AnonymousTokenRedemptionResult anonymous_token_redemption_results = |
| 1; |
| } |
| |
| // Plaintext message with public metadata. |
| message PlaintextMessageWithPublicMetadata { |
| // Message to be signed. |
| bytes plaintext_message = 1; |
| |
| // Public metadata to be tied to the signature. |
| bytes public_metadata = 2; |
| } |
| |
| // Proto representing a token created during the blind signing protocol. |
| message RSABlindSignatureToken { |
| // Resulting token from the blind signing protocol. |
| bytes token = 1; |
| |
| // Nonce used to mask messages. |
| bytes message_mask = 2; |
| } |
| |
| // Proto representing a token along with the input. |
| message RSABlindSignatureTokenWithInput { |
| // Input consisting of plaintext message and public metadata. |
| PlaintextMessageWithPublicMetadata input = 1; |
| |
| // Resulting token after blind signing protocol. |
| RSABlindSignatureToken token = 2; |
| } |
| |
| // Proto representing redemption result along with the token and the token |
| // input. |
| message RSABlindSignatureRedemptionResult { |
| // Proto representing a token along with the input. |
| RSABlindSignatureTokenWithInput token_with_input = 1; |
| |
| // This is set to true if and only if the anonymous token was redeemed |
| // successfully i.e. token was cryptographically verified, all relevant |
| // state in the redemption server was updated successfully and the token was |
| // not redeemed already. |
| bool redeemed = 2; |
| |
| // True if and only if the token was redeemed before. |
| bool double_spent = 3; |
| } |