Commit fce18192 authored by Rusty Russell's avatar Rusty Russell

crypto/shachain: examples and some documentation.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 0020bff2
......@@ -12,6 +12,36 @@
*
* License: BSD-MIT
* Author: Rusty Russell <rusty@rustcorp.com.au>
*
* Example:
*
* #include <ccan/crypto/shachain/shachain.h>
* #include <ccan/err/err.h>
* #include <stdio.h>
* #include <stdlib.h>
* #include <string.h>
*
* int main(int argc, char *argv[])
* {
* size_t i, j, limit = 10;
* struct sha256 seed;
*
* if (argc < 2)
* errx(1, "Usage: %s <passphrase> [<num-to-generate>]", argv[0]);
* sha256(&seed, argv[1], strlen(argv[1]));
* if (argv[2])
* limit = atol(argv[2]);
*
* for (i = 0; i < limit; i++) {
* struct sha256 v;
* shachain_from_seed(&seed, i, &v);
* printf("%zu: ", i);
* for (j = 0; j < sizeof(v.u.u8); j++)
* printf("%02x", v.u.u8[j]);
* printf("\n");
* }
* return 0;
* }
*/
int main(int argc, char *argv[])
{
......
......@@ -11,9 +11,45 @@
#define shachain_index_t uint64_t
#endif
/**
* shachain_from_seed - Generate an unpredictable SHA from a seed value.
* @seed: (secret) seed value to use
* @index: index of value to generate.
* @hash: value generated
*
* There will be no way to derive the result from that generated for
* any *lesser* index.
*
* Example:
* #include <time.h>
*
* static void next_hash(struct sha256 *hash)
* {
* static uint64_t index = 0;
* static struct sha256 seed;
*
* // First time, initialize seed.
* if (index == 0) {
* // DO NOT DO THIS! Very predictable!
* time_t now = time(NULL);
* memcpy(&seed, &now, sizeof(now));
* }
*
* shachain_from_seed(&seed, index++, hash);
* }
*/
void shachain_from_seed(const struct sha256 *seed, shachain_index_t index,
struct sha256 *hash);
/**
* shachain - structure for recording/deriving incrementing chain members
* @max_index: maximum index value successfully shachain_add_hash()ed.
* @num_valid: number of known[] array valid. If non-zero, @max_index valid.
* @known: known values to allow us to derive those <= @max_index.
*
* This is sufficient storage to derive any shachain hash value previously
* added.
*/
struct shachain {
shachain_index_t max_index;
unsigned int num_valid;
......@@ -23,11 +59,70 @@ struct shachain {
} known[sizeof(shachain_index_t) * 8];
};
void shachain_init(struct shachain *shachain);
/**
* shachain_init - initialize an shachain
* @chain: the chain to initialize
*
* Alternately, ensure that it's all zero.
*/
void shachain_init(struct shachain *chain);
bool shachain_add_hash(struct shachain *shachain,
/**
* shachain_add_hash - record the hash for the next index.
* @chain: the chain to add to
* @index: the index of the hash
* @hash: the hash value.
*
* You can only add index 0 (for a freshly initialized chain), or one more
* than the previously successfully added value.
*
* This can fail (return false without altering @chain) if the hash
* for this index isn't consistent with previous hashes (ie. wasn't
* generated from the same seed), though it can't always detect that.
* If the hash is inconsistent yet undetected, the next addition will
* fail.
*
* Example:
* static void next_hash(const struct sha256 *hash)
* {
* static uint64_t index = 0;
* static struct shachain chain;
*
* if (!shachain_add_hash(&chain, index++, hash))
* errx(1, "Corrupted hash value?");
* }
*/
bool shachain_add_hash(struct shachain *chain,
shachain_index_t index, const struct sha256 *hash);
bool shachain_get_hash(const struct shachain *shachain,
/**
* shachain_get_hash - get the hash for a given index.
* @chain: the chain query
* @index: the index of the hash to get
* @hash: the hash value.
*
* This will return true and set @hash to that given in the successful
* shachain_get_hash() call for that index. If there was no
* successful shachain_get_hash() for that index, it will return
* false.
*
* Example:
* #include <ccan/structeq/structeq.h>
*
* static void next_hash(const struct sha256 *hash)
* {
* static uint64_t index = 0;
* static struct shachain chain;
*
* if (!shachain_add_hash(&chain, index++, hash))
* errx(1, "Corrupted hash value?");
* else {
* struct sha256 check;
* assert(shachain_get_hash(&chain, index-1, &check));
* assert(structeq(&check, hash));
* }
* }
*/
bool shachain_get_hash(const struct shachain *chain,
shachain_index_t index, struct sha256 *hash);
#endif /* CCAN_CRYPTO_SHACHAIN_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment