This commit is contained in:
2024-11-18 17:58:13 +11:00
parent 279664fc84
commit 702447b8d1
6 changed files with 223 additions and 171 deletions

9
rust/Cargo.toml Normal file
View File

@@ -0,0 +1,9 @@
[package]
name = "rust"
version = "0.1.0"
edition = "2021"
[dependencies]
rayon = "1.5"
sha2 = "0.10"

30
rust/confession_fake.txt Normal file
View File

@@ -0,0 +1,30 @@
This is the secret confession of Richard Buckland
to be revealed by anonymous email if I should
mysteriously vanish. I have left the last few hex
digits of the SHA256 hash of this message with my
trusted solicitor, Dennis Denuto, which will verify
that this is indeed my intended and unaltered
confession written by me Richard Buckland.
Dennis has not seen this confession he has only seen
the last few digits of the hash. I have also sent copies
of the last few digits to my bank manager and to my priest
Father Brown.
On the 10th of February I saw Mark Zukerberg near my
house and we struck up a conversation. He explained all
the things he was doing to ensure that Facebook respects
privacy - both of its users and of others. It was very
impressive.
I feel awful that I have been criticising Facebook publicly
for so long. I apologised to him in our conversation and
now I want to confess to the world that actually Facebook
has more than enough privacy features, and that the reason
I spend so much time criticising Facebook is that I am
envious of Mark and wish I was a clever and smart and wise
as he is. I feel so bad for having been so mean to him for
so many years that I am considering retreating to the outback.
I may well cut off all contact with the world and live as a
hermit from now on. So do not worry if I vanish it is just
that I feel so guilty that I have been so unfair to Facebook.

22
rust/confession_real.txt Normal file
View File

@@ -0,0 +1,22 @@
This is the secret confession of Richard Buckland
to be revealed by anonymous email if I should
mysteriously vanish. I have left the last few hex
digits of the SHA256 hash of this message with my
trusted solicitor, Dennis Denuto, which will verify
that this is indeed my intended and unaltered
confession written by me Richard Buckland.
Dennis has not seen this confession he has only seen
the last few digits of the hash. I have also sent copies
of the last few digits to my bank manager and to my priest
Father Brown.
On the 10th of February I saw Mark Zukerberg peeping
through my window and recording my private and personal
conversation with my friend.
I confronted him and he was very embarrassed. He
promised to pay me $1 million a year if I would stay
silent and not tell anyone I had seen him do this. I
agreed but now I worry that it would be cheaper for him
to make me vanish than to keep paying me.

124
rust/src/main.rs Normal file
View File

@@ -0,0 +1,124 @@
use rayon::prelude::*;
use sha2::{Digest, Sha256};
use std::fs;
use std::io::Write;
use std::time::Instant;
use std::env;
// Function to calculate the hash for the given file content
fn calculate_hash(file_lines: &[String], num_chars: usize) -> String {
let content = file_lines.join(""); // Join lines with no separator (newlines are preserved)
let mut hasher = Sha256::new();
hasher.update(content.as_bytes());
let result = hasher.finalize();
format!("{:x}", result)[64 - num_chars..].to_string() // Get the last `num_chars` hex digits
}
// Function to generate a modified fake file by adding spaces based on the bit pattern
fn modify_and_hash(
fake_og: &[String],
num_chars: usize,
bit_pattern: u64,
real_hash: &str,
) -> Option<Vec<String>> {
let fake_modified: Vec<String> = fake_og
.iter()
.enumerate()
.map(|(idx, line)| {
let trimmed_line = line.trim_end(); // Remove trailing whitespace
let spaces_to_add = if (bit_pattern >> idx) & 1 == 1 { " " } else { "" };
format!("{}{}\n", trimmed_line, spaces_to_add)
})
.collect();
// Calculate the hash for the modified fake file
let fake_hash = calculate_hash(&fake_modified, num_chars);
// Return the modified file if the hash matches
if fake_hash == real_hash {
Some(fake_modified)
} else {
None
}
}
fn main() {
// Get command line arguments
let args: Vec<String> = env::args().collect();
if args.len() != 4 {
eprintln!("Usage: {} <real_file> <fake_file> <num_chars>", args[0]);
std::process::exit(1);
}
let real_file = &args[1];
let fake_file = &args[2];
let num_chars: usize = args[3].parse().expect("Invalid number of characters");
// Read the real and fake files
let real_og: Vec<String> = fs::read_to_string(real_file)
.expect("Failed to read real file")
.lines()
.map(|line| format!("{}\n", line)) // Preserve newlines
.collect();
let fake_og: Vec<String> = fs::read_to_string(fake_file)
.expect("Failed to read fake file")
.lines()
.map(|line| format!("{}\n", line)) // Preserve newlines
.collect();
// Calculate the hash of the real file (unmodified)
let real_hash = calculate_hash(&real_og, num_chars);
println!("Real file hash: {}", real_hash);
let mut found_collision = false;
let mut hash_counter = 0;
let start_time = Instant::now(); // Start the timer
// Search for a matching hash in parallel
while !found_collision {
// Generate a batch of bit patterns
let batch_size = 100;
let bit_patterns: Vec<u64> = (hash_counter..hash_counter + batch_size as u64).collect();
// Process the batch in parallel
let results: Vec<Option<Vec<String>>> = bit_patterns
.par_iter()
.map(|&pattern| modify_and_hash(&fake_og, num_chars, pattern, &real_hash))
.collect();
// Check if a collision was found
for result in results {
if let Some(fake_modified) = result {
let elapsed_time = start_time.elapsed();
println!(
"\nCollision found! The fake file's hash matches the real file's hash: {}",
real_hash
);
println!(
"Total hashes processed: {} in {:.2?} seconds.",
hash_counter, elapsed_time
);
// Write the modified fake file to the output
let out_file = format!("{}.out", fake_file);
let mut file = fs::File::create(out_file).expect("Failed to create output file");
for line in fake_modified {
file.write_all(line.as_bytes()).expect("Failed to write to file");
}
found_collision = true;
break;
}
}
// Update the hash counter
hash_counter += batch_size;
let elapsed_time = start_time.elapsed();
print!(
"\rProcessed {} hashes in {:.2?} seconds.",
hash_counter, elapsed_time
);
std::io::stdout().flush().unwrap();
}
}