Browse Source

crypto/shachain: examples and some documentation.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 10 years ago
parent
commit
fce1819222
2 changed files with 128 additions and 3 deletions
  1. 30 0
      ccan/crypto/shachain/_info
  2. 98 3
      ccan/crypto/shachain/shachain.h

+ 30 - 0
ccan/crypto/shachain/_info

@@ -12,6 +12,36 @@
  *
  *
  * License: BSD-MIT
  * License: BSD-MIT
  * Author: Rusty Russell <rusty@rustcorp.com.au>
  * 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[])
 int main(int argc, char *argv[])
 {
 {

+ 98 - 3
ccan/crypto/shachain/shachain.h

@@ -11,9 +11,45 @@
 #define shachain_index_t uint64_t
 #define shachain_index_t uint64_t
 #endif
 #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,
 void shachain_from_seed(const struct sha256 *seed, shachain_index_t index,
 			struct sha256 *hash);
 			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 {
 struct shachain {
 	shachain_index_t max_index;
 	shachain_index_t max_index;
 	unsigned int num_valid;
 	unsigned int num_valid;
@@ -23,11 +59,70 @@ struct shachain {
 	} known[sizeof(shachain_index_t) * 8];
 	} 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);
 		       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);
 		       shachain_index_t index, struct sha256 *hash);
 #endif /* CCAN_CRYPTO_SHACHAIN_H */
 #endif /* CCAN_CRYPTO_SHACHAIN_H */