Skip to content

Commit adf8082

Browse files
Update jellyfish.c
1 parent d9c9ee7 commit adf8082

File tree

1 file changed

+85
-88
lines changed

1 file changed

+85
-88
lines changed

code/logic/jellyfish.c

Lines changed: 85 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -127,111 +127,108 @@ uint64_t get_time_microseconds(void) {
127127
}
128128
#endif
129129

130-
// Default fallback salt (FNV offset basis)
131-
#define DEFAULT_SALT 0xcbf29ce484222325ULL
130+
#if defined(_WIN32)
131+
#include <windows.h>
132+
#elif defined(__unix__) || defined(__APPLE__)
133+
#include <unistd.h>
134+
#include <pwd.h>
135+
#endif
132136

133-
#if defined(_WIN32) || defined(_WIN64)
134-
// =======================
135-
// Windows (MinGW-safe)
136-
// =======================
137-
#include <winsock2.h> // MUST come first
138-
#include <iphlpapi.h>
139-
#pragma comment(lib, "iphlpapi.lib")
140-
141-
static uint64_t get_device_salt(void) {
142-
uint64_t salt = DEFAULT_SALT;
143-
ULONG size = 15000;
144-
145-
IP_ADAPTER_ADDRESSES *adapters = (IP_ADAPTER_ADDRESSES *)malloc(size);
146-
if (!adapters) return salt;
147-
148-
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST, NULL, adapters, &size) == NO_ERROR) {
149-
for (IP_ADAPTER_ADDRESSES *a = adapters; a; a = a->Next) {
150-
if (a->PhysicalAddressLength == 6) {
151-
for (ULONG i = 0; i < 6; ++i) {
152-
salt ^= a->PhysicalAddress[i];
153-
salt *= 0x100000001b3ULL;
154-
}
155-
break;
156-
}
157-
}
137+
static uint64_t fnv1a_hash(const unsigned char *data, size_t len) {
138+
uint64_t hash = 0xcbf29ce484222325ULL;
139+
for (size_t i = 0; i < len; ++i) {
140+
hash ^= data[i];
141+
hash *= 0x100000001b3ULL;
158142
}
159-
160-
free(adapters);
161-
return salt;
143+
return hash;
162144
}
163145

164-
#elif defined(__APPLE__) && defined(__MACH__)
165-
// =======================
166-
// macOS
167-
// =======================
168-
#include <ifaddrs.h>
169-
#include <net/if_dl.h>
170-
#include <net/if.h>
171-
#include <sys/socket.h>
146+
// Try reading file contents as salt (Linux/macOS)
147+
static uint64_t try_read_file_salt(const char *path) {
148+
FILE *fp = fopen(path, "rb");
149+
if (!fp) return 0;
150+
char buffer[256];
151+
size_t len = fread(buffer, 1, sizeof(buffer), fp);
152+
fclose(fp);
153+
if (len == 0) return 0;
154+
return fnv1a_hash((unsigned char *)buffer, len);
155+
}
172156

173-
static uint64_t get_device_salt(void) {
174-
uint64_t salt = DEFAULT_SALT;
175-
struct ifaddrs *ifap = NULL;
157+
// Try volume serial number (Windows)
158+
static uint64_t try_windows_volume_serial_salt(void) {
159+
#if defined(_WIN32)
160+
DWORD serial = 0;
161+
if (GetVolumeInformationA("C:\\", NULL, 0, &serial, NULL, NULL, NULL, 0)) {
162+
return fnv1a_hash((unsigned char *)&serial, sizeof(serial));
163+
}
164+
#endif
165+
return 0;
166+
}
176167

177-
if (getifaddrs(&ifap) != 0 || !ifap)
178-
return salt;
168+
// Try hostname + username combo (portable)
169+
static uint64_t try_username_hostname_salt(void) {
170+
char buffer[512];
171+
buffer[0] = '\0';
172+
173+
#if defined(_WIN32)
174+
DWORD size = 256;
175+
char username[256], hostname[256];
176+
GetUserNameA(username, &size);
177+
size = 256;
178+
GetComputerNameA(hostname, &size);
179+
snprintf(buffer, sizeof(buffer), "%s@%s", username, hostname);
180+
181+
#elif defined(__unix__) || defined(__APPLE__)
182+
const char *username = getlogin();
183+
char hostname[256];
184+
gethostname(hostname, sizeof(hostname));
185+
snprintf(buffer, sizeof(buffer), "%s@%s", username ? username : "?", hostname);
186+
#endif
179187

180-
for (struct ifaddrs *ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
181-
if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_LINK)
182-
continue;
188+
return fnv1a_hash((unsigned char *)buffer, strlen(buffer));
189+
}
183190

184-
struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
185-
const unsigned char *mac = (const unsigned char *)LLADDR(sdl);
186-
if (sdl->sdl_alen == 6) {
187-
for (int i = 0; i < 6; ++i) {
188-
salt ^= mac[i];
189-
salt *= 0x100000001b3ULL;
190-
}
191-
break;
192-
}
191+
// Final fallback: generate + store UUID
192+
static uint64_t try_random_uuid_salt(void) {
193+
FILE *fp = fopen(".device_salt", "rb");
194+
uint64_t salt;
195+
if (fp && fread(&salt, sizeof(salt), 1, fp) == 1) {
196+
fclose(fp);
197+
return salt;
193198
}
194199

195-
freeifaddrs(ifap);
200+
// Generate new one
201+
salt = ((uint64_t)rand() << 32) | rand();
202+
fp = fopen(".device_salt", "wb");
203+
if (fp) {
204+
fwrite(&salt, sizeof(salt), 1, fp);
205+
fclose(fp);
206+
}
196207
return salt;
197208
}
198209

199-
#else
200-
// =======================
201-
// Linux / BSD
202-
// =======================
203-
#include <unistd.h>
204-
#include <sys/ioctl.h>
205-
#include <net/if.h>
206-
#include <netinet/in.h>
207-
#include <sys/socket.h>
208-
209-
static uint64_t get_device_salt(void) {
210-
uint64_t salt = DEFAULT_SALT;
211-
int sock = socket(AF_INET, SOCK_DGRAM, 0);
212-
if (sock < 0) return salt;
213-
214-
struct ifreq ifr;
215-
const char *interfaces[] = { "eth0", "wlan0", "en0", "eno1" };
216-
217-
for (size_t i = 0; i < sizeof(interfaces)/sizeof(interfaces[0]); ++i) {
218-
memset(&ifr, 0, sizeof(ifr));
219-
strncpy(ifr.ifr_name, interfaces[i], sizeof(ifr.ifr_name) - 1);
220-
221-
if (ioctl(sock, 0x8927, &ifr) == 0) { // SIOCGIFHWADDR
222-
unsigned char *mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
223-
for (int j = 0; j < 6; ++j) {
224-
salt ^= mac[j];
225-
salt *= 0x100000001b3ULL;
226-
}
227-
break;
228-
}
210+
uint64_t get_device_salt(void) {
211+
uint64_t salt = 0;
212+
213+
#if defined(__linux__) || defined(__APPLE__)
214+
const char *paths[] = {
215+
"/etc/machine-id",
216+
"/var/lib/dbus/machine-id",
217+
"/sys/class/dmi/id/product_uuid"
218+
};
219+
for (int i = 0; i < 3 && !salt; ++i) {
220+
salt = try_read_file_salt(paths[i]);
229221
}
222+
#endif
223+
224+
#if defined(_WIN32)
225+
if (!salt) salt = try_windows_volume_serial_salt();
226+
#endif
230227

231-
close(sock);
228+
if (!salt) salt = try_username_hostname_salt();
229+
if (!salt) salt = try_random_uuid_salt();
232230
return salt;
233231
}
234-
#endif
235232

236233
void fossil_jellyfish_hash(const char *input, const char *output, uint8_t *hash_out) {
237234
const uint64_t PRIME = 0x100000001b3ULL;

0 commit comments

Comments
 (0)