Skip to content

Commit 0ce0958

Browse files
feat: Updated crypto/segwit_addr to support bech32m encoding
1 parent aa77d2a commit 0ce0958

File tree

3 files changed

+247
-160
lines changed

3 files changed

+247
-160
lines changed

common/coin_support/coin_utils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ void bech32_addr_encode(char *output,
127127
uint8_t data[65] = {0};
128128
size_t datalen = 0;
129129
convert_bits(data, &datalen, 5, address_bytes, byte_len, 8, 1);
130-
bech32_encode(output, hrp, data, datalen);
130+
bech32_encode(output, hrp, data, datalen, BECH32_ENCODING_BECH32);
131131
}
132132

133133
FUNC_RETURN_CODES hd_path_array_to_string(const uint32_t *path,
Lines changed: 201 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2017 Pieter Wuille
1+
/* Copyright (c) 2017, 2021 Pieter Wuille
22
*
33
* Permission is hereby granted, free of charge, to any person obtaining a copy
44
* of this software and associated documentation files (the "Software"), to deal
@@ -18,174 +18,230 @@
1818
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1919
* THE SOFTWARE.
2020
*/
21-
#include <stdlib.h>
21+
#include "segwit_addr.h"
22+
2223
#include <stdint.h>
24+
#include <stdlib.h>
2325
#include <string.h>
2426

25-
#include "segwit_addr.h"
27+
static uint32_t bech32_polymod_step(uint32_t pre) {
28+
uint8_t b = pre >> 25;
29+
return ((pre & 0x1FFFFFF) << 5) ^ (-((b >> 0) & 1) & 0x3b6a57b2UL) ^
30+
(-((b >> 1) & 1) & 0x26508e6dUL) ^ (-((b >> 2) & 1) & 0x1ea119faUL) ^
31+
(-((b >> 3) & 1) & 0x3d4233ddUL) ^ (-((b >> 4) & 1) & 0x2a1462b3UL);
32+
}
2633

27-
uint32_t bech32_polymod_step(uint32_t pre) {
28-
uint8_t b = pre >> 25;
29-
return ((pre & 0x1FFFFFF) << 5) ^
30-
(-((b >> 0) & 1) & 0x3b6a57b2UL) ^
31-
(-((b >> 1) & 1) & 0x26508e6dUL) ^
32-
(-((b >> 2) & 1) & 0x1ea119faUL) ^
33-
(-((b >> 3) & 1) & 0x3d4233ddUL) ^
34-
(-((b >> 4) & 1) & 0x2a1462b3UL);
34+
static uint32_t bech32_final_constant(bech32_encoding enc) {
35+
if (enc == BECH32_ENCODING_BECH32)
36+
return 1;
37+
if (enc == BECH32_ENCODING_BECH32M)
38+
return 0x2bc830a3;
39+
return 0;
3540
}
3641

37-
static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
42+
static const char *charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
3843

3944
static const int8_t charset_rev[128] = {
40-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43-
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
44-
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
45-
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
46-
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
47-
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
48-
};
49-
50-
int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len) {
51-
uint32_t chk = 1;
52-
size_t i = 0;
53-
while (hrp[i] != 0) {
54-
int ch = hrp[i];
55-
if (ch < 33 || ch > 126) {
56-
return 0;
57-
}
45+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
46+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
47+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, 10, 17, 21, 20, 26, 30, 7,
48+
5, -1, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22,
49+
31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1,
50+
-1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0,
51+
3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1};
5852

59-
if (ch >= 'A' && ch <= 'Z') return 0;
60-
chk = bech32_polymod_step(chk) ^ (ch >> 5);
61-
++i;
53+
int bech32_encode(char *output,
54+
const char *hrp,
55+
const uint8_t *data,
56+
size_t data_len,
57+
bech32_encoding enc) {
58+
uint32_t chk = 1;
59+
size_t i = 0;
60+
while (hrp[i] != 0) {
61+
int ch = hrp[i];
62+
if (ch < 33 || ch > 126) {
63+
return 0;
6264
}
63-
if (i + 7 + data_len > 90) return 0;
65+
66+
if (ch >= 'A' && ch <= 'Z')
67+
return 0;
68+
chk = bech32_polymod_step(chk) ^ (ch >> 5);
69+
++i;
70+
}
71+
if (i + 7 + data_len > 90)
72+
return 0;
73+
chk = bech32_polymod_step(chk);
74+
while (*hrp != 0) {
75+
chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f);
76+
*(output++) = *(hrp++);
77+
}
78+
*(output++) = '1';
79+
for (i = 0; i < data_len; ++i) {
80+
if (*data >> 5)
81+
return 0;
82+
chk = bech32_polymod_step(chk) ^ (*data);
83+
*(output++) = charset[*(data++)];
84+
}
85+
for (i = 0; i < 6; ++i) {
6486
chk = bech32_polymod_step(chk);
65-
while (*hrp != 0) {
66-
chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f);
67-
*(output++) = *(hrp++);
68-
}
69-
*(output++) = '1';
70-
for (i = 0; i < data_len; ++i) {
71-
if (*data >> 5) return 0;
72-
chk = bech32_polymod_step(chk) ^ (*data);
73-
*(output++) = charset[*(data++)];
74-
}
75-
for (i = 0; i < 6; ++i) {
76-
chk = bech32_polymod_step(chk);
77-
}
78-
chk ^= 1;
79-
for (i = 0; i < 6; ++i) {
80-
*(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f];
81-
}
82-
*output = 0;
83-
return 1;
87+
}
88+
chk ^= bech32_final_constant(enc);
89+
for (i = 0; i < 6; ++i) {
90+
*(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f];
91+
}
92+
*output = 0;
93+
return 1;
8494
}
8595

86-
int bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) {
87-
uint32_t chk = 1;
88-
size_t i = 0;
89-
size_t input_len = strlen(input);
90-
size_t hrp_len = 0;
91-
int have_lower = 0, have_upper = 0;
92-
if (input_len < 8 || input_len > 90) {
93-
return 0;
94-
}
95-
*data_len = 0;
96-
while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') {
97-
++(*data_len);
96+
bech32_encoding bech32_decode(char *hrp,
97+
uint8_t *data,
98+
size_t *data_len,
99+
const char *input) {
100+
uint32_t chk = 1;
101+
size_t i = 0;
102+
size_t input_len = strlen(input);
103+
size_t hrp_len = 0;
104+
int have_lower = 0, have_upper = 0;
105+
if (input_len < 8) {
106+
return BECH32_ENCODING_NONE;
107+
}
108+
*data_len = 0;
109+
while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') {
110+
++(*data_len);
111+
}
112+
hrp_len = input_len - (1 + *data_len);
113+
if (1 + *data_len >= input_len || *data_len < 6 ||
114+
hrp_len > BECH32_MAX_HRP_LEN) {
115+
return BECH32_ENCODING_NONE;
116+
}
117+
*(data_len) -= 6;
118+
for (i = 0; i < hrp_len; ++i) {
119+
int ch = input[i];
120+
if (ch < 33 || ch > 126) {
121+
return BECH32_ENCODING_NONE;
98122
}
99-
hrp_len = input_len - (1 + *data_len);
100-
if (1 + *data_len >= input_len || *data_len < 6) {
101-
return 0;
123+
if (ch >= 'a' && ch <= 'z') {
124+
have_lower = 1;
125+
} else if (ch >= 'A' && ch <= 'Z') {
126+
have_upper = 1;
127+
ch = (ch - 'A') + 'a';
102128
}
103-
*(data_len) -= 6;
104-
for (i = 0; i < hrp_len; ++i) {
105-
int ch = input[i];
106-
if (ch < 33 || ch > 126) {
107-
return 0;
108-
}
109-
if (ch >= 'a' && ch <= 'z') {
110-
have_lower = 1;
111-
} else if (ch >= 'A' && ch <= 'Z') {
112-
have_upper = 1;
113-
ch = (ch - 'A') + 'a';
114-
}
115-
hrp[i] = ch;
116-
chk = bech32_polymod_step(chk) ^ (ch >> 5);
129+
hrp[i] = ch;
130+
chk = bech32_polymod_step(chk) ^ (ch >> 5);
131+
}
132+
hrp[i] = 0;
133+
chk = bech32_polymod_step(chk);
134+
for (i = 0; i < hrp_len; ++i) {
135+
chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f);
136+
}
137+
++i;
138+
while (i < input_len) {
139+
int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]];
140+
if (input[i] >= 'a' && input[i] <= 'z')
141+
have_lower = 1;
142+
if (input[i] >= 'A' && input[i] <= 'Z')
143+
have_upper = 1;
144+
if (v == -1) {
145+
return BECH32_ENCODING_NONE;
117146
}
118-
hrp[i] = 0;
119-
chk = bech32_polymod_step(chk);
120-
for (i = 0; i < hrp_len; ++i) {
121-
chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f);
147+
chk = bech32_polymod_step(chk) ^ v;
148+
if (i + 6 < input_len) {
149+
data[i - (1 + hrp_len)] = v;
122150
}
123151
++i;
124-
while (i < input_len) {
125-
int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]];
126-
if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1;
127-
if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1;
128-
if (v == -1) {
129-
return 0;
130-
}
131-
chk = bech32_polymod_step(chk) ^ v;
132-
if (i + 6 < input_len) {
133-
data[i - (1 + hrp_len)] = v;
134-
}
135-
++i;
136-
}
137-
if (have_lower && have_upper) {
138-
return 0;
139-
}
140-
return chk == 1;
152+
}
153+
if (have_lower && have_upper) {
154+
return BECH32_ENCODING_NONE;
155+
}
156+
if (chk == bech32_final_constant(BECH32_ENCODING_BECH32)) {
157+
return BECH32_ENCODING_BECH32;
158+
} else if (chk == bech32_final_constant(BECH32_ENCODING_BECH32M)) {
159+
return BECH32_ENCODING_BECH32M;
160+
} else {
161+
return BECH32_ENCODING_NONE;
162+
}
141163
}
142164

143-
int convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) {
144-
uint32_t val = 0;
145-
int bits = 0;
146-
uint32_t maxv = (((uint32_t)1) << outbits) - 1;
147-
while (inlen--) {
148-
val = (val << inbits) | *(in++);
149-
bits += inbits;
150-
while (bits >= outbits) {
151-
bits -= outbits;
152-
out[(*outlen)++] = (val >> bits) & maxv;
153-
}
165+
int convert_bits(uint8_t *out,
166+
size_t *outlen,
167+
int outbits,
168+
const uint8_t *in,
169+
size_t inlen,
170+
int inbits,
171+
int pad) {
172+
uint32_t val = 0;
173+
int bits = 0;
174+
uint32_t maxv = (((uint32_t)1) << outbits) - 1;
175+
while (inlen--) {
176+
val = (val << inbits) | *(in++);
177+
bits += inbits;
178+
while (bits >= outbits) {
179+
bits -= outbits;
180+
out[(*outlen)++] = (val >> bits) & maxv;
154181
}
155-
if (pad) {
156-
if (bits) {
157-
out[(*outlen)++] = (val << (outbits - bits)) & maxv;
158-
}
159-
} else if (((val << (outbits - bits)) & maxv) || bits >= inbits) {
160-
return 0;
182+
}
183+
if (pad) {
184+
if (bits) {
185+
out[(*outlen)++] = (val << (outbits - bits)) & maxv;
161186
}
162-
return 1;
187+
} else if (((val << (outbits - bits)) & maxv) || bits >= inbits) {
188+
return 0;
189+
}
190+
return 1;
163191
}
164192

165-
int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) {
166-
uint8_t data[65] = {0};
167-
size_t datalen = 0;
168-
if (witver > 16) return 0;
169-
if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0;
170-
if (witprog_len < 2 || witprog_len > 40) return 0;
171-
data[0] = witver;
172-
convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1);
173-
++datalen;
174-
return bech32_encode(output, hrp, data, datalen);
193+
int segwit_addr_encode(char *output,
194+
const char *hrp,
195+
int witver,
196+
const uint8_t *witprog,
197+
size_t witprog_len) {
198+
uint8_t data[65] = {0};
199+
size_t datalen = 0;
200+
bech32_encoding enc = BECH32_ENCODING_BECH32;
201+
if (witver > 16)
202+
return 0;
203+
if (witver == 0 && witprog_len != 20 && witprog_len != 32)
204+
return 0;
205+
if (witprog_len < 2 || witprog_len > 40)
206+
return 0;
207+
if (witver > 0)
208+
enc = BECH32_ENCODING_BECH32M;
209+
data[0] = witver;
210+
convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1);
211+
++datalen;
212+
return bech32_encode(output, hrp, data, datalen, enc);
175213
}
176214

177-
int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) {
178-
uint8_t data[84] = {0};
179-
char hrp_actual[84] = {0};
180-
size_t data_len = 0;
181-
if (!bech32_decode(hrp_actual, data, &data_len, addr)) return 0;
182-
if (data_len == 0 || data_len > 65) return 0;
183-
if (strncmp(hrp, hrp_actual, 84) != 0) return 0;
184-
if (data[0] > 16) return 0;
185-
*witdata_len = 0;
186-
if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0;
187-
if (*witdata_len < 2 || *witdata_len > 40) return 0;
188-
if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0;
189-
*witver = data[0];
190-
return 1;
215+
int segwit_addr_decode(int *witver,
216+
uint8_t *witdata,
217+
size_t *witdata_len,
218+
const char *hrp,
219+
const char *addr) {
220+
uint8_t data[84] = {0};
221+
char hrp_actual[84] = {0};
222+
size_t data_len = 0;
223+
if (strlen(addr) > 90)
224+
return 0;
225+
bech32_encoding enc = bech32_decode(hrp_actual, data, &data_len, addr);
226+
if (enc == BECH32_ENCODING_NONE)
227+
return 0;
228+
if (data_len == 0 || data_len > 65)
229+
return 0;
230+
if (strncmp(hrp, hrp_actual, 84) != 0)
231+
return 0;
232+
if (data[0] > 16)
233+
return 0;
234+
if (data[0] == 0 && enc != BECH32_ENCODING_BECH32)
235+
return 0;
236+
if (data[0] > 0 && enc != BECH32_ENCODING_BECH32M)
237+
return 0;
238+
*witdata_len = 0;
239+
if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0))
240+
return 0;
241+
if (*witdata_len < 2 || *witdata_len > 40)
242+
return 0;
243+
if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32)
244+
return 0;
245+
*witver = data[0];
246+
return 1;
191247
}

0 commit comments

Comments
 (0)