commit c4ba4d4cc8a1d31f78d1dc54c7851bed32a25e5c Author: David Goulet dgoulet@torproject.org Date: Thu May 11 10:16:28 2017 -0400
prop224: Implement subcredential creation
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/hs_common.c | 37 +++++++++++++++++++++++++++++++++++++ src/or/hs_common.h | 10 ++++++++++ 2 files changed, 47 insertions(+)
diff --git a/src/or/hs_common.c b/src/or/hs_common.c index 631e4b711..102e4689f 100644 --- a/src/or/hs_common.c +++ b/src/or/hs_common.c @@ -500,6 +500,43 @@ hs_parse_address_impl(const char *address, ed25519_public_key_t *key_out, tor_assert(offset == HS_SERVICE_ADDR_LEN); }
+/* Using the given identity public key and a blinded public key, compute the + * subcredential and put it in subcred_out. This can't fail. */ +void +hs_get_subcredential(const ed25519_public_key_t *identity_pk, + const ed25519_public_key_t *blinded_pk, + uint8_t *subcred_out) +{ + uint8_t credential[DIGEST256_LEN]; + crypto_digest_t *digest; + + tor_assert(identity_pk); + tor_assert(blinded_pk); + tor_assert(subcred_out); + + /* First, build the credential. Construction is as follow: + * credential = H("credential" | public-identity-key) */ + digest = crypto_digest256_new(DIGEST_SHA3_256); + crypto_digest_add_bytes(digest, HS_CREDENTIAL_PREFIX, + HS_CREDENTIAL_PREFIX_LEN); + crypto_digest_add_bytes(digest, (const char *) identity_pk->pubkey, + ED25519_PUBKEY_LEN); + crypto_digest_get_digest(digest, (char *) credential, DIGEST256_LEN); + crypto_digest_free(digest); + + /* Now, compute the subcredential. Construction is as follow: + * subcredential = H("subcredential" | credential | blinded-public-key). */ + digest = crypto_digest256_new(DIGEST_SHA3_256); + crypto_digest_add_bytes(digest, HS_SUBCREDENTIAL_PREFIX, + HS_SUBCREDENTIAL_PREFIX_LEN); + crypto_digest_add_bytes(digest, (const char *) credential, + sizeof(credential)); + crypto_digest_add_bytes(digest, (const char *) blinded_pk->pubkey, + ED25519_PUBKEY_LEN); + crypto_digest_get_digest(digest, (char *) subcred_out, DIGEST256_LEN); + crypto_digest_free(digest); +} + /* Using a base32 representation of a service address, parse its content into * the key_out, checksum_out and version_out. Any out variable can be NULL in * case the caller would want only one field. checksum_out MUST at least be 2 diff --git a/src/or/hs_common.h b/src/or/hs_common.h index bda91515b..6abcd9831 100644 --- a/src/or/hs_common.h +++ b/src/or/hs_common.h @@ -95,6 +95,12 @@ #define HS_KEYBLIND_NONCE_LEN \ (HS_KEYBLIND_NONCE_PREFIX_LEN + sizeof(uint64_t) + sizeof(uint64_t))
+/* Credential and subcredential prefix value. */ +#define HS_CREDENTIAL_PREFIX "credential" +#define HS_CREDENTIAL_PREFIX_LEN (sizeof(HS_CREDENTIAL_PREFIX) - 1) +#define HS_SUBCREDENTIAL_PREFIX "subcredential" +#define HS_SUBCREDENTIAL_PREFIX_LEN (sizeof(HS_SUBCREDENTIAL_PREFIX) - 1) + /* Type of authentication key used by an introduction point. */ typedef enum { HS_AUTH_KEY_TYPE_LEGACY = 1, @@ -139,6 +145,10 @@ const char *rend_data_get_desc_id(const rend_data_t *rend_data, const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out);
+void hs_get_subcredential(const ed25519_public_key_t *identity_pk, + const ed25519_public_key_t *blinded_pk, + uint8_t *subcred_out); + uint64_t hs_get_time_period_num(time_t now); uint64_t hs_get_next_time_period_num(time_t now);
tor-commits@lists.torproject.org