diff options
| author | Your Name <you@example.com> | 2026-05-16 23:55:05 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-16 23:55:05 +0530 |
| commit | 4c47ae188b288e7d24bd9566ab3e6a6805d9484f (patch) | |
| tree | 33b74b2090b4f3b7597841734a56a4006a86d73f /main/geohash.c | |
| parent | 133e40c82afb4d7659758b1fa57925ac57af4621 (diff) | |
Phase 3: Nostr identity derivation + wifistr service discovery
- Add identity.c/h: HMAC-SHA512 derivation from nsec → npub, STA/AP MAC, SSID, AP IP
- Add nostr_event.c/h: NIP-01 event serialization + Schnorr signing (BIP-340)
- Add geohash.c/h: lat/lon to geohash encoding
- Add wifistr.c/h: kind 38787 event builder + WebSocket publish to Nostr relays
- Update config.c/h: nsec-based identity, Nostr relay/geo config, remove static SSID/IP
- Replace custom mbedTLS wallet with nucula library (libsecp256k1)
- Remove wallet.c/h, wallet_persist.c/h (replaced by nucula_lib component)
- Verified on Board A: derived SSID, captive portal, payment, wallet, wifistr publish
Diffstat (limited to 'main/geohash.c')
| -rw-r--r-- | main/geohash.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/main/geohash.c b/main/geohash.c new file mode 100644 index 0000000..f649824 --- /dev/null +++ b/main/geohash.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #include "geohash.h" | ||
| 2 | #include <string.h> | ||
| 3 | |||
| 4 | static const char BASE32[] = "0123456789bcdefghjkmnpqrstuvwxyz"; | ||
| 5 | |||
| 6 | void geohash_encode(double lat, double lon, int precision, char *out) | ||
| 7 | { | ||
| 8 | double lat_range[2] = { -90.0, 90.0 }; | ||
| 9 | double lon_range[2] = { -180.0, 180.0 }; | ||
| 10 | uint8_t hash_bytes[16]; | ||
| 11 | int bit_count = precision * 5; | ||
| 12 | int byte_count = (bit_count + 7) / 8; | ||
| 13 | memset(hash_bytes, 0, sizeof(hash_bytes)); | ||
| 14 | |||
| 15 | for (int i = 0; i < bit_count; i++) { | ||
| 16 | int byte_idx = i / 8; | ||
| 17 | int bit_idx = 7 - (i % 8); | ||
| 18 | |||
| 19 | if (i % 2 == 0) { | ||
| 20 | double mid = (lon_range[0] + lon_range[1]) / 2.0; | ||
| 21 | if (lon >= mid) { | ||
| 22 | hash_bytes[byte_idx] |= (1 << bit_idx); | ||
| 23 | lon_range[0] = mid; | ||
| 24 | } else { | ||
| 25 | lon_range[1] = mid; | ||
| 26 | } | ||
| 27 | } else { | ||
| 28 | double mid = (lat_range[0] + lat_range[1]) / 2.0; | ||
| 29 | if (lat >= mid) { | ||
| 30 | hash_bytes[byte_idx] |= (1 << bit_idx); | ||
| 31 | lat_range[0] = mid; | ||
| 32 | } else { | ||
| 33 | lat_range[1] = mid; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | for (int i = 0; i < precision; i++) { | ||
| 39 | int byte_idx = (i * 5) / 8; | ||
| 40 | int bit_offset = (i * 5) % 8; | ||
| 41 | uint16_t val = (hash_bytes[byte_idx] << 8); | ||
| 42 | if (byte_idx + 1 < (int)sizeof(hash_bytes)) | ||
| 43 | val |= hash_bytes[byte_idx + 1]; | ||
| 44 | val = (val >> (16 - 5 - bit_offset)) & 0x1F; | ||
| 45 | out[i] = BASE32[val]; | ||
| 46 | } | ||
| 47 | out[precision] = '\0'; | ||
| 48 | } | ||