diff --git a/.gitignore b/.gitignore index a12cb66..afa9d21 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ Gemini.md TropicOfCancer-HenryMiller.txt .gitea_token true_rng/ +swiftrng/ # Auto-generated files (none currently) diff --git a/otp-arm64 b/otp-arm64 deleted file mode 100755 index 4bc2ec2..0000000 Binary files a/otp-arm64 and /dev/null differ diff --git a/otp-x86_64 b/otp-x86_64 deleted file mode 100755 index 27a70d9..0000000 Binary files a/otp-x86_64 and /dev/null differ diff --git a/otp.c b/otp.c index abcb181..eba8fa7 100644 --- a/otp.c +++ b/otp.c @@ -405,7 +405,7 @@ int interactive_mode(void) { void show_main_menu(void) { printf("\n"); - print_centered_header("Main Menu - OTP v0.3.14", 0); + print_centered_header("Main Menu - OTP v0.3.15", 0); printf("\n"); printf(" \033[4mT\033[0mext encrypt\n"); //TEXT ENCRYPT @@ -927,7 +927,10 @@ int generate_pad(uint64_t size_bytes, int display_progress) { fclose(pad_file); // Calculate XOR checksum of the pad file - if (calculate_checksum(temp_filename, chksum_hex) != 0) { + if (display_progress) { + printf("Calculating pad checksum...\n"); + } + if (calculate_checksum_with_progress(temp_filename, chksum_hex, display_progress, size_bytes) != 0) { printf("Error: Cannot calculate pad checksum\n"); unlink(temp_filename); return 1; @@ -3797,7 +3800,7 @@ int generate_ascii_armor(const char* chksum, uint64_t offset, const unsigned cha strcpy(*ascii_output, "-----BEGIN OTP MESSAGE-----\n"); char temp_line[256]; - snprintf(temp_line, sizeof(temp_line), "Version: v0.3.14\n"); + snprintf(temp_line, sizeof(temp_line), "Version: v0.3.15\n"); strcat(*ascii_output, temp_line); snprintf(temp_line, sizeof(temp_line), "Pad-ChkSum: %s\n", chksum); @@ -4579,7 +4582,7 @@ int calculate_checksum(const char* filename, char* checksum_hex) { // Process this chunk with XOR checksum for (size_t i = 0; i < bytes_read; i++) { unsigned char bucket = (total_bytes + i) % 32; - checksum[bucket] ^= buffer[i] ^ (((total_bytes + i) >> 8) & 0xFF) ^ + checksum[bucket] ^= buffer[i] ^ (((total_bytes + i) >> 8) & 0xFF) ^ (((total_bytes + i) >> 16) & 0xFF) ^ (((total_bytes + i) >> 24) & 0xFF); } total_bytes += bytes_read; @@ -4611,6 +4614,70 @@ int calculate_checksum(const char* filename, char* checksum_hex) { return 0; } +// Calculate checksum with progress display for large files +int calculate_checksum_with_progress(const char* filename, char* checksum_hex, int display_progress, uint64_t file_size) { + FILE* file = fopen(filename, "rb"); + if (!file) { + return 1; + } + + unsigned char checksum[32]; + unsigned char buffer[64 * 1024]; // 64KB buffer for large files + size_t bytes_read; + + // Initialize checksum + memset(checksum, 0, 32); + size_t total_bytes = 0; + time_t start_time = time(NULL); + + // Calculate XOR checksum of entire file with progress + while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) { + // Process this chunk with XOR checksum + for (size_t i = 0; i < bytes_read; i++) { + unsigned char bucket = (total_bytes + i) % 32; + checksum[bucket] ^= buffer[i] ^ (((total_bytes + i) >> 8) & 0xFF) ^ + (((total_bytes + i) >> 16) & 0xFF) ^ (((total_bytes + i) >> 24) & 0xFF); + } + total_bytes += bytes_read; + + // Show progress for large files (every 64MB or if display_progress is enabled) + if (display_progress && file_size > 10 * 1024 * 1024 && total_bytes % (64 * 1024 * 1024) == 0) { + show_progress(total_bytes, file_size, start_time); + } + } + + // Final progress update + if (display_progress && file_size > 10 * 1024 * 1024) { + show_progress(file_size, file_size, start_time); + printf("\n"); + } + + fclose(file); + + // Now encrypt the checksum with the first 32 bytes of the pad + fseek(file = fopen(filename, "rb"), 0, SEEK_SET); + unsigned char pad_key[32]; + if (fread(pad_key, 1, 32, file) != 32) { + fclose(file); + return 1; + } + fclose(file); + + // XOR encrypt the checksum with pad data to create unique identifier + unsigned char encrypted_checksum[32]; + for (int i = 0; i < 32; i++) { + encrypted_checksum[i] = checksum[i] ^ pad_key[i]; + } + + // Convert to hex string (64 characters) + for (int i = 0; i < 32; i++) { + sprintf(checksum_hex + (i * 2), "%02x", encrypted_checksum[i]); + } + checksum_hex[64] = '\0'; + + return 0; +} + // Unified pad selection function - extracts the best UI from handle_pads_menu() char* select_pad_interactive(const char* title, const char* prompt, pad_filter_type_t filter_type, int allow_cancel) { // Get list of pads from current directory @@ -5539,7 +5606,7 @@ int handle_delete_pad(const char* pad_chksum) { void print_usage(const char* program_name) { - printf("OTP Cipher - One Time Pad Implementation v0.3.14\n"); + printf("OTP Cipher - One Time Pad Implementation v0.3.15\n"); printf("Built for testing entropy system\n"); printf("Usage:\n"); printf(" %s - Interactive mode\n", program_name); diff --git a/otp.h b/otp.h index a1def2a..86e0f50 100644 --- a/otp.h +++ b/otp.h @@ -223,6 +223,7 @@ void show_progress(uint64_t current, uint64_t total, time_t start_time); int read_state_offset(const char* pad_chksum, uint64_t* offset); int write_state_offset(const char* pad_chksum, uint64_t offset); int calculate_checksum(const char* filename, char* checksum_hex); +int calculate_checksum_with_progress(const char* filename, char* checksum_hex, int display_progress, uint64_t file_size); //////////////////////////////////////////////////////////////////////////////// // UNIVERSAL CORE FUNCTIONS FOR CODE CONSOLIDATION