diff --git a/bitcoin/varint.c b/bitcoin/varint.c index 1e97cddd3..15199b521 100644 --- a/bitcoin/varint.c +++ b/bitcoin/varint.c @@ -60,3 +60,65 @@ size_t varint_get(const u8 *p, size_t max, varint_t *val) return 1; } } + +size_t bigsize_put(u8 buf[VARINT_MAX_LEN], varint_t v) +{ + u8 *p = buf; + + if (v < 0xfd) { + *(p++) = v; + } else if (v <= 0xffff) { + (*p++) = 0xfd; + (*p++) = v >> 8; + (*p++) = v; + } else if (v <= 0xffffffff) { + (*p++) = 0xfe; + (*p++) = v >> 24; + (*p++) = v >> 16; + (*p++) = v >> 8; + (*p++) = v; + } else { + (*p++) = 0xff; + (*p++) = v >> 56; + (*p++) = v >> 48; + (*p++) = v >> 40; + (*p++) = v >> 32; + (*p++) = v >> 24; + (*p++) = v >> 16; + (*p++) = v >> 8; + (*p++) = v; + } + return p - buf; +} + +size_t bigsize_get(const u8 *p, size_t max, varint_t *val) +{ + if (max < 1) + return 0; + + switch (*p) { + case 0xfd: + if (max < 3) + return 0; + *val = ((u64)p[1] << 8) + p[2]; + return 3; + case 0xfe: + if (max < 5) + return 0; + *val = ((u64)p[1] << 24) + ((u64)p[2] << 16) + + ((u64)p[3] << 8) + p[4]; + return 5; + case 0xff: + if (max < 9) + return 0; + *val = ((u64)p[1] << 56) + ((u64)p[2] << 48) + + ((u64)p[3] << 40) + ((u64)p[4] << 32) + + ((u64)p[5] << 24) + ((u64)p[6] << 16) + + ((u64)p[7] << 8) + p[8]; + return 9; + default: + *val = *p; + return 1; + } + +} diff --git a/bitcoin/varint.h b/bitcoin/varint.h index e8e99827e..6d9003fd0 100644 --- a/bitcoin/varint.h +++ b/bitcoin/varint.h @@ -14,4 +14,13 @@ size_t varint_put(u8 buf[VARINT_MAX_LEN], varint_t v); /* Returns bytes used: 0 if max_len too small. */ size_t varint_get(const u8 *p, size_t max_len, varint_t *val); + + +/* Big-endian variant of varint_put, used in lightning */ +size_t bigsize_put(u8 buf[VARINT_MAX_LEN], varint_t v); + +/* Big-endian variant of varint_get, used in lightning */ +size_t bigsize_get(const u8 *p, size_t max, varint_t *val); + + #endif /* LIGHTNING_BITCOIN_VARINT_H */ diff --git a/common/sphinx.c b/common/sphinx.c index 904fdc2fa..5dd229cd9 100644 --- a/common/sphinx.c +++ b/common/sphinx.c @@ -454,7 +454,7 @@ static bool sphinx_write_frame(u8 *dest, const struct sphinx_hop *hop) if (hop->type == SPHINX_V0_PAYLOAD) dest[pos++] = 0x00; else - pos += varint_put(dest+pos, raw_size); + pos += bigsize_put(dest+pos, raw_size); memcpy(dest + pos, hop->payload, raw_size); pos += raw_size; @@ -618,7 +618,7 @@ struct route_step *process_onionpacket( } else { /* In addition to the raw payload we need to also shift the * length encoding itself and the HMAC away. */ - vsize = varint_get(paddedheader, 3, &shift_size); + vsize = bigsize_get(paddedheader, 3, &shift_size); shift_size += vsize + HMAC_SIZE; /* If we get an unreasonable shift size we must return an error. */