Skip to content

Commit c6bc756

Browse files
committed
use sha256 hashes instead of crc32
1 parent 5371041 commit c6bc756

File tree

9 files changed

+155
-47
lines changed

9 files changed

+155
-47
lines changed

linux/makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ PIPEWIRE_LIBS = $(shell pkg-config --libs libpipewire-0.3)
3131
JACK_CFLAGS = $(shell pkg-config --cflags jack)
3232
JACK_LIBS = $(shell pkg-config --libs jack)
3333

34-
CFLAGS += $(GTK3_CFLAGS) $(ALSA_CFLAGS) $(PULSE_CFLAGS) $(PIPEWIRE_CFLAGS) $(JACK_CFLAGS)
34+
CFLAGS += $(GTK3_CFLAGS) $(ALSA_CFLAGS) $(PULSE_CFLAGS) $(PIPEWIRE_CFLAGS) $(JACK_CFLAGS) $(shell pkg-config --cflags openssl)
3535

3636
INCS = -I../external/sdl/build/include/ -I../external/imgui/ -I../external/stb/ -I../shared/
37-
LIBS = -L../external/sdl/build/lib -lSDL2-2.0 -lGL $(GTK3_LIBS) $(ALSA_LIBS) $(PULSE_LIBS) $(PIPEWIRE_LIBS) $(JACK_LIBS) $(ESD_LIBS) $(SNDIO_LIBS) -lm -ldl -lpthread
37+
LIBS = -L../external/sdl/build/lib -lSDL2-2.0 -lGL $(GTK3_LIBS) $(ALSA_LIBS) $(PULSE_LIBS) $(PIPEWIRE_LIBS) $(JACK_LIBS) $(ESD_LIBS) $(SNDIO_LIBS) -lm -ldl -lpthread $(shell pkg-config --libs openssl)
3838

3939
# SDL dependency files
4040
SDL_LIB = ../external/sdl/build/lib/libSDL2-2.0.so.0
@@ -45,7 +45,7 @@ BOOTROM_HEADER = ../shared/bootrom.h
4545
BOOTROM_SOURCE = ../roms/Kiwi8_logo_2.ch8
4646

4747
# Source files
48-
CORE_SRCS = ../shared/audio.cc ../shared/chip8.cc ../shared/crc32.cc ../shared/display.cc ../shared/gui.cc \
48+
CORE_SRCS = ../shared/audio.cc ../shared/chip8.cc ../shared/sha256.cc ../shared/display.cc ../shared/gui.cc \
4949
../shared/input.cc ../shared/main.cc \
5050
../shared/toast.cc ../shared/open_file_dialog.cc ../shared/profiles.cc
5151
IMGUI_SRCS = ../external/imgui/imgui.cpp ../external/imgui/imgui_draw.cpp ../external/imgui/imgui_impl_sdl.cpp

macos/makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ APP_BUNDLE = $(APP_NAME).app
1616
APP_EXE = $(APP_NAME)
1717

1818
CC = clang++
19-
CFLAGS = -std=c++17 -Wall -mmacosx-version-min=11.0 -MMD -MP -DAPP_NAME='"$(APP_NAME)"' -DVERSION='"$(VERSION)"' -DSUB_VERSION='"$(SUB_VERSION)"'
19+
CFLAGS = -std=c++17 -Wall -mmacosx-version-min=11.0 -MMD -MP -DAPP_NAME='"$(APP_NAME)"' -DVERSION='"$(VERSION)"' -DSUB_VERSION='"$(SUB_VERSION)"' $(shell pkg-config --cflags openssl)
2020
LFLAGS = -mmacosx-version-min=11.0
2121
INCS = -I../external/sdl/build/include/ -I../external/imgui/ -I../external/stb/ -I../shared/
22-
LIBS = -L../external/sdl/build/lib/ -lSDL2-2.0.0 -framework Cocoa -framework OpenGL
22+
LIBS = -L../external/sdl/build/lib/ -lSDL2-2.0.0 -framework Cocoa -framework OpenGL $(shell pkg-config --libs openssl)
2323

2424
# SDL dependency files
2525
SDL_LIB = ../external/sdl/build/lib/libSDL2-2.0.0.dylib
@@ -30,7 +30,7 @@ BOOTROM_HEADER = ../shared/bootrom.h
3030
BOOTROM_SOURCE = ../roms/Kiwi8_logo_2.ch8
3131

3232
# Source files
33-
CORE_SRCS = ../shared/audio.cc ../shared/chip8.cc ../shared/crc32.cc ../shared/display.cc ../shared/gui.cc \
33+
CORE_SRCS = ../shared/audio.cc ../shared/chip8.cc ../shared/sha256.cc ../shared/display.cc ../shared/gui.cc \
3434
../shared/input.cc ../shared/main.cc \
3535
../shared/toast.cc ../shared/open_file_dialog.cc ../shared/profiles.cc
3636
IMGUI_SRCS = ../external/imgui/imgui.cpp ../external/imgui/imgui_draw.cpp ../external/imgui/imgui_impl_sdl.cpp

shared/chip8.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "audio.h"
66
#include "opcodes.h"
77
#include "profiles.h"
8-
#include "crc32.h"
8+
#include "sha256.h"
99
#include "toast.h"
1010
#include "open_file_dialog.h"
1111
#include <SDL2/SDL.h>
@@ -176,9 +176,9 @@ int chip8_load_rom(const char *rom_filepath) {
176176
snprintf(notif_msg, sizeof(notif_msg), "ROM loaded: %s", chip8.rom_filename);
177177
toast_show(TOAST_SUCCESS, notif_msg);
178178

179-
/* Compute CRC32 and lookup profile */
180-
uint32_t crc = crc32_compute(chip8.rom, chip8.rom_size);
181-
const struct profile *profile = profile_lookup(crc);
179+
/* Compute SHA256 and lookup profile */
180+
sha256_hash_t sha256 = sha256_compute(chip8.rom, chip8.rom_size);
181+
const struct profile *profile = profile_lookup(&sha256);
182182

183183
if (profile) {
184184
/* Apply profile quirks */

shared/profiles.cc

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#include "profiles.h"
22
#define STB_DS_IMPLEMENTATION
33
#include "stb_ds.h"
4-
#include "crc32.h"
4+
#include "sha256.h"
55
#include "chip8.h"
66
#include "toast.h"
77
#include <SDL2/SDL.h>
88
#include <stdio.h>
99
#include <string.h>
1010
#include <stddef.h>
1111

12-
/* ROM profile hashmap: CRC32 -> profile */
13-
static struct { uint32_t key; struct profile value; } *profile_map = NULL;
12+
/* ROM profile hashmap: SHA256 -> profile */
13+
static struct { sha256_hash_t key; struct profile value; } *profile_map = NULL;
1414

1515
/* Track which path we loaded profiles.ini from */
1616
static char loaded_profiles_path[512] = "";
@@ -36,7 +36,7 @@ static int create_profiles_file(const char *path) {
3636
FILE *file = fopen(path, "w");
3737
if (!file) return 0;
3838
fprintf(file, "# ROM Profiles Database\n");
39-
fprintf(file, "# Format: [0xCRC32] followed by quirk settings\n\n");
39+
fprintf(file, "# Format: [0xSHA256] followed by quirk settings\n\n");
4040
fclose(file);
4141
return 1;
4242
}
@@ -47,7 +47,8 @@ static void parse_profiles_ini(void) {
4747
if (!file) return;
4848

4949
char line[512];
50-
uint32_t current_crc = 0;
50+
sha256_hash_t current_sha256 = {0};
51+
int has_current = 0;
5152
struct profile current_profile;
5253

5354
while (fgets(line, sizeof(line), file)) {
@@ -58,23 +59,46 @@ static void parse_profiles_ini(void) {
5859
/* Skip empty lines and comments */
5960
if (line[0] == '\0' || line[0] == '#') continue;
6061

61-
/* Section header [0xHEXVALUE] */
62+
/* Section header [0xHEXVALUE] - 64 hex chars for SHA256 */
6263
if (line[0] == '[') {
63-
if (current_crc != 0) hmput(profile_map, current_crc, current_profile);
64+
if (has_current) hmput(profile_map, current_sha256, current_profile);
6465

65-
if (sscanf(line, "[0x%x]", &current_crc) != 1) {
66+
char hex_str[65];
67+
if (sscanf(line, "[%64[0-9a-fA-F]]", hex_str) != 1) {
6668
printf("Error: Invalid profile section header: %s\n", line);
67-
current_crc = 0;
69+
has_current = 0;
6870
continue;
6971
}
72+
73+
/* Parse 64 hex characters into 32 bytes */
74+
if (strlen(hex_str) != 64) {
75+
printf("Error: SHA256 must be 64 hex characters: %s\n", hex_str);
76+
has_current = 0;
77+
continue;
78+
}
79+
80+
for (int i = 0; i < 32; i++) {
81+
unsigned int byte;
82+
if (sscanf(hex_str + i*2, "%2x", &byte) != 1) {
83+
printf("Error: Invalid hex in SHA256: %s\n", hex_str);
84+
has_current = 0;
85+
goto next_line;
86+
}
87+
current_sha256.bytes[i] = (uint8_t)byte;
88+
}
89+
7090
memset(&current_profile, 0, sizeof(current_profile));
71-
current_profile.crc32 = current_crc;
91+
current_profile.sha256 = current_sha256;
7292
current_profile.quirks = quirks_get_defaults();
93+
has_current = 1;
94+
continue;
95+
96+
next_line:
7397
continue;
7498
}
7599

76100
/* Key=value pairs */
77-
if (current_crc == 0) continue;
101+
if (!has_current) continue;
78102

79103
char key[256];
80104
int value;
@@ -96,7 +120,7 @@ static void parse_profiles_ini(void) {
96120
}
97121

98122
/* Commit last entry */
99-
if (current_crc != 0) hmput(profile_map, current_crc, current_profile);
123+
if (has_current) hmput(profile_map, current_sha256, current_profile);
100124
fclose(file);
101125
}
102126

@@ -177,8 +201,8 @@ void profiles_init(const char *custom_path) {
177201
}
178202
}
179203

180-
const struct profile* profile_lookup(uint32_t crc32) {
181-
ptrdiff_t idx = hmgeti(profile_map, crc32);
204+
const struct profile* profile_lookup(const sha256_hash_t *sha256) {
205+
ptrdiff_t idx = hmgeti(profile_map, *sha256);
182206
return (idx >= 0) ? &profile_map[idx].value : NULL;
183207
}
184208

@@ -196,11 +220,13 @@ static void profiles_write_to_file(void) {
196220
}
197221

198222
fprintf(file, "# ROM Profiles Database\n");
199-
fprintf(file, "# Format: [0xCRC32] followed by quirk settings\n\n");
223+
fprintf(file, "# Format: [0xSHA256] followed by quirk settings\n\n");
200224

201225
for (int i = 0; i < hmlen(profile_map); i++) {
202226
struct profile *p = &profile_map[i].value;
203-
fprintf(file, "[0x%X]\n", p->crc32);
227+
char hash_hex[65];
228+
sha256_to_hex(&p->sha256, hash_hex, sizeof(hash_hex));
229+
fprintf(file, "[%s]\n", hash_hex);
204230
if (p->rom_name[0] != '\0') fprintf(file, "name=%s\n", p->rom_name);
205231
for (size_t q = 0; q < NUM_QUIRK_FIELDS; q++) {
206232
bool val = *(bool *)((char *)&p->quirks + quirk_fields[q].offset);
@@ -222,18 +248,20 @@ void profiles_save_current(void) {
222248
return;
223249
}
224250

225-
uint32_t crc = crc32_compute(chip8.rom, chip8.rom_size);
251+
sha256_hash_t sha256 = sha256_compute(chip8.rom, chip8.rom_size);
226252

227253
struct profile p;
228254
memset(&p, 0, sizeof(p));
229-
p.crc32 = crc;
255+
p.sha256 = sha256;
230256
set_path(p.rom_name, sizeof(p.rom_name), chip8.rom_filename);
231257
p.quirks = chip8.quirks;
232258

233-
hmput(profile_map, crc, p);
259+
hmput(profile_map, sha256, p);
234260
profiles_write_to_file();
235261

236-
printf("Saved ROM profile for: %s (CRC32: 0x%X)\n", chip8.rom_filename, crc);
262+
char hash_hex[65];
263+
sha256_to_hex(&sha256, hash_hex, sizeof(hash_hex));
264+
printf("Saved ROM profile for: %s (SHA256: %s)\n", chip8.rom_filename, hash_hex);
237265
char msg[256];
238266
snprintf(msg, sizeof(msg), "Profile saved: %s", chip8.rom_filename);
239267
toast_show(TOAST_SUCCESS, msg);

shared/profiles.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33

44
#include <stdint.h>
55
#include "quirks.h"
6+
#include "sha256.h"
67

78
struct profile {
8-
uint32_t crc32;
9+
sha256_hash_t sha256;
910
char rom_name[256];
1011
struct quirks quirks;
1112
};
@@ -14,8 +15,8 @@ struct profile {
1415
* Pass a custom file path, or NULL to use default search paths. */
1516
void profiles_init(const char *custom_path);
1617

17-
/* Lookup a ROM profile by CRC32. Returns NULL if not found. */
18-
const struct profile* profile_lookup(uint32_t crc32);
18+
/* Lookup a ROM profile by SHA256. Returns NULL if not found. */
19+
const struct profile* profile_lookup(const sha256_hash_t *sha256);
1920

2021
/* Save current ROM's quirks to the profile database and INI file
2122
* Requires: chip8.rom, chip8.rom_size, chip8.rom_filename, chip8.quirks

shared/profiles.ini

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Kiwi8 ROM Profiles Database
22

3-
# Format: [0xCRC32] followed by quirk settings
3+
# Format: [0xSHA256] followed by quirk settings
44

5-
[0x9D307E90]
5+
[22ca535175f53fd0c8c0295b77198d7830a9c44b81497f14ee1fbc6c1322adc0]
66
name=Blinky [Hans Christian Egeberg, 1991].ch8
77
load_store_quirk=1
88
shift_quirk=1
@@ -13,7 +13,7 @@ draw_flag_quirk=0
1313
vwrap=1
1414
hwrap=0
1515

16-
[0x6FF0A017]
16+
[00bb7001de52b562d98357d33375406c6d0308466d7d95c2580537d2451a75cd]
1717
name=Space Invaders [David Winter].ch8
1818
load_store_quirk=0
1919
shift_quirk=0
@@ -24,7 +24,7 @@ draw_flag_quirk=0
2424
vwrap=0
2525
hwrap=1
2626

27-
[0x614BA7F]
27+
[cfc1c1948c4419c3d45d98d8704885d8a0bc84d0d32022e069ac9119febe6035]
2828
name=Astro Dodge [Revival Studios, 2008].ch8
2929
load_store_quirk=1
3030
shift_quirk=1
@@ -35,7 +35,7 @@ draw_flag_quirk=0
3535
vwrap=1
3636
hwrap=0
3737

38-
[0x9858889B]
38+
[871349b9cac53b5f99aabd3e25a71ad9979b85f1e7664049ad62fe288d1a0557]
3939
name=Connect 4 [David Winter].ch8
4040
load_store_quirk=1
4141
shift_quirk=1
@@ -46,7 +46,7 @@ draw_flag_quirk=0
4646
vwrap=1
4747
hwrap=0
4848

49-
[0x61861AE5]
49+
[4f0b0ea0ca8cb819574dd1bef22943dd04282e005647f9dcfd9246d4e2458a89]
5050
name=Hidden [David Winter, 1996].ch8
5151
load_store_quirk=1
5252
shift_quirk=1
@@ -57,7 +57,7 @@ draw_flag_quirk=0
5757
vwrap=1
5858
hwrap=0
5959

60-
[0x3A297A10]
60+
[4a07eed424eb5bbea779386f1c600f61ec7f6125539f64e4073cae2aeba7c039]
6161
name=Tic-Tac-Toe [David Winter].ch8
6262
load_store_quirk=1
6363
shift_quirk=1
@@ -68,7 +68,7 @@ draw_flag_quirk=0
6868
vwrap=1
6969
hwrap=0
7070

71-
[0x511CDD7A]
71+
[f6024fea49433bb48b05fa05f7ab1d80696684d7cd89f884315494ed08fa4f22]
7272
name=Stars [Sergey Naydenov, 2010].ch8
7373
load_store_quirk=1
7474
shift_quirk=1
@@ -79,7 +79,7 @@ draw_flag_quirk=0
7979
vwrap=1
8080
hwrap=0
8181

82-
[0xAAA44D0B]
82+
[c435e310ed832846a10f6d19e103910400a97dce27745370cb18207f24baee39]
8383
name=Brix [Andreas Gustafsson, 1990].ch8
8484
load_store_quirk=0
8585
shift_quirk=0
@@ -90,7 +90,7 @@ draw_flag_quirk=0
9090
vwrap=0
9191
hwrap=1
9292

93-
[0x331413E7]
93+
[281d3bcc61227e15a5d3294b0e10facc156ec1bd819a3018d92e3ccf3a07acf1]
9494
name=UFO [Lutz V, 1992].ch8
9595
load_store_quirk=0
9696
shift_quirk=0
@@ -101,7 +101,7 @@ draw_flag_quirk=0
101101
vwrap=0
102102
hwrap=1
103103

104-
[0x6465ACEF]
104+
[c37c9f76fa1061e1eb15e66ad76536798c84024bd67a64735cc454de0857f889]
105105
name=Animal Race [Brian Astle].ch8
106106
load_store_quirk=0
107107
shift_quirk=1

shared/sha256.cc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "sha256.h"
2+
#include <string.h>
3+
#include <stdio.h>
4+
#include <openssl/evp.h>
5+
6+
sha256_hash_t sha256_compute(const uint8_t* data, size_t len) {
7+
sha256_hash_t result;
8+
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
9+
10+
if (!mdctx) {
11+
memset(&result, 0, sizeof(result));
12+
return result;
13+
}
14+
15+
if (!EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) {
16+
EVP_MD_CTX_free(mdctx);
17+
memset(&result, 0, sizeof(result));
18+
return result;
19+
}
20+
21+
if (!EVP_DigestUpdate(mdctx, data, len)) {
22+
EVP_MD_CTX_free(mdctx);
23+
memset(&result, 0, sizeof(result));
24+
return result;
25+
}
26+
27+
unsigned int digest_len = 0;
28+
if (!EVP_DigestFinal_ex(mdctx, result.bytes, &digest_len)) {
29+
EVP_MD_CTX_free(mdctx);
30+
memset(&result, 0, sizeof(result));
31+
return result;
32+
}
33+
34+
EVP_MD_CTX_free(mdctx);
35+
return result;
36+
}
37+
38+
void sha256_to_hex(const sha256_hash_t *hash, char *dst, size_t dst_size) {
39+
if (dst_size < 65) return; /* 64 hex chars + null terminator */
40+
41+
for (int i = 0; i < 32; i++) {
42+
snprintf(dst + i*2, 3, "%02x", hash->bytes[i]);
43+
}
44+
dst[64] = '\0';
45+
}
46+
47+
int sha256_equal(const sha256_hash_t *a, const sha256_hash_t *b) {
48+
for (int i = 0; i < 32; i++) {
49+
if (a->bytes[i] != b->bytes[i]) {
50+
return 0;
51+
}
52+
}
53+
return 1;
54+
}

0 commit comments

Comments
 (0)