mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
common/codex32: Add codex32_secret_encode to encode seeds in bip93 format.
This commit is contained in:
parent
38ee765922
commit
d00efbccde
@ -166,6 +166,13 @@ static void input_data_str(u8 *generator, u8 *residue, const char *datastr, size
|
||||
return;
|
||||
}
|
||||
|
||||
static void input_own_target(const u8 *generator, u8 *residue, const u8 *target, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
input_fe(generator, residue, target[i], len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper to verify codex32 checksum */
|
||||
static bool checksum_verify(const char *hrp, const char *codex_datastr,
|
||||
const struct checksum_engine *initial_engine)
|
||||
@ -178,6 +185,19 @@ static bool checksum_verify(const char *hrp, const char *codex_datastr,
|
||||
return memcmp(engine.target, engine.residue, engine.len) == 0;
|
||||
}
|
||||
|
||||
static void calculate_checksum(const char *hrp, char *csum, const char *codex_datastr,
|
||||
const struct checksum_engine *initial_engine)
|
||||
{
|
||||
struct checksum_engine engine = *initial_engine;
|
||||
|
||||
input_hrp(engine.generator, engine.residue, hrp, engine.len);
|
||||
input_data_str(engine.generator, engine.residue, codex_datastr, engine.len);
|
||||
input_own_target(engine.generator, engine.residue, engine.target, engine.len);
|
||||
|
||||
for (size_t i = 0; i < engine.len; i++)
|
||||
csum[i] = bech32_charset[engine.residue[i]];
|
||||
}
|
||||
|
||||
/* Pull len chars from cursor into dst. */
|
||||
static bool pull_chars(char *dst, size_t len, const char **cursor, size_t *max)
|
||||
{
|
||||
@ -374,3 +394,47 @@ struct codex32 *codex32_decode(const tal_t *ctx,
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
/* Returns Codex32 encoded secret of the seed provided. */
|
||||
char *codex32_secret_encode(const tal_t *ctx,
|
||||
const char *id,
|
||||
const u32 threshold,
|
||||
const u8 *seed,
|
||||
size_t seedlen)
|
||||
{
|
||||
const struct checksum_engine *csum_engine;
|
||||
const char *hrp = "ms";
|
||||
assert(threshold <= 9 && threshold >= 0 &&
|
||||
threshold != 1 && strlen(id) == 4);
|
||||
|
||||
/* Every codex32 has hrp `ms` and since we are generating a
|
||||
* secret it's share index would be `s` and threshold given by user. */
|
||||
char *ret = tal_fmt(ctx, "%s1%d%ss", hrp, threshold, id);
|
||||
|
||||
uint8_t next_u5 = 0, rem = 0;
|
||||
|
||||
for (size_t i = 0; i < seedlen; i++) {
|
||||
/* Each byte provides at least one u5. Push that. */
|
||||
uint8_t u5 = (next_u5 << (5 - rem)) | seed[i] >> (3 + rem);
|
||||
|
||||
tal_append_fmt(&ret, "%c", bech32_charset[u5]);
|
||||
next_u5 = seed[i] & ((1 << (3 + rem)) - 1);
|
||||
|
||||
/* If there were 2 or more bits from the last iteration, then
|
||||
* this iteration will push *two* u5s. */
|
||||
if(rem >= 2) {
|
||||
tal_append_fmt(&ret, "%c", bech32_charset[next_u5 >> (rem - 2)]);
|
||||
next_u5 &= (1 << (rem - 2)) - 1;
|
||||
}
|
||||
rem = (rem + 8) % 5;
|
||||
}
|
||||
if(rem > 0) {
|
||||
tal_append_fmt(&ret, "%c", bech32_charset[next_u5 << (5 - rem)]);
|
||||
}
|
||||
|
||||
csum_engine = &initial_engine_csum[seedlen >= 51];
|
||||
char csum[csum_engine->len];
|
||||
calculate_checksum(hrp, csum, ret + 3, csum_engine);
|
||||
tal_append_fmt(&ret, "%.*s", (int)csum_engine->len, csum);
|
||||
return ret;
|
||||
}
|
||||
|
@ -40,4 +40,20 @@ struct codex32 *codex32_decode(const tal_t *ctx,
|
||||
const char *codex32str,
|
||||
char **fail);
|
||||
|
||||
/** Encode a seed into codex32 secret format.
|
||||
*
|
||||
* Out: char *: String containing the codex32 (BIP93) format secret.
|
||||
* fail: Asserting error if invalid threshold is used.
|
||||
* In: input: id: Valid 4 char string identifying the secret
|
||||
* threshold: Threshold according to the bip93
|
||||
* seed: The secret in u8*
|
||||
* seedlen: Length of the seed provided.
|
||||
* Returns a string which contains the seed provided in bip93 format.
|
||||
*/
|
||||
char *codex32_secret_encode(const tal_t *ctx,
|
||||
const char *id,
|
||||
const u32 threshold,
|
||||
const u8 *seed,
|
||||
size_t seedlen);
|
||||
|
||||
#endif /* LIGHTNING_COMMON_CODEX32_H */
|
||||
|
@ -125,6 +125,18 @@ int main(int argc, char *argv[])
|
||||
char *fail;
|
||||
struct codex32 *parts;
|
||||
|
||||
/* Test vector for codex32_secret_encode*/
|
||||
u8 seed_b[32] = {
|
||||
0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
|
||||
0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00,
|
||||
0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
|
||||
0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00,
|
||||
};
|
||||
|
||||
char *c = codex32_secret_encode(tmpctx, "leet", 0, seed_b, ARRAY_SIZE(seed_b));
|
||||
assert(streq(c,
|
||||
"ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqqtum9pgv99ycma"));
|
||||
|
||||
/*
|
||||
* Test vector 1
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user