aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-07-08 03:36:17 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-07-08 03:47:48 +0200
commit78bd8a44b75cf39ea17c8a586ba35776d835551f (patch)
tree8ac165cc8166c4bfa12b5e13833f76296010f7d0 /libbb
parentd18ac080e4bb7d63e0ec0dea16bacc6ac455f390 (diff)
downloadbusybox-w32-78bd8a44b75cf39ea17c8a586ba35776d835551f.tar.gz
busybox-w32-78bd8a44b75cf39ea17c8a586ba35776d835551f.tar.bz2
busybox-w32-78bd8a44b75cf39ea17c8a586ba35776d835551f.zip
libbb/yescrypt: explain and shrink decode64_uint32()
function old new delta decode64_uint32 177 141 -36 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/yescrypt/alg-yescrypt-common.c87
-rw-r--r--libbb/yescrypt/alg-yescrypt.h2
2 files changed, 79 insertions, 10 deletions
diff --git a/libbb/yescrypt/alg-yescrypt-common.c b/libbb/yescrypt/alg-yescrypt-common.c
index e5d045058..c85b2a0b9 100644
--- a/libbb/yescrypt/alg-yescrypt-common.c
+++ b/libbb/yescrypt/alg-yescrypt-common.c
@@ -27,41 +27,106 @@ static NOINLINE const uint8_t *decode64_uint32(
27 uint32_t *dst, 27 uint32_t *dst,
28 const uint8_t *src, uint32_t val) 28 const uint8_t *src, uint32_t val)
29{ 29{
30 uint32_t start = 0, end = 47, chars = 1, bits = 0; 30 uint32_t start = 0, end = 47, bits = 0;
31 uint32_t c; 31 uint32_t c;
32 32
33 if (!src) /* prevous decode failed already? */ 33 if (!src) /* previous decode failed already? */
34 goto fail; 34 goto fail;
35 35
36 c = a2i64(*src++); 36 c = a2i64(*src++);
37 if (c > 63) 37 if (c > 63)
38 goto fail; 38 goto fail;
39 39
40// The encoding of number N:
41// start = 0 end = 47
42// If N < 48, it is encoded verbatim, else
43// N -= 48
44// start = end+1 = 48
45// end += (64-end)/2 = 55
46// If N < (end+1-start)<<6 = 8<<6, it is encoded as 48+(N>>6)|low6bits (that is, 48...55|<6bit>), else
47// N -= 8<<6
48// start = end+1 = 56
49// end += (64-end)/2 = 59
50// If N < (end+1-start)<<2*6 = 4<<12, it is encoded as 56+(N>>2*6)|low12bits (that is, 56...59|<6bit>|<6bit>), else
51// ...same for 60..61|<6bit>|<6bit>|<6bit>
52// .......same for 62|<6bit>|<6bit>|<6bit>|<6bit>
53// .......same for 63|<6bit>|<6bit>|<6bit>|<6bit>|<6bit>
54 dbg_dec64("c:%d val:0x%08x", (int)c, (unsigned)val);
40 while (c > end) { 55 while (c > end) {
56 dbg_dec64("c:%d > end:%d", (int)c, (int)end);
41 val += (end + 1 - start) << bits; 57 val += (end + 1 - start) << bits;
58 dbg_dec64("val+=0x%08x", (int)((end + 1 - start) << bits));
59 dbg_dec64(" val:0x%08x", (unsigned)val);
42 start = end + 1; 60 start = end + 1;
43 end = start + (62 - end) / 2; 61 end += (64 - end) / 2;
44 chars++;
45 bits += 6; 62 bits += 6;
63 dbg_dec64("start=%d", (int)start);
64 dbg_dec64("end=%d", (int)end);
65 dbg_dec64("bits=%d", (int)bits);
46 } 66 }
47 67
48 val += (c - start) << bits; 68 val += (c - start) << bits;
69 dbg_dec64("final val+=0x%08x", (int)((c - start) << bits));
70 dbg_dec64(" val:0x%08x", (unsigned)val);
49 71
50 while (--chars) { 72 while (bits != 0) {
51 c = a2i64(*src++); 73 c = a2i64(*src++);
52 if (c > 63) 74 if (c > 63)
53 goto fail; 75 goto fail;
54 bits -= 6; 76 bits -= 6;
55 val += c << bits; 77 val += c << bits;
78 dbg_dec64("low bits val+=0x%08x", (int)(c << bits));
79 dbg_dec64(" val:0x%08x", (unsigned)val);
56 } 80 }
81 ret:
57 *dst = val; 82 *dst = val;
58
59 return src; 83 return src;
84 fail:
85 val = 0;
86 src = NULL;
87 goto ret;
88}
60 89
61fail: 90#if TEST_DECODE64
62 *dst = 0; 91static void test_decode64_uint32(void)
63 return NULL; 92{
93 const uint8_t *src, *end;
94 uint32_t u32;
95 int a = 48;
96 int b = 8<<6; // 0x0200
97 int c = 4<<12; // 0x04000
98 int d = 2<<18; // 0x080000
99 int e = 1<<24; // 0x1000000
100
101 src = (void*)"wzzz";
102 end = decode64_uint32(&u32, src, 0);
103 if (u32 != 0x0003ffff+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32);
104 if (end != src + 4) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end);
105 src = (void*)"xzzz";
106 end = decode64_uint32(&u32, src, 0);
107 if (u32 != 0x0007ffff+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32);
108 if (end != src + 4) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end);
109 // Note how the last representable "x---" encoding, 0x7ffff, is exactly d-1!
110 // And if we now increment it, we get:
111 src = (void*)"y....";
112 end = decode64_uint32(&u32, src, 0);
113 if (u32 != 0x00000000+d+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32);
114 if (end != src + 5) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end);
115 src = (void*)"yzzzz";
116 end = decode64_uint32(&u32, src, 0);
117 if (u32 != 0x00ffffff+d+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32);
118 if (end != src + 5) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end);
119
120 src = (void*)"zzzzzz";
121 end = decode64_uint32(&u32, src, 0);
122 if (u32 != 0x3fffffff+e+d+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32);
123 if (end != src + 6) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end);
124
125 bb_error_msg("test_decode64_uint32() OK");
64} 126}
127#else
128# define test_decode64_uint32() ((void)0)
129#endif
65 130
66#if 1 131#if 1
67static const uint8_t *decode64( 132static const uint8_t *decode64(
@@ -70,7 +135,7 @@ static const uint8_t *decode64(
70{ 135{
71 size_t dstpos = 0; 136 size_t dstpos = 0;
72 137
73 dbg_dec64("src:'%s' len:%d", src, (int)srclen); 138 dbg_dec64("src:'%s'", src);
74 for (;;) { 139 for (;;) {
75 uint32_t c, value = 0; 140 uint32_t c, value = 0;
76 int bits = 0; 141 int bits = 0;
@@ -215,6 +280,8 @@ char *yescrypt_r(
215 size_t need, prefixlen; 280 size_t need, prefixlen;
216 uint32_t u32; 281 uint32_t u32;
217 282
283 test_decode64_uint32();
284
218 memset(yctx, 0, sizeof(yctx)); 285 memset(yctx, 0, sizeof(yctx));
219 yctx->param.p = 1; 286 yctx->param.p = 1;
220 287
diff --git a/libbb/yescrypt/alg-yescrypt.h b/libbb/yescrypt/alg-yescrypt.h
index 4554e3de3..e558cfdc5 100644
--- a/libbb/yescrypt/alg-yescrypt.h
+++ b/libbb/yescrypt/alg-yescrypt.h
@@ -28,6 +28,7 @@
28 * online backup system. 28 * online backup system.
29 */ 29 */
30#ifdef YESCRYPT_INTERNAL 30#ifdef YESCRYPT_INTERNAL
31
31# if 1 32# if 1
32# define dbg(...) ((void)0) 33# define dbg(...) ((void)0)
33# else 34# else
@@ -39,6 +40,7 @@
39# define dbg_dec64(...) bb_error_msg(__VA_ARGS__) 40# define dbg_dec64(...) bb_error_msg(__VA_ARGS__)
40# endif 41# endif
41#endif 42#endif
43#define TEST_DECODE64 0
42 44
43/** 45/**
44 * Type and possible values for the flags argument of yescrypt_kdf(), 46 * Type and possible values for the flags argument of yescrypt_kdf(),