Compare commits

...

4 Commits

5 changed files with 80 additions and 39 deletions

1
.gitignore vendored
View File

@@ -5,5 +5,6 @@ Gemini.md
TropicOfCancer-HenryMiller.txt TropicOfCancer-HenryMiller.txt
.gitea_token .gitea_token
true_rng/ true_rng/
swiftrng/
# Auto-generated files (none currently) # Auto-generated files (none currently)

BIN
otp-arm64

Binary file not shown.

Binary file not shown.

113
otp.c
View File

@@ -405,7 +405,7 @@ int interactive_mode(void) {
void show_main_menu(void) { void show_main_menu(void) {
printf("\n"); printf("\n");
print_centered_header("Main Menu - OTP v0.3.11", 0); print_centered_header("Main Menu - OTP v0.3.15", 0);
printf("\n"); printf("\n");
printf(" \033[4mT\033[0mext encrypt\n"); //TEXT ENCRYPT printf(" \033[4mT\033[0mext encrypt\n"); //TEXT ENCRYPT
@@ -860,13 +860,13 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
return 1; return 1;
} }
char temp_filename[64]; char temp_filename[1024];
char pad_path[MAX_HASH_LENGTH + 20]; char pad_path[MAX_HASH_LENGTH + 20];
char state_path[MAX_HASH_LENGTH + 20]; char state_path[MAX_HASH_LENGTH + 20];
char chksum_hex[MAX_HASH_LENGTH]; char chksum_hex[MAX_HASH_LENGTH];
// Create temporary filename // Create temporary filename in the pads directory to avoid cross-filesystem issues
snprintf(temp_filename, sizeof(temp_filename), "temp_%ld.pad", time(NULL)); snprintf(temp_filename, sizeof(temp_filename), "%s/temp_%ld.pad", current_pads_dir, time(NULL));
FILE* urandom = fopen("/dev/urandom", "rb"); FILE* urandom = fopen("/dev/urandom", "rb");
if (!urandom) { if (!urandom) {
@@ -927,7 +927,10 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
fclose(pad_file); fclose(pad_file);
// Calculate XOR checksum of the 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"); printf("Error: Cannot calculate pad checksum\n");
unlink(temp_filename); unlink(temp_filename);
return 1; return 1;
@@ -936,41 +939,13 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
// Get final paths in pads directory // Get final paths in pads directory
get_pad_path(chksum_hex, pad_path, state_path); get_pad_path(chksum_hex, pad_path, state_path);
// Try rename first (works for same filesystem) // Rename temporary file to final name (atomic operation within same directory)
if (rename(temp_filename, pad_path) != 0) { if (rename(temp_filename, pad_path) != 0) {
// If rename fails, try copy and delete (works across filesystems) printf("Error: Cannot rename temporary pad file to final name\n");
FILE* temp_file = fopen(temp_filename, "rb");
FILE* dest_file = fopen(pad_path, "wb");
if (!temp_file || !dest_file) {
printf("Error: Cannot copy pad file to pads directory\n");
if (temp_file) fclose(temp_file);
if (dest_file) fclose(dest_file);
unlink(temp_filename); unlink(temp_filename);
return 1; return 1;
} }
// Copy file in chunks
unsigned char copy_buffer[64 * 1024];
size_t bytes_read;
while ((bytes_read = fread(copy_buffer, 1, sizeof(copy_buffer), temp_file)) > 0) {
if (fwrite(copy_buffer, 1, bytes_read, dest_file) != bytes_read) {
printf("Error: Failed to copy pad file to pads directory\n");
fclose(temp_file);
fclose(dest_file);
unlink(temp_filename);
unlink(pad_path);
return 1;
}
}
fclose(temp_file);
fclose(dest_file);
// Remove temporary file after successful copy
unlink(temp_filename);
}
// Set pad file to read-only // Set pad file to read-only
if (chmod(pad_path, S_IRUSR) != 0) { if (chmod(pad_path, S_IRUSR) != 0) {
printf("Warning: Cannot set pad file to read-only\n"); printf("Warning: Cannot set pad file to read-only\n");
@@ -3825,7 +3800,7 @@ int generate_ascii_armor(const char* chksum, uint64_t offset, const unsigned cha
strcpy(*ascii_output, "-----BEGIN OTP MESSAGE-----\n"); strcpy(*ascii_output, "-----BEGIN OTP MESSAGE-----\n");
char temp_line[256]; char temp_line[256];
snprintf(temp_line, sizeof(temp_line), "Version: v0.3.11\n"); snprintf(temp_line, sizeof(temp_line), "Version: v0.3.15\n");
strcat(*ascii_output, temp_line); strcat(*ascii_output, temp_line);
snprintf(temp_line, sizeof(temp_line), "Pad-ChkSum: %s\n", chksum); snprintf(temp_line, sizeof(temp_line), "Pad-ChkSum: %s\n", chksum);
@@ -4639,6 +4614,70 @@ int calculate_checksum(const char* filename, char* checksum_hex) {
return 0; 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() // 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) { 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 // Get list of pads from current directory
@@ -5567,7 +5606,7 @@ int handle_delete_pad(const char* pad_chksum) {
void print_usage(const char* program_name) { void print_usage(const char* program_name) {
printf("OTP Cipher - One Time Pad Implementation v0.3.11\n"); printf("OTP Cipher - One Time Pad Implementation v0.3.15\n");
printf("Built for testing entropy system\n"); printf("Built for testing entropy system\n");
printf("Usage:\n"); printf("Usage:\n");
printf(" %s - Interactive mode\n", program_name); printf(" %s - Interactive mode\n", program_name);

1
otp.h
View File

@@ -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 read_state_offset(const char* pad_chksum, uint64_t* offset);
int write_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(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 // UNIVERSAL CORE FUNCTIONS FOR CODE CONSOLIDATION