@qntx/nostr-native 0.0.0-stage → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/LICENSE-APACHE +201 -0
  2. package/LICENSE-MIT +21 -0
  3. package/NostrNative.podspec +37 -0
  4. package/README.md +30 -2
  5. package/android/CMakeLists.txt +38 -0
  6. package/android/build.gradle +136 -0
  7. package/android/gradle.properties +4 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +7 -0
  10. package/android/src/main/java/com/margelo/nitro/nostrnative/NostrNativePackage.java +29 -0
  11. package/cpp/HybridNostrNative.cpp +52 -0
  12. package/cpp/HybridNostrNative.hpp +22 -0
  13. package/cpp/nostr_core.c +128 -0
  14. package/cpp/nostr_core.h +65 -0
  15. package/cpp/nostr_native.c +54 -0
  16. package/cpp/nostr_native.h +47 -0
  17. package/dist/index.d.mts +15 -0
  18. package/dist/index.mjs +26 -0
  19. package/dist/index.mjs.map +1 -0
  20. package/nitro.json +19 -0
  21. package/nitrogen/generated/.gitattributes +1 -0
  22. package/nitrogen/generated/android/NostrNative+autolinking.cmake +81 -0
  23. package/nitrogen/generated/android/NostrNative+autolinking.gradle +27 -0
  24. package/nitrogen/generated/android/NostrNativeOnLoad.cpp +49 -0
  25. package/nitrogen/generated/android/NostrNativeOnLoad.hpp +34 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nostrnative/NostrNativeOnLoad.kt +35 -0
  27. package/nitrogen/generated/ios/NostrNative+autolinking.rb +62 -0
  28. package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.cpp +17 -0
  29. package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.hpp +27 -0
  30. package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Umbrella.hpp +38 -0
  31. package/nitrogen/generated/ios/NostrNativeAutolinking.mm +35 -0
  32. package/nitrogen/generated/ios/NostrNativeAutolinking.swift +16 -0
  33. package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.cpp +23 -0
  34. package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.hpp +64 -0
  35. package/package.json +86 -4
  36. package/react-native.config.js +12 -0
  37. package/vendor/secp256k1/COPYING +19 -0
  38. package/vendor/secp256k1/include/secp256k1.h +931 -0
  39. package/vendor/secp256k1/include/secp256k1_ecdh.h +63 -0
  40. package/vendor/secp256k1/include/secp256k1_ellswift.h +200 -0
  41. package/vendor/secp256k1/include/secp256k1_extrakeys.h +250 -0
  42. package/vendor/secp256k1/include/secp256k1_musig.h +588 -0
  43. package/vendor/secp256k1/include/secp256k1_preallocated.h +134 -0
  44. package/vendor/secp256k1/include/secp256k1_recovery.h +123 -0
  45. package/vendor/secp256k1/include/secp256k1_schnorrsig.h +179 -0
  46. package/vendor/secp256k1/include/secp256k1_silentpayments.h +396 -0
  47. package/vendor/secp256k1/src/assumptions.h +87 -0
  48. package/vendor/secp256k1/src/checkmem.h +117 -0
  49. package/vendor/secp256k1/src/ecdsa.h +21 -0
  50. package/vendor/secp256k1/src/ecdsa_impl.h +309 -0
  51. package/vendor/secp256k1/src/eckey.h +28 -0
  52. package/vendor/secp256k1/src/eckey_impl.h +94 -0
  53. package/vendor/secp256k1/src/ecmult.h +64 -0
  54. package/vendor/secp256k1/src/ecmult_compute_table.h +16 -0
  55. package/vendor/secp256k1/src/ecmult_compute_table_impl.h +49 -0
  56. package/vendor/secp256k1/src/ecmult_const.h +38 -0
  57. package/vendor/secp256k1/src/ecmult_const_impl.h +402 -0
  58. package/vendor/secp256k1/src/ecmult_gen.h +145 -0
  59. package/vendor/secp256k1/src/ecmult_gen_compute_table.h +14 -0
  60. package/vendor/secp256k1/src/ecmult_gen_compute_table_impl.h +108 -0
  61. package/vendor/secp256k1/src/ecmult_gen_impl.h +347 -0
  62. package/vendor/secp256k1/src/ecmult_impl.h +869 -0
  63. package/vendor/secp256k1/src/field.h +351 -0
  64. package/vendor/secp256k1/src/field_10x26.h +57 -0
  65. package/vendor/secp256k1/src/field_10x26_impl.h +1210 -0
  66. package/vendor/secp256k1/src/field_5x52.h +62 -0
  67. package/vendor/secp256k1/src/field_5x52_impl.h +496 -0
  68. package/vendor/secp256k1/src/field_5x52_int128_impl.h +274 -0
  69. package/vendor/secp256k1/src/field_impl.h +457 -0
  70. package/vendor/secp256k1/src/group.h +218 -0
  71. package/vendor/secp256k1/src/group_impl.h +1014 -0
  72. package/vendor/secp256k1/src/hash.h +56 -0
  73. package/vendor/secp256k1/src/hash_impl.h +397 -0
  74. package/vendor/secp256k1/src/hsort.h +33 -0
  75. package/vendor/secp256k1/src/hsort_impl.h +125 -0
  76. package/vendor/secp256k1/src/int128.h +90 -0
  77. package/vendor/secp256k1/src/int128_impl.h +18 -0
  78. package/vendor/secp256k1/src/int128_native.h +19 -0
  79. package/vendor/secp256k1/src/int128_native_impl.h +94 -0
  80. package/vendor/secp256k1/src/int128_struct.h +14 -0
  81. package/vendor/secp256k1/src/int128_struct_impl.h +205 -0
  82. package/vendor/secp256k1/src/modinv32.h +43 -0
  83. package/vendor/secp256k1/src/modinv32_impl.h +725 -0
  84. package/vendor/secp256k1/src/modinv64.h +47 -0
  85. package/vendor/secp256k1/src/modinv64_impl.h +780 -0
  86. package/vendor/secp256k1/src/modules/extrakeys/main_impl.h +292 -0
  87. package/vendor/secp256k1/src/modules/schnorrsig/main_impl.h +256 -0
  88. package/vendor/secp256k1/src/precomputed_ecmult.c +16456 -0
  89. package/vendor/secp256k1/src/precomputed_ecmult.h +40 -0
  90. package/vendor/secp256k1/src/precomputed_ecmult_gen.c +1779 -0
  91. package/vendor/secp256k1/src/precomputed_ecmult_gen.h +28 -0
  92. package/vendor/secp256k1/src/scalar.h +105 -0
  93. package/vendor/secp256k1/src/scalar_4x64.h +19 -0
  94. package/vendor/secp256k1/src/scalar_4x64_impl.h +1005 -0
  95. package/vendor/secp256k1/src/scalar_8x32.h +19 -0
  96. package/vendor/secp256k1/src/scalar_8x32_impl.h +820 -0
  97. package/vendor/secp256k1/src/scalar_impl.h +321 -0
  98. package/vendor/secp256k1/src/scalar_low.h +24 -0
  99. package/vendor/secp256k1/src/scalar_low_impl.h +217 -0
  100. package/vendor/secp256k1/src/scratch.h +44 -0
  101. package/vendor/secp256k1/src/scratch_impl.h +99 -0
  102. package/vendor/secp256k1/src/secp256k1.c +855 -0
  103. package/vendor/secp256k1/src/selftest.h +41 -0
  104. package/vendor/secp256k1/src/util.h +479 -0
  105. package/vendor/secp256k1/src/util_local_visibility.h +12 -0
  106. package/vendor/secp256k1/vendored.json +6 -0
@@ -0,0 +1,56 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2014 Pieter Wuille *
3
+ * Distributed under the MIT software license, see the accompanying *
4
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
+ ***********************************************************************/
6
+
7
+ #ifndef SECP256K1_HASH_H
8
+ #define SECP256K1_HASH_H
9
+
10
+ #include <stdlib.h>
11
+ #include <stdint.h>
12
+
13
+ #include "../include/secp256k1.h"
14
+
15
+ typedef struct {
16
+ nostr_native_secp256k1_sha256_compression_function fn_sha256_compression;
17
+ } nostr_native_secp256k1_hash_ctx;
18
+
19
+ static void nostr_native_secp256k1_hash_ctx_init(nostr_native_secp256k1_hash_ctx *hash_ctx);
20
+
21
+ typedef struct {
22
+ uint32_t s[8];
23
+ unsigned char buf[64];
24
+ uint64_t bytes;
25
+ } nostr_native_secp256k1_sha256;
26
+
27
+ static void nostr_native_secp256k1_sha256_initialize(nostr_native_secp256k1_sha256 *hash);
28
+ /* Initialize a SHA256 hash state with a precomputed midstate.
29
+ * The byte counter must be a multiple of 64, i.e., there must be no unwritten
30
+ * bytes in the buffer. */
31
+ static void nostr_native_secp256k1_sha256_initialize_midstate(nostr_native_secp256k1_sha256 *hash, uint64_t bytes, const uint32_t state[8]);
32
+ static void nostr_native_secp256k1_sha256_write(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_sha256 *hash, const unsigned char *data, size_t size);
33
+ static void nostr_native_secp256k1_sha256_finalize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_sha256 *hash, unsigned char *out32);
34
+ static void nostr_native_secp256k1_sha256_clear(nostr_native_secp256k1_sha256 *hash);
35
+
36
+ typedef struct {
37
+ nostr_native_secp256k1_sha256 inner, outer;
38
+ } nostr_native_secp256k1_hmac_sha256;
39
+
40
+ static void nostr_native_secp256k1_hmac_sha256_initialize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size);
41
+ static void nostr_native_secp256k1_hmac_sha256_write(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size);
42
+ static void nostr_native_secp256k1_hmac_sha256_finalize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_hmac_sha256 *hash, unsigned char *out32);
43
+ static void nostr_native_secp256k1_hmac_sha256_clear(nostr_native_secp256k1_hmac_sha256 *hash);
44
+
45
+ typedef struct {
46
+ unsigned char v[32];
47
+ unsigned char k[32];
48
+ int retry;
49
+ } nostr_native_secp256k1_rfc6979_hmac_sha256;
50
+
51
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_initialize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen);
52
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_generate(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen);
53
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_finalize(nostr_native_secp256k1_rfc6979_hmac_sha256 *rng);
54
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_clear(nostr_native_secp256k1_rfc6979_hmac_sha256 *rng);
55
+
56
+ #endif /* SECP256K1_HASH_H */
@@ -0,0 +1,397 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2014 Pieter Wuille *
3
+ * Distributed under the MIT software license, see the accompanying *
4
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
+ ***********************************************************************/
6
+
7
+ #ifndef SECP256K1_HASH_IMPL_H
8
+ #define SECP256K1_HASH_IMPL_H
9
+
10
+ #include "hash.h"
11
+ #include "util.h"
12
+
13
+ #include <stdlib.h>
14
+ #include <stdint.h>
15
+ #include <string.h>
16
+
17
+ #define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
18
+ #define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
19
+ #define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10))
20
+ #define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7))
21
+ #define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3))
22
+ #define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10))
23
+
24
+ #define Round(a,b,c,d,e,f,g,h,k,w) do { \
25
+ uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \
26
+ uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \
27
+ (d) += t1; \
28
+ (h) = t1 + t2; \
29
+ } while(0)
30
+
31
+ static void nostr_native_secp256k1_sha256_initialize(nostr_native_secp256k1_sha256 *hash) {
32
+ hash->s[0] = 0x6a09e667ul;
33
+ hash->s[1] = 0xbb67ae85ul;
34
+ hash->s[2] = 0x3c6ef372ul;
35
+ hash->s[3] = 0xa54ff53aul;
36
+ hash->s[4] = 0x510e527ful;
37
+ hash->s[5] = 0x9b05688cul;
38
+ hash->s[6] = 0x1f83d9abul;
39
+ hash->s[7] = 0x5be0cd19ul;
40
+ hash->bytes = 0;
41
+ }
42
+
43
+ static void nostr_native_secp256k1_sha256_initialize_midstate(nostr_native_secp256k1_sha256 *hash, uint64_t bytes, const uint32_t state[8]) {
44
+ VERIFY_CHECK((bytes & 0x3F) == 0);
45
+ VERIFY_CHECK(state != NULL);
46
+ memcpy(hash->s, state, sizeof(hash->s));
47
+ hash->bytes = bytes;
48
+ }
49
+
50
+ /** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */
51
+ static void nostr_native_secp256k1_sha256_transform_impl(uint32_t* s, const unsigned char* buf) {
52
+ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
53
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
54
+
55
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = nostr_native_secp256k1_read_be32(&buf[0]));
56
+ Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = nostr_native_secp256k1_read_be32(&buf[4]));
57
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = nostr_native_secp256k1_read_be32(&buf[8]));
58
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = nostr_native_secp256k1_read_be32(&buf[12]));
59
+ Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = nostr_native_secp256k1_read_be32(&buf[16]));
60
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = nostr_native_secp256k1_read_be32(&buf[20]));
61
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = nostr_native_secp256k1_read_be32(&buf[24]));
62
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = nostr_native_secp256k1_read_be32(&buf[28]));
63
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = nostr_native_secp256k1_read_be32(&buf[32]));
64
+ Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = nostr_native_secp256k1_read_be32(&buf[36]));
65
+ Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = nostr_native_secp256k1_read_be32(&buf[40]));
66
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = nostr_native_secp256k1_read_be32(&buf[44]));
67
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = nostr_native_secp256k1_read_be32(&buf[48]));
68
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = nostr_native_secp256k1_read_be32(&buf[52]));
69
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = nostr_native_secp256k1_read_be32(&buf[56]));
70
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = nostr_native_secp256k1_read_be32(&buf[60]));
71
+
72
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
73
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
74
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
75
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
76
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
77
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
78
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
79
+ Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
80
+ Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
81
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
82
+ Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
83
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
84
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
85
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
86
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
87
+ Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
88
+
89
+ Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
90
+ Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
91
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
92
+ Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
93
+ Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
94
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
95
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
96
+ Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
97
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
98
+ Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
99
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
100
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
101
+ Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
102
+ Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
103
+ Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
104
+ Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
105
+
106
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
107
+ Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
108
+ Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
109
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
110
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
111
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
112
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
113
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
114
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
115
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
116
+ Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
117
+ Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
118
+ Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
119
+ Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
120
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
121
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
122
+
123
+ s[0] += a;
124
+ s[1] += b;
125
+ s[2] += c;
126
+ s[3] += d;
127
+ s[4] += e;
128
+ s[5] += f;
129
+ s[6] += g;
130
+ s[7] += h;
131
+ }
132
+
133
+ static void nostr_native_secp256k1_sha256_transform(uint32_t *state, const unsigned char *blocks64, size_t n_blocks) {
134
+ while (n_blocks--) {
135
+ nostr_native_secp256k1_sha256_transform_impl(state, blocks64);
136
+ blocks64 += 64;
137
+ }
138
+ }
139
+
140
+ /* Perform a smoke test on a supplied SHA256 compression function. */
141
+ static int nostr_native_secp256k1_sha256_smoke_test(const nostr_native_secp256k1_sha256_compression_function fn_compression) {
142
+ nostr_native_secp256k1_hash_ctx ctx;
143
+ nostr_native_secp256k1_sha256 sha_msg, sha_accum;
144
+ unsigned char out[32];
145
+ size_t i, j;
146
+
147
+ /* SHA256 works on 64 byte blocks, nostr_native_secp256k1_sha256_write gives as many blocks
148
+ * at once to compression, so the count is what varies here. A SIMD implementation
149
+ * typically hashes four or eight at a time, then any left over one by one.
150
+ * These lengths cover every number from 1 to 9, which includes counts that
151
+ * divide evenly and counts leaving one, two or three over. */
152
+ static const size_t msg_lens[] = {
153
+ 0, 1, 28, /* Shorter than a block, so padding makes up the rest */
154
+ 55, 56, /* Final 0x80 and 8 byte length fit in the last block, and don't */
155
+ 64, 128, 192, 256, 320, /* 1 to 5 blocks */
156
+ 384, 448, 512, 576 /* 6 to 9 blocks */
157
+ };
158
+ unsigned char msg[640]; /* Longest message, plus 64 for the shifted start */
159
+
160
+ /* Accumulated digest of every message, hashed with the built-in nostr_native_secp256k1_sha256_transform.
161
+ * Note: To regenerate set 'ctx.fn_sha256_compression = nostr_native_secp256k1_sha256_transform' below
162
+ * and print the sha_accum digest. */
163
+ static const unsigned char accum_expected[32] = {
164
+ 0x22, 0x8E, 0x6A, 0x1F, 0x78, 0x02, 0x1B, 0xCF,
165
+ 0x4E, 0xF4, 0xEA, 0xB3, 0x8A, 0x40, 0x69, 0xBF,
166
+ 0x8D, 0xF3, 0x72, 0xAB, 0xE2, 0x11, 0x93, 0xA6,
167
+ 0xE6, 0x46, 0x98, 0xBF, 0xD4, 0x3D, 0x19, 0x84,
168
+ };
169
+ /* The purpose of this VERIFY_CHECK is to make anyone aware that they
170
+ * should also change the size of msg_buf when changing the length of the
171
+ * longest message. */
172
+ VERIFY_CHECK(msg_lens[ARRAY_SIZE(msg_lens) - 1] == 576);
173
+
174
+ VERIFY_CHECK(fn_compression != NULL);
175
+ nostr_native_secp256k1_hash_ctx_init(&ctx);
176
+ ctx.fn_sha256_compression = fn_compression;
177
+ nostr_native_secp256k1_sha256_initialize(&sha_accum);
178
+
179
+ /* No two blocks of a message are equal, so a function that doesn't advance the block
180
+ * pointer gives a different digest. 251 is prime, so its repeats only line up with
181
+ * block starts every 251 blocks; wrapping at 256 would do so every 4. */
182
+ for (i = 0; i < sizeof(msg); i++) {
183
+ msg[i] = (unsigned char)(i % 251);
184
+ }
185
+
186
+ /* Each round starts one byte further along to check different alignments,
187
+ * nostr_native_secp256k1_sha256_write invokes compression directly on input >= 64 bytes */
188
+ for (i = 0; i < 64; i++) {
189
+ unsigned char *m = msg + i;
190
+ m[0] ^= 0xff; /* Changes the first byte, so every state after it changes too */
191
+ for (j = 0; j < ARRAY_SIZE(msg_lens); j++) {
192
+ nostr_native_secp256k1_sha256_initialize(&sha_msg);
193
+ nostr_native_secp256k1_sha256_write(&ctx, &sha_msg, m, msg_lens[j]);
194
+ nostr_native_secp256k1_sha256_finalize(&ctx, &sha_msg, out);
195
+ nostr_native_secp256k1_sha256_write(&ctx, &sha_accum, out, 32);
196
+ }
197
+ m[0] ^= 0xff; /* Reset first byte */
198
+ }
199
+
200
+ /* Compare against pre-computed accumulated digest */
201
+ nostr_native_secp256k1_sha256_finalize(&ctx, &sha_accum, out);
202
+ return nostr_native_secp256k1_memcmp_var(accum_expected, out, 32) == 0;
203
+ }
204
+
205
+ static void nostr_native_secp256k1_hash_ctx_init(nostr_native_secp256k1_hash_ctx *hash_ctx) {
206
+ VERIFY_CHECK(hash_ctx != NULL);
207
+ hash_ctx->fn_sha256_compression = nostr_native_secp256k1_sha256_transform;
208
+ }
209
+
210
+ static void nostr_native_secp256k1_sha256_write(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_sha256 *hash, const unsigned char *data, size_t len) {
211
+ size_t chunk_len;
212
+ size_t bufsize = hash->bytes & 0x3F;
213
+ hash->bytes += len;
214
+ VERIFY_CHECK(hash->bytes >= len);
215
+ VERIFY_CHECK(hash_ctx != NULL);
216
+ VERIFY_CHECK(hash_ctx->fn_sha256_compression != NULL);
217
+
218
+ /* If we exceed the 64-byte block size with this input, process it and wipe the buffer */
219
+ chunk_len = 64 - bufsize;
220
+ if (bufsize && len >= chunk_len) {
221
+ memcpy(hash->buf + bufsize, data, chunk_len);
222
+ data += chunk_len;
223
+ len -= chunk_len;
224
+ hash_ctx->fn_sha256_compression(hash->s, hash->buf, 1);
225
+ bufsize = 0;
226
+ }
227
+
228
+ /* If we still have data to process, invoke compression directly on the input */
229
+ if (len >= 64) {
230
+ const size_t n_blocks = len / 64;
231
+ const size_t advance = n_blocks * 64;
232
+ hash_ctx->fn_sha256_compression(hash->s, data, n_blocks);
233
+ data += advance;
234
+ len -= advance;
235
+ }
236
+
237
+ /* Fill the buffer with what remains */
238
+ if (len) {
239
+ memcpy(hash->buf + bufsize, data, len);
240
+ }
241
+ }
242
+
243
+ static void nostr_native_secp256k1_sha256_finalize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_sha256 *hash, unsigned char *out32) {
244
+ static const unsigned char pad[64] = {0x80};
245
+ unsigned char sizedesc[8];
246
+ int i;
247
+ /* The maximum message size of SHA256 is 2^64-1 bits. */
248
+ VERIFY_CHECK(hash->bytes < ((uint64_t)1 << 61));
249
+ nostr_native_secp256k1_write_be32(&sizedesc[0], hash->bytes >> 29);
250
+ nostr_native_secp256k1_write_be32(&sizedesc[4], hash->bytes << 3);
251
+ nostr_native_secp256k1_sha256_write(hash_ctx, hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64));
252
+ nostr_native_secp256k1_sha256_write(hash_ctx, hash, sizedesc, 8);
253
+ for (i = 0; i < 8; i++) {
254
+ nostr_native_secp256k1_write_be32(&out32[4*i], hash->s[i]);
255
+ hash->s[i] = 0;
256
+ }
257
+ }
258
+
259
+ /* Initializes a sha256 struct and writes the 64 byte string
260
+ * SHA256(tag)||SHA256(tag) into it. */
261
+ static void nostr_native_secp256k1_sha256_initialize_tagged(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen) {
262
+ unsigned char buf[32];
263
+ nostr_native_secp256k1_sha256_initialize(hash);
264
+ nostr_native_secp256k1_sha256_write(hash_ctx, hash, tag, taglen);
265
+ nostr_native_secp256k1_sha256_finalize(hash_ctx, hash, buf);
266
+
267
+ nostr_native_secp256k1_sha256_initialize(hash);
268
+ nostr_native_secp256k1_sha256_write(hash_ctx, hash, buf, 32);
269
+ nostr_native_secp256k1_sha256_write(hash_ctx, hash, buf, 32);
270
+ }
271
+
272
+ static void nostr_native_secp256k1_sha256_clear(nostr_native_secp256k1_sha256 *hash) {
273
+ nostr_native_secp256k1_memclear_explicit(hash, sizeof(*hash));
274
+ }
275
+
276
+ static void nostr_native_secp256k1_hmac_sha256_initialize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) {
277
+ size_t n;
278
+ unsigned char rkey[64];
279
+ if (keylen <= sizeof(rkey)) {
280
+ memcpy(rkey, key, keylen);
281
+ memset(rkey + keylen, 0, sizeof(rkey) - keylen);
282
+ } else {
283
+ nostr_native_secp256k1_sha256 sha256;
284
+ nostr_native_secp256k1_sha256_initialize(&sha256);
285
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha256, key, keylen);
286
+ nostr_native_secp256k1_sha256_finalize(hash_ctx, &sha256, rkey);
287
+ memset(rkey + 32, 0, 32);
288
+ }
289
+
290
+ nostr_native_secp256k1_sha256_initialize(&hash->outer);
291
+ for (n = 0; n < sizeof(rkey); n++) {
292
+ rkey[n] ^= 0x5c;
293
+ }
294
+ nostr_native_secp256k1_sha256_write(hash_ctx, &hash->outer, rkey, sizeof(rkey));
295
+
296
+ nostr_native_secp256k1_sha256_initialize(&hash->inner);
297
+ for (n = 0; n < sizeof(rkey); n++) {
298
+ rkey[n] ^= 0x5c ^ 0x36;
299
+ }
300
+ nostr_native_secp256k1_sha256_write(hash_ctx, &hash->inner, rkey, sizeof(rkey));
301
+ nostr_native_secp256k1_memclear_explicit(rkey, sizeof(rkey));
302
+ }
303
+
304
+ static void nostr_native_secp256k1_hmac_sha256_write(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) {
305
+ nostr_native_secp256k1_sha256_write(hash_ctx, &hash->inner, data, size);
306
+ }
307
+
308
+ static void nostr_native_secp256k1_hmac_sha256_finalize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_hmac_sha256 *hash, unsigned char *out32) {
309
+ unsigned char temp[32];
310
+ nostr_native_secp256k1_sha256_finalize(hash_ctx, &hash->inner, temp);
311
+ nostr_native_secp256k1_sha256_write(hash_ctx, &hash->outer, temp, 32);
312
+ nostr_native_secp256k1_memclear_explicit(temp, sizeof(temp));
313
+ nostr_native_secp256k1_sha256_finalize(hash_ctx, &hash->outer, out32);
314
+ }
315
+
316
+ static void nostr_native_secp256k1_hmac_sha256_clear(nostr_native_secp256k1_hmac_sha256 *hash) {
317
+ nostr_native_secp256k1_memclear_explicit(hash, sizeof(*hash));
318
+ }
319
+
320
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_initialize(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) {
321
+ nostr_native_secp256k1_hmac_sha256 hmac;
322
+ static const unsigned char zero[1] = {0x00};
323
+ static const unsigned char one[1] = {0x01};
324
+
325
+ memset(rng->v, 0x01, 32); /* RFC6979 3.2.b. */
326
+ memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */
327
+
328
+ /* RFC6979 3.2.d. */
329
+ nostr_native_secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32);
330
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32);
331
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, zero, 1);
332
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, key, keylen);
333
+ nostr_native_secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->k);
334
+ nostr_native_secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32);
335
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32);
336
+ nostr_native_secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v);
337
+
338
+ /* RFC6979 3.2.f. */
339
+ nostr_native_secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32);
340
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32);
341
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, one, 1);
342
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, key, keylen);
343
+ nostr_native_secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->k);
344
+ nostr_native_secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32);
345
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32);
346
+ nostr_native_secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v);
347
+ rng->retry = 0;
348
+ }
349
+
350
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_generate(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) {
351
+ /* RFC6979 3.2.h. */
352
+ static const unsigned char zero[1] = {0x00};
353
+ if (rng->retry) {
354
+ nostr_native_secp256k1_hmac_sha256 hmac;
355
+ nostr_native_secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32);
356
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32);
357
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, zero, 1);
358
+ nostr_native_secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->k);
359
+ nostr_native_secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32);
360
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32);
361
+ nostr_native_secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v);
362
+ }
363
+
364
+ while (outlen > 0) {
365
+ nostr_native_secp256k1_hmac_sha256 hmac;
366
+ size_t now = outlen;
367
+ nostr_native_secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32);
368
+ nostr_native_secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32);
369
+ nostr_native_secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v);
370
+ if (now > 32) {
371
+ now = 32;
372
+ }
373
+ memcpy(out, rng->v, now);
374
+ out += now;
375
+ outlen -= now;
376
+ }
377
+
378
+ rng->retry = 1;
379
+ }
380
+
381
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_finalize(nostr_native_secp256k1_rfc6979_hmac_sha256 *rng) {
382
+ (void) rng;
383
+ }
384
+
385
+ static void nostr_native_secp256k1_rfc6979_hmac_sha256_clear(nostr_native_secp256k1_rfc6979_hmac_sha256 *rng) {
386
+ nostr_native_secp256k1_memclear_explicit(rng, sizeof(*rng));
387
+ }
388
+
389
+ #undef Round
390
+ #undef sigma1
391
+ #undef sigma0
392
+ #undef Sigma1
393
+ #undef Sigma0
394
+ #undef Maj
395
+ #undef Ch
396
+
397
+ #endif /* SECP256K1_HASH_IMPL_H */
@@ -0,0 +1,33 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2021 Russell O'Connor, Jonas Nick *
3
+ * Distributed under the MIT software license, see the accompanying *
4
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
+ ***********************************************************************/
6
+
7
+ #ifndef SECP256K1_HSORT_H
8
+ #define SECP256K1_HSORT_H
9
+
10
+ #include <stddef.h>
11
+ #include <string.h>
12
+
13
+ /* In-place, iterative heapsort with an interface matching glibc's qsort_r. This
14
+ * is preferred over standard library implementations because they generally
15
+ * make no guarantee about being fast for malicious inputs.
16
+ * Remember that heapsort is unstable.
17
+ *
18
+ * In/Out: ptr: pointer to the array to sort. The contents of the array are
19
+ * sorted in ascending order according to the comparison function.
20
+ * In: count: number of elements in the array.
21
+ * size: size in bytes of each element.
22
+ * cmp: pointer to a comparison function that is called with two
23
+ * arguments that point to the objects being compared. The cmp_data
24
+ * argument of nostr_native_secp256k1_hsort is passed as third argument. The
25
+ * function must return an integer less than, equal to, or greater
26
+ * than zero if the first argument is considered to be respectively
27
+ * less than, equal to, or greater than the second.
28
+ * cmp_data: pointer passed as third argument to cmp.
29
+ */
30
+ static void nostr_native_secp256k1_hsort(void *ptr, size_t count, size_t size,
31
+ int (*cmp)(const void *, const void *, void *),
32
+ void *cmp_data);
33
+ #endif
@@ -0,0 +1,125 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2021 Russell O'Connor, Jonas Nick *
3
+ * Distributed under the MIT software license, see the accompanying *
4
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
+ ***********************************************************************/
6
+
7
+ #ifndef SECP256K1_HSORT_IMPL_H
8
+ #define SECP256K1_HSORT_IMPL_H
9
+
10
+ #include "hsort.h"
11
+
12
+ /* An array is a heap when, for all non-zero indexes i, the element at index i
13
+ * compares as less than or equal to the element at index parent(i) = (i-1)/2.
14
+ */
15
+
16
+ static SECP256K1_INLINE size_t nostr_native_secp256k1_heap_child1(size_t i) {
17
+ VERIFY_CHECK(i <= (SIZE_MAX - 1)/2);
18
+ return 2*i + 1;
19
+ }
20
+
21
+ static SECP256K1_INLINE size_t nostr_native_secp256k1_heap_child2(size_t i) {
22
+ VERIFY_CHECK(i <= SIZE_MAX/2 - 1);
23
+ return nostr_native_secp256k1_heap_child1(i)+1;
24
+ }
25
+
26
+ static SECP256K1_INLINE void nostr_native_secp256k1_heap_swap64(unsigned char *a, unsigned char *b, size_t len) {
27
+ unsigned char tmp[64];
28
+ VERIFY_CHECK(len <= 64);
29
+ memcpy(tmp, a, len);
30
+ memmove(a, b, len);
31
+ memcpy(b, tmp, len);
32
+ }
33
+
34
+ static SECP256K1_INLINE void nostr_native_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
+ nostr_native_secp256k1_heap_swap64(a + (len - 64), b + (len - 64), 64);
40
+ len -= 64;
41
+ }
42
+ nostr_native_secp256k1_heap_swap64(a, b, len);
43
+ }
44
+
45
+ /* This function accepts an array arr containing heap_size elements, each of
46
+ * size stride. The elements in the array at indices >i satisfy the max-heap
47
+ * property, i.e., for any element at index j (where j > i), all of its children
48
+ * are smaller than the element itself. The purpose of the function is to update
49
+ * the array so that all elements at indices >=i satisfy the max-heap
50
+ * property. */
51
+ static SECP256K1_INLINE void nostr_native_secp256k1_heap_down(unsigned char *arr, size_t i, size_t heap_size, size_t stride,
52
+ int (*cmp)(const void *, const void *, void *), void *cmp_data) {
53
+ while (i < heap_size/2) {
54
+ VERIFY_CHECK(i <= SIZE_MAX/2 - 1);
55
+ /* Proof:
56
+ * i < heap_size/2
57
+ * i + 1 <= heap_size/2
58
+ * 2*i + 2 <= heap_size <= SIZE_MAX
59
+ * 2*i <= SIZE_MAX - 2
60
+ */
61
+
62
+ VERIFY_CHECK(nostr_native_secp256k1_heap_child1(i) < heap_size);
63
+ /* Proof:
64
+ * i < heap_size/2
65
+ * i + 1 <= heap_size/2
66
+ * 2*i + 2 <= heap_size
67
+ * 2*i + 1 < heap_size
68
+ * child1(i) < heap_size
69
+ */
70
+
71
+ /* Let [x] be notation for the contents at arr[x*stride].
72
+ *
73
+ * If [child1(i)] > [i] and [child2(i)] > [i],
74
+ * swap [i] with the larger child to ensure the new parent is larger
75
+ * than both children. When [child1(i)] == [child2(i)], swap [i] with
76
+ * [child2(i)].
77
+ * Else if [child1(i)] > [i], swap [i] with [child1(i)].
78
+ * Else if [child2(i)] > [i], swap [i] with [child2(i)].
79
+ */
80
+ if (nostr_native_secp256k1_heap_child2(i) < heap_size
81
+ && 0 <= cmp(arr + nostr_native_secp256k1_heap_child2(i)*stride, arr + nostr_native_secp256k1_heap_child1(i)*stride, cmp_data)) {
82
+ if (0 < cmp(arr + nostr_native_secp256k1_heap_child2(i)*stride, arr + i*stride, cmp_data)) {
83
+ nostr_native_secp256k1_heap_swap(arr, i, nostr_native_secp256k1_heap_child2(i), stride);
84
+ i = nostr_native_secp256k1_heap_child2(i);
85
+ } else {
86
+ /* At this point we have [child2(i)] >= [child1(i)] and we have
87
+ * [child2(i)] <= [i], and thus [child1(i)] <= [i] which means
88
+ * that the next comparison can be skipped. */
89
+ return;
90
+ }
91
+ } else if (0 < cmp(arr + nostr_native_secp256k1_heap_child1(i)*stride, arr + i*stride, cmp_data)) {
92
+ nostr_native_secp256k1_heap_swap(arr, i, nostr_native_secp256k1_heap_child1(i), stride);
93
+ i = nostr_native_secp256k1_heap_child1(i);
94
+ } else {
95
+ return;
96
+ }
97
+ }
98
+ /* heap_size/2 <= i
99
+ * heap_size/2 < i + 1
100
+ * heap_size < 2*i + 2
101
+ * heap_size <= 2*i + 1
102
+ * heap_size <= child1(i)
103
+ * Thus child1(i) and child2(i) are now out of bounds and we are at a leaf.
104
+ */
105
+ }
106
+
107
+ /* In-place heap sort. */
108
+ static void nostr_native_secp256k1_hsort(void *ptr, size_t count, size_t size,
109
+ int (*cmp)(const void *, const void *, void *),
110
+ void *cmp_data) {
111
+ size_t i;
112
+
113
+ for (i = count/2; 0 < i; --i) {
114
+ nostr_native_secp256k1_heap_down(ptr, i-1, count, size, cmp, cmp_data);
115
+ }
116
+ for (i = count; 1 < i; --i) {
117
+ /* Extract the largest value from the heap */
118
+ nostr_native_secp256k1_heap_swap(ptr, 0, i-1, size);
119
+
120
+ /* Repair the heap condition */
121
+ nostr_native_secp256k1_heap_down(ptr, 0, i-1, size, cmp, cmp_data);
122
+ }
123
+ }
124
+
125
+ #endif