Generalise deterministic key generation

This commit is contained in:
Jeremy Lakeman 2016-11-14 16:25:51 +10:30
parent 3726fe2f73
commit c05775a320
5 changed files with 36 additions and 31 deletions

View File

@ -68,4 +68,29 @@ int crypto_verify_message(struct subscriber *subscriber, unsigned char *message,
return 0;
}
int crypto_seed_keypair(sign_keypair_t *keypair, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
int n = vsnprintf(NULL, 0, fmt, ap);
if (n<0)
return WHYF_perror("vsnprintf(%s, ...)", fmt);
va_end(ap);
char str_seed[n+1];
va_start(ap, fmt);
if (vsnprintf(str_seed, sizeof str_seed, fmt, ap)<0)
return WHYF_perror("vsnprintf(%s, ...)", fmt);
va_end(ap);
union {
unsigned char hash[crypto_hash_sha512_BYTES];
sign_private_t seed;
} u;
// The first 256 bits (32 bytes) of the hash will be used as the seed bytes
crypto_hash_sha512(u.hash, (uint8_t *)str_seed, n);
crypto_sign_seed_keypair(keypair->public_key.binary, keypair->binary, u.seed.binary);
return 0;
}

View File

@ -27,5 +27,6 @@ int crypto_isvalid_keypair(const sign_private_t *private_key, const sign_public_
int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, size_t *message_len);
int crypto_sign_to_sid(const sign_public_t *public_key, sid_t *sid);
int crypto_ismatching_sign_sid(const sign_public_t *public_key, const sid_t *sid);
int crypto_seed_keypair(sign_keypair_t *key, const char *fmt, ...);
#endif

View File

@ -46,10 +46,13 @@ void meshms_free_conversations(struct meshms_conversations *conv)
static enum meshms_status get_my_conversation_bundle(const keyring_identity *id, rhizome_manifest *m)
{
/* Find our private key */
struct rhizome_bundle_result result = rhizome_private_bundle(m,
sign_keypair_t key;
crypto_seed_keypair(&key,
"incorrection%sconcentrativeness",
alloca_tohex(id->box_sk, crypto_box_SECRETKEYBYTES));
struct rhizome_bundle_result result = rhizome_private_bundle(m, &key);
switch (result.status) {
case RHIZOME_BUNDLE_STATUS_NEW:
case RHIZOME_BUNDLE_STATUS_SAME:

View File

@ -371,7 +371,7 @@ int rhizome_cleanup(struct rhizome_cleanup_report *report);
int rhizome_store_cleanup(struct rhizome_cleanup_report *report);
void rhizome_vacuum_db(sqlite_retry_state *retry);
int rhizome_manifest_createid(rhizome_manifest *m);
struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const char *fmt, ...);
struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const sign_keypair_t *keypair);
void rhizome_new_bundle_from_secret(rhizome_manifest *m, const rhizome_bk_t *bsk);
struct rhizome_manifest_summary {

View File

@ -41,37 +41,13 @@ int rhizome_manifest_createid(rhizome_manifest *m)
/* Generate a bundle id deterministically from the given seed.
* Then either fetch it from the database or initialise a new empty manifest */
struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const char *fmt, ...)
struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const sign_keypair_t *keypair)
{
va_list ap;
va_start(ap, fmt);
int n = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
char seed[n+1];
va_start(ap, fmt);
vsnprintf(seed, sizeof seed, fmt, ap);
va_end(ap);
union {
unsigned char hash[crypto_hash_sha512_BYTES];
sign_private_t bsk;
} u;
crypto_hash_sha512(u.hash, (uint8_t *)seed, n);
// The first 256 bits (32 bytes) of the hash will be used as the private key of the BID.
sign_keypair_t sk;
rhizome_bid_t bid;
crypto_sign_seed_keypair(bid.binary, sk.binary, u.bsk.binary);
enum rhizome_bundle_status ret = rhizome_retrieve_manifest(&bid, m);
enum rhizome_bundle_status ret = rhizome_retrieve_manifest(&keypair->public_key, m);
switch(ret){
case RHIZOME_BUNDLE_STATUS_NEW:
rhizome_manifest_set_id(m, &bid); // zerofills m->keypair.binary
m->keypair = sk;
rhizome_manifest_set_id(m, &keypair->public_key); // zerofills m->keypair.binary
m->keypair = *keypair;
m->haveSecret = NEW_BUNDLE_ID;
rhizome_manifest_set_service(m, RHIZOME_SERVICE_FILE);
rhizome_manifest_set_name(m, "");
@ -81,7 +57,7 @@ struct rhizome_bundle_result rhizome_private_bundle(rhizome_manifest *m, const c
return rhizome_fill_manifest(m, NULL);
case RHIZOME_BUNDLE_STATUS_SAME:
m->haveSecret = EXISTING_BUNDLE_ID;
m->keypair = sk;
m->keypair = *keypair;
// always consider the content encrypted, we don't need to rely on the manifest itself.
rhizome_manifest_set_crypt(m, PAYLOAD_ENCRYPTED);
if (strcmp(m->service, RHIZOME_SERVICE_FILE) != 0)