diff --git a/lightningd/signmessage.c b/lightningd/signmessage.c index e5144aeff..860cffab7 100644 --- a/lightningd/signmessage.c +++ b/lightningd/signmessage.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -9,6 +10,31 @@ #include #include +/* These tables copied from zbase32 src: + * copyright 2002-2007 Zooko "Zooko" Wilcox-O'Hearn + * mailto:zooko@zooko.com + * + * Permission is hereby granted to any person obtaining a copy of this work to + * deal in this work without restriction (including the rights to use, modify, + * distribute, sublicense, and/or sell copies). + */ +static const char*const zbase32_chars="ybndrfg8ejkmcpqxot1uwisza345h769"; + +static const char *to_zbase32(const tal_t *ctx, const u8 *msg, size_t srclen) +{ + size_t outlen; + char *out = tal_arr(ctx, char, (srclen * 8 + 4) / 5 + 1); + + outlen = 0; + if (!bech32_convert_bits((uint8_t *)out, &outlen, 5, msg, srclen, 8, true)) + return tal_free(out); + assert(outlen < tal_bytelen(out)); + for (size_t i = 0; i < outlen; i++) + out[i] = zbase32_chars[(unsigned)out[i]]; + out[outlen] = '\0'; + return out; +} + static struct command_result *json_signmessage(struct command *cmd, const char *buffer, const jsmntok_t *obj UNNEEDED, @@ -17,7 +43,7 @@ static struct command_result *json_signmessage(struct command *cmd, const char *message; secp256k1_ecdsa_recoverable_signature rsig; struct json_stream *response; - u8 sig[64], recidu8, *msg; + u8 sig[65], *msg; int recid; if (!param(cmd, buffer, params, @@ -41,12 +67,22 @@ static struct command_result *json_signmessage(struct command *cmd, tal_hex(msg, msg)); secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_ctx, - sig, &recid, + sig+1, &recid, &rsig); response = json_stream_success(cmd); - json_add_hex(response, "signature", sig, sizeof(sig)); - recidu8 = recid; - json_add_hex(response, "recid", &recidu8, sizeof(recidu8)); + json_add_hex(response, "signature", sig+1, sizeof(sig)-1); + sig[0] = recid; + json_add_hex(response, "recid", sig, 1); + + /* From https://twitter.com/rusty_twit/status/1182102005914800128: + * @roasbeef & @bitconner point out that #lnd algo is: + * zbase32(SigRec(SHA256(SHA256("Lightning Signed Message:" + msg)))). + * zbase32 from https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt + * and SigRec has first byte 31 + recovery id, followed by 64 byte sig. + * #specinatweet */ + sig[0] += 31; + json_add_string(response, "zbase", + to_zbase32(response, sig, sizeof(sig))); return command_success(cmd, response); }