OPEN 28/6



0by 0x tinyZED imageTEXT theTUBE

- conservation of creation -

zett

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

#define FILE_PATH "glass.bowl.candies.jpg"
#define NUM_ITERATIONS 1250000

#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
#define QR(a, b, c, d) (             \
    a += b, d ^= a, d = ROTL(d, 16), \
    c += d, b ^= c, b = ROTL(b, 12), \
    a += b, d ^= a, d = ROTL(d,  8), \
    c += d, b ^= c, b = ROTL(b,  7))
#define ROUNDS 20

// Function to read a binary file as bits
bool *read_binary_file_as_bits(const char *file_path, size_t *length) {
    FILE *file = fopen(file_path, "rb");
    if (!file) {
        perror("Failed to open file");
        exit(EXIT_FAILURE);
    }

    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    unsigned char *binary_data = (unsigned char *)malloc(file_size);
    fread(binary_data, 1, file_size, file);
    fclose(file);

    *length = file_size * 8;
    bool *truth_values = (bool *)malloc(*length * sizeof(bool));

    for (long i = 0; i < file_size; ++i) {
        for (int bit = 0; bit < 8; ++bit) {
            truth_values[i * 8 + bit] = (binary_data[i] & (1 << bit)) != 0;
        }
    }

    free(binary_data);
    return truth_values;
}

// Function to calculate runs of truth values
int *calculate_runs(const bool *truth_values, size_t length, size_t *runs_length) {
    int *runs = (int *)malloc(length * sizeof(int));
    size_t index = 0;
    int current_run_length = 1;

    for (size_t i = 1; i < length; ++i) {
        if (truth_values[i]) {
            runs[index++] = current_run_length;
            current_run_length = 1;
        } else {
            current_run_length++;
        }
    }

    *runs_length = index;
    return runs;
}

// Function to replace the first pair of runs
void replace_first_pair_of_runs(int *runs, size_t runs_length) {
    if (runs_length >= 3) {
        int run1 = runs[0];
        int run2 = runs[1];
        int run3 = runs[2];

        if (run1 == run2 && run1 == 1) {
            for (size_t i = 0; i < runs_length - 1; ++i) {
                runs[i] = runs[i + 1];
            }
            runs[0] = 1;
        } else {
            int t = run1 + run2 - 1;
            run2 = run1;
            run1 = t;

            if (run1 == run2) {
                for (size_t i = 0; i < runs_length - 1; ++i) {
                    runs[i] = runs[i + 1];
                }
                runs[0] = run1;
                runs[1] = run2 + run3 - 1;
            } else {
                runs[0] = run1;
                runs[1] = run2;
            }
        }
    }
}

// Function to generate a sequence of truth values from runs
bool *true_false_sequence(const int *runs, size_t runs_length, size_t *length) {
    size_t total_length = 0;

    for (size_t i = 0; i < runs_length; ++i) {
        total_length += runs[i];
    }

    bool *truth_values = (bool *)malloc(total_length * sizeof(bool));
    size_t index = 0;

    for (size_t i = 0; i < runs_length; ++i) {
        for (int j = 0; j < runs[i] - 1; ++j) {
            truth_values[index++] = true;
        }
        truth_values[index++] = false;
    }

    *length = total_length;
    return truth_values;
}

// Chacha20 block function for generating pseudorandom values
void chacha_block(uint32_t out[16], uint32_t const in[16]) {
    int i;
    uint32_t x[16];

    for (i = 0; i < 16; ++i)
        x[i] = in[i];

    for (i = 0; i < ROUNDS; i += 2) {
        QR(x[0], x[4], x[ 8], x[12]);
        QR(x[1], x[5], x[ 9], x[13]);
        QR(x[2], x[6], x[10], x[14]);
        QR(x[3], x[7], x[11], x[15]);

        QR(x[0], x[5], x[10], x[15]);
        QR(x[1], x[6], x[11], x[12]);
        QR(x[2], x[7], x[ 8], x[13]);
        QR(x[3], x[4], x[ 9], x[14]);
    }

    for (i = 0; i < 16; ++i)
        out[i] = x[i] + in[i];
}

// Function to generate pseudorandom truth values
void generate_pseudorandom_truths(uint32_t seed, int count, int truths[]) {
    uint32_t input[16] = {
        0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
        0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
        0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
        0x00000001, seed, 0x4a000000, 0x00000000
    };
    uint32_t output[16];
    int i, j;

    for (i = 0; i < count; ++i) {
        chacha_block(output, input);
        for (j = 0; j < 16 && i < count; ++j, ++i) {
            truths[i] = output[j] & 1; 
        }
    }
}

// Function to XOR truth values with pseudorandom truth values
void xor_truth_values(uint32_t *current_seed, bool *truth_values, size_t length) {
    int count = length;
    int *pseudorandom_truths = (int *)malloc(count * sizeof(int));

    generate_pseudorandom_truths(*current_seed, count, pseudorandom_truths);

    for (size_t i = 0; i < 16; ++i) {
        truth_values[i] ^= pseudorandom_truths[i % count];
    }

    free(pseudorandom_truths);
    *current_seed -= 133;
}

// Main processing function
bool *process_runs(uint32_t current_seed, const char *file_path, size_t num_iterations, size_t *final_length) {
    size_t length;
    bool *truth_values = read_binary_file_as_bits(file_path, &length);

    for (size_t i = 0; i < num_iterations; ++i) {
        size_t runs_length;
        int *runs = calculate_runs(truth_values, length, &runs_length);
        replace_first_pair_of_runs(runs, runs_length);
        free(truth_values);

        truth_values = true_false_sequence(runs, runs_length, &length);
        free(runs);

        xor_truth_values(&current_seed, truth_values, length);
    }

    *final_length = length;
    return truth_values;
}

// Function to transform truth values to binary bytes
unsigned char *truth_values_to_binary_bytes(const bool *truth_values, size_t length) {
    unsigned char *binary_bytes = (unsigned char *)malloc(length * sizeof(unsigned char));

    for (size_t i = 0; i < length; ++i) {
        binary_bytes[i] = truth_values[i] ? 0xFF : 0x00;
    }

    return binary_bytes;
}

int main() {
    uint32_t current_seed = 0x31515433; // Example seed
    size_t num_iterations = NUM_ITERATIONS;
    size_t final_length;
    bool *final_bits = process_runs(current_seed, FILE_PATH, num_iterations, &final_length);

    unsigned char *binary_bytes = truth_values_to_binary_bytes(final_bits, final_length);
    free(final_bits);

    FILE *output_file = fopen("output.bin", "wb");
    if (!output_file) {
        perror("Failed to open output file");
        free(binary_bytes);
        exit(EXIT_FAILURE);
    }

    fwrite(binary_bytes, 1, final_length, output_file);
    fclose(output_file);
    free(binary_bytes);

    printf("Binary output has been written to output.bin\n");
    printf("Final length: %zu\n", final_length);

    return 0;
}