Skip to content

Commit 6e5b7d5

Browse files
jonasnickreal-or-randomroconnor-blockstream
committed
fixup! hsort
Co-authored-by: Tim Ruffing <crypto@timruffing.de> Co-authored-by: Russell O'Connor <roconnor@blockstream.io>
1 parent 4520d75 commit 6e5b7d5

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

src/hsort_impl.h

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,26 @@ static SECP256K1_INLINE size_t secp256k1_heap_child2(size_t i) {
2323
return secp256k1_heap_child1(i)+1;
2424
}
2525

26-
static SECP256K1_INLINE void secp256k1_heap_swap64(unsigned char *a, size_t i, size_t j, size_t stride) {
26+
static SECP256K1_INLINE void secp256k1_heap_swap64(unsigned char *a, unsigned char *b, size_t len) {
2727
unsigned char tmp[64];
28-
VERIFY_CHECK(stride <= 64);
29-
memcpy(tmp, a + i*stride, stride);
30-
memmove(a + i*stride, a + j*stride, stride);
31-
memcpy(a + j*stride, tmp, stride);
28+
VERIFY_CHECK(len <= 64);
29+
memcpy(tmp, a, len);
30+
memmove(a, b, len);
31+
memcpy(b, tmp, len);
3232
}
3333

34-
static SECP256K1_INLINE void secp256k1_heap_swap(unsigned char *a, size_t i, size_t j, size_t stride) {
35-
while (64 < stride) {
36-
secp256k1_heap_swap64(a + (stride - 64), i, j, 64);
37-
stride -= 64;
34+
static SECP256K1_INLINE void secp256k1_heap_swap(unsigned char *arr, size_t i, size_t j, size_t stride) {
35+
unsigned char *a = arr + i*stride;
36+
unsigned char *b = arr + j*stride;
37+
size_t len = stride;
38+
while (64 < len) {
39+
secp256k1_heap_swap64(a + (len - 64), b + (len - 64), 64);
40+
len -= 64;
3841
}
39-
secp256k1_heap_swap64(a, i, j, stride);
42+
secp256k1_heap_swap64(a, b, len);
4043
}
4144

42-
static SECP256K1_INLINE void secp256k1_heap_down(unsigned char *a, size_t i, size_t heap_size, size_t stride,
45+
static SECP256K1_INLINE void secp256k1_heap_down(unsigned char *arr, size_t i, size_t heap_size, size_t stride,
4346
int (*cmp)(const void *, const void *, void *), void *cmp_data) {
4447
while (i < heap_size/2) {
4548
VERIFY_CHECK(i <= SIZE_MAX/2 - 1);
@@ -69,18 +72,18 @@ static SECP256K1_INLINE void secp256k1_heap_down(unsigned char *a, size_t i, siz
6972
* Else if [child2(i)] > [i], swap [i] with [child2(i)].
7073
*/
7174
if (secp256k1_heap_child2(i) < heap_size
72-
&& 0 <= cmp(a + secp256k1_heap_child2(i)*stride, a + secp256k1_heap_child1(i)*stride, cmp_data)) {
73-
if (0 < cmp(a + secp256k1_heap_child2(i)*stride, a + i*stride, cmp_data)) {
74-
secp256k1_heap_swap(a, i, secp256k1_heap_child2(i), stride);
75+
&& 0 <= cmp(arr + secp256k1_heap_child2(i)*stride, arr + secp256k1_heap_child1(i)*stride, cmp_data)) {
76+
if (0 < cmp(arr + secp256k1_heap_child2(i)*stride, arr + i*stride, cmp_data)) {
77+
secp256k1_heap_swap(arr, i, secp256k1_heap_child2(i), stride);
7578
i = secp256k1_heap_child2(i);
7679
} else {
7780
/* At this point we have [child2(i)] >= [child1(i)] and we have
7881
* [child2(i)] <= [i], and thus [child1(i)] <= [i] which means
7982
* that the next comparison can be skipped. */
8083
return;
8184
}
82-
} else if (0 < cmp(a + secp256k1_heap_child1(i)*stride, a + i*stride, cmp_data)) {
83-
secp256k1_heap_swap(a, i, secp256k1_heap_child1(i), stride);
85+
} else if (0 < cmp(arr + secp256k1_heap_child1(i)*stride, arr + i*stride, cmp_data)) {
86+
secp256k1_heap_swap(arr, i, secp256k1_heap_child1(i), stride);
8487
i = secp256k1_heap_child1(i);
8588
} else {
8689
return;

src/tests.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6607,6 +6607,18 @@ static void run_pubkey_comparison(void) {
66076607
CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk2, &pk1) > 0);
66086608
}
66096609

6610+
static void test_heap_swap(void) {
6611+
unsigned char a[600];
6612+
unsigned char e[sizeof(a)];
6613+
memset(a, 21, 200);
6614+
memset(a + 200, 99, 200);
6615+
memset(a + 400, 42, 200);
6616+
memset(e, 42, 200);
6617+
memset(e + 200, 99, 200);
6618+
memset(e + 400, 21, 200);
6619+
secp256k1_heap_swap(a, 0, 2, 200);
6620+
CHECK(secp256k1_memcmp_var(a, e, sizeof(a)) == 0);
6621+
}
66106622

66116623
static void test_hsort_is_sorted(int *ints, size_t n) {
66126624
size_t i;
@@ -6801,6 +6813,7 @@ static void run_pubkey_sort(void) {
68016813
test_sort_api();
68026814
test_sort();
68036815
test_sort_vectors();
6816+
test_heap_swap();
68046817
}
68056818

68066819

0 commit comments

Comments
 (0)