Skip to content

Commit

Permalink
Add python bindings for Birthday paradox
Browse files Browse the repository at this point in the history
  • Loading branch information
gogo2464 committed Aug 29, 2023
1 parent ca414a6 commit 761ccaf
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 27 deletions.
21 changes: 17 additions & 4 deletions cryptatools-core/binding-testing/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,28 @@






from cryptatools_core.utils.alphabets import Encoding, Alphabet

a = Alphabet.new_empty()
empty = a.get_encoding()
assert empty == [], f"cipher={empty} incorrect empty alphabet."
print("empty encoding = {0}. OK!".format(empty))

from cryptatools_core.utils.alphabets import Encoding, Alphabet

a = Alphabet.full_hexadecimal_alphabet()
hex_alphabet = [{d.str: d.bytes} for d in a.get_encoding()]
assert hex_alphabet == [{'00': [0]}, {'01': [1]}, {'02': [2]}, {'03': [3]}, {'04': [4]}, {'05': [5]}, {'06': [6]}, {'07': [7]}, {'08': [8]}, {'09': [9]}, {'0a': [10]}, {'0b': [11]}, {'0c': [12]}, {'0d': [13]}, {'0e': [14]}, {'0f': [15]}, {'10': [16]}, {'11': [17]}, {'12': [18]}, {'13': [19]}, {'14': [20]}, {'15': [21]}, {'16': [22]}, {'17': [23]}, {'18': [24]}, {'19': [25]}, {'1a': [26]}, {'1b': [27]}, {'1c': [28]}, {'1d': [29]}, {'1e': [30]}, {'1f': [31]}, {'20': [32]}, {'21': [33]}, {'22': [34]}, {'23': [35]}, {'24': [36]}, {'25': [37]}, {'26': [38]}, {'27': [39]}, {'28': [40]}, {'29': [41]}, {'2a': [42]}, {'2b': [43]}, {'2c': [44]}, {'2d': [45]}, {'2e': [46]}, {'2f': [47]}, {'30': [48]}, {'31': [49]}, {'32': [50]}, {'33': [51]}, {'34': [52]}, {'35': [53]}, {'36': [54]}, {'37': [55]}, {'38': [56]}, {'39': [57]}, {'3a': [58]}, {'3b': [59]}, {'3c': [60]}, {'3d': [61]}, {'3e': [62]}, {'3f': [63]}, {'40': [64]}, {'41': [65]}, {'42': [66]}, {'43': [67]}, {'44': [68]}, {'45': [69]}, {'46': [70]}, {'47': [71]}, {'48': [72]}, {'49': [73]}, {'4a': [74]}, {'4b': [75]}, {'4c': [76]}, {'4d': [77]}, {'4e': [78]}, {'4f': [79]}, {'50': [80]}, {'51': [81]}, {'52': [82]}, {'53': [83]}, {'54': [84]}, {'55': [85]}, {'56': [86]}, {'57': [87]}, {'58': [88]}, {'59': [89]}, {'5a': [90]}, {'5b': [91]}, {'5c': [92]}, {'5d': [93]}, {'5e': [94]}, {'5f': [95]}, {'60': [96]}, {'61': [97]}, {'62': [98]}, {'63': [99]}, {'64': [100]}, {'65': [101]}, {'66': [102]}, {'67': [103]}, {'68': [104]}, {'69': [105]}, {'6a': [106]}, {'6b': [107]}, {'6c': [108]}, {'6d': [109]}, {'6e': [110]}, {'6f': [111]}, {'70': [112]}, {'71': [113]}, {'72': [114]}, {'73': [115]}, {'74': [116]}, {'75': [117]}, {'76': [118]}, {'77': [119]}, {'78': [120]}, {'79': [121]}, {'7a': [122]}, {'7b': [123]}, {'7c': [124]}, {'7d': [125]}, {'7e': [126]}, {'7f': [127]}, {'80': [128]}, {'81': [129]}, {'82': [130]}, {'83': [131]}, {'84': [132]}, {'85': [133]}, {'86': [134]}, {'87': [135]}, {'88': [136]}, {'89': [137]}, {'8a': [138]}, {'8b': [139]}, {'8c': [140]}, {'8d': [141]}, {'8e': [142]}, {'8f': [143]}, {'90': [144]}, {'91': [145]}, {'92': [146]}, {'93': [147]}, {'94': [148]}, {'95': [149]}, {'96': [150]}, {'97': [151]}, {'98': [152]}, {'99': [153]}, {'9a': [154]}, {'9b': [155]}, {'9c': [156]}, {'9d': [157]}, {'9e': [158]}, {'9f': [159]}, {'a0': [160]}, {'a1': [161]}, {'a2': [162]}, {'a3': [163]}, {'a4': [164]}, {'a5': [165]}, {'a6': [166]}, {'a7': [167]}, {'a8': [168]}, {'a9': [169]}, {'aa': [170]}, {'ab': [171]}, {'ac': [172]}, {'ad': [173]}, {'ae': [174]}, {'af': [175]}, {'b0': [176]}, {'b1': [177]}, {'b2': [178]}, {'b3': [179]}, {'b4': [180]}, {'b5': [181]}, {'b6': [182]}, {'b7': [183]}, {'b8': [184]}, {'b9': [185]}, {'ba': [186]}, {'bb': [187]}, {'bc': [188]}, {'bd': [189]}, {'be': [190]}, {'bf': [191]}, {'c0': [192]}, {'c1': [193]}, {'c2': [194]}, {'c3': [195]}, {'c4': [196]}, {'c5': [197]}, {'c6': [198]}, {'c7': [199]}, {'c8': [200]}, {'c9': [201]}, {'ca': [202]}, {'cb': [203]}, {'cc': [204]}, {'cd': [205]}, {'ce': [206]}, {'cf': [207]}, {'d0': [208]}, {'d1': [209]}, {'d2': [210]}, {'d3': [211]}, {'d4': [212]}, {'d5': [213]}, {'d6': [214]}, {'d7': [215]}, {'d8': [216]}, {'d9': [217]}, {'da': [218]}, {'db': [219]}, {'dc': [220]}, {'dd': [221]}, {'de': [222]}, {'df': [223]}, {'e0': [224]}, {'e1': [225]}, {'e2': [226]}, {'e3': [227]}, {'e4': [228]}, {'e5': [229]}, {'e6': [230]}, {'e7': [231]}, {'e8': [232]}, {'e9': [233]}, {'ea': [234]}, {'eb': [235]}, {'ec': [236]}, {'ed': [237]}, {'ee': [238]}, {'ef': [239]}, {'f0': [240]}, {'f1': [241]}, {'f2': [242]}, {'f3': [243]}, {'f4': [244]}, {'f5': [245]}, {'f6': [246]}, {'f7': [247]}, {'f8': [248]}, {'f9': [249]}, {'fa': [250]}, {'fb': [251]}, {'fc': [252]}, {'fd': [253]}, {'fe': [254]}, {'ff': [255]}], f"cipher={hex_alphabet} incorrect alphabet."
print("encoding = {0}. OK!".format(hex_alphabet))

from cryptatools_core.python3_bindings import *

a = Alphabet.new_empty()
empty = a.get_encoding()
assert empty == [], f"cipher={empty} incorrect empty alphabet."
print("empty encoding = {0}. OK!".format(empty))
bp = BirthdayParadox(a)
ha = "baf6dc2e647aeb6f510f9e318856a1bcd66c5e19"
hash_array = [int("0x" + ha[i] + ha[i+1], 16) for i in range(0, len(ha), 2)]
prob = bp.calculate_birthday_paradox_expecting_percent_focusing_on_speed_with_taylor(hash_array, 0.5)
assert prob == 1.4234013764919992e+24, f"birthday paradox={prob} incorrect birthday paradox."
print("birthday paradox: {0}. OK!".format(prob))
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ use num::One;
use crate::utils::alphabets::Alphabet;
use crate::utils::alphabets::split_bytes_by_characters_representation;

pub struct BirtdayParadox {
pub struct BirthdayParadox {
alphabet: Arc<Alphabet>,
}

impl BirtdayParadox {
impl BirthdayParadox {
pub fn new(alphabet: Arc<Alphabet>) -> Self {
BirtdayParadox {
BirthdayParadox {
alphabet: alphabet,
}
}
Expand All @@ -28,27 +28,27 @@ impl BirtdayParadox {
///
/// ```
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::frequency_analysis::coincidence_index::CoincidenceIndexGuesser;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirtdayParadox;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirthdayParadox;
/// use cryptatools_core::utils::alphabets::Alphabet;
/// use cryptatools_core::utils::convert::Encode;
///
/// let lowercase_hexadecimal = Alphabet::new_empty().hexadecimal_ascii_lowercase_sixteen_bits_alphabet();
/// let bp = BirtdayParadox::new(lowercase_hexadecimal.into());
/// let bp = BirthdayParadox::new(lowercase_hexadecimal.into());
/// let mut hash = Encode::from_ascii_to_u8(String::from("1"));
/// assert_eq!(hash, vec![49]);
/// assert_eq!(bp.calculate_birtday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.5), 5);//20
/// assert_eq!(bp.calculate_birtday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.95), 10);//39
/// assert_eq!(bp.calculate_birthday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.5), 5);//20
/// assert_eq!(bp.calculate_birthday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.95), 10);//39
/// hash = Encode::from_ascii_to_u8(String::from("1f9"));
/// assert_eq!(bp.calculate_birtday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.95), 16060);
/// assert_eq!(bp.calculate_birthday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.95), 16060);
/// hash = Encode::from_ascii_to_u8(String::from("1f90"));
/// assert_eq!(bp.calculate_birtday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.95), 160416);
/// assert_eq!(bp.calculate_birthday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.95), 160416);
/// //let hash = Encode::from_ascii_to_u8(String::from("00000000"));
/// //assert_eq!(bp.calculate_birtday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.50), 500);
/// //assert_eq!(bp.calculate_birthday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.50), 500);
/// //let hash = Encode::from_ascii_to_u8(String::from("1f9090aae28b8a3dceadf281b0f12828e676c326"));
/// //assert_eq!(hash, vec![49, 102, 57, 48, 57, 48, 97, 97, 101, 50, 56, 98, 56, 97, 51, 100, 99, 101, 97, 100, 102, 50, 56, 49, 98, 48, 102, 49, 50, 56, 50, 56, 101, 54, 55, 54, 99, 51, 50, 54]);
/// //assert_eq!(bp.calculate_birtday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.5), 20);
/// //assert_eq!(bp.calculate_birthday_paradox_expecting_percent_focusing_on_precision(hash.clone(), 0.5), 20);
/// ```
pub fn calculate_birtday_paradox_expecting_percent_focusing_on_precision(&self, hash_to_process: Vec<u8>, probability_expectation: f64) -> u64 {
pub fn calculate_birthday_paradox_expecting_percent_focusing_on_precision(&self, hash_to_process: Vec<u8>, probability_expectation: f64) -> u64 {
let organized_hash = split_bytes_by_characters_representation(&self.alphabet, hash_to_process);
let iter: usize = organized_hash.len() ;
let alphabet_size = self.alphabet.get_encoding().len();
Expand Down Expand Up @@ -79,17 +79,17 @@ impl BirtdayParadox {
///
/// ```
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::frequency_analysis::coincidence_index::CoincidenceIndexGuesser;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirtdayParadox;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirthdayParadox;
/// use cryptatools_core::utils::alphabets::Alphabet;
/// use cryptatools_core::utils::convert::Encode;
///
/// let lowercase_hexadecimal = Alphabet::new_empty().hexadecimal_ascii_lowercase_sixteen_bits_alphabet();
/// let mut bp = BirtdayParadox::new(lowercase_hexadecimal.into());
/// let mut bp = BirthdayParadox::new(lowercase_hexadecimal.into());
/// let hash = Encode::from_ascii_to_u8(String::from("bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0w"));
/// assert_eq!(hash, vec![98, 99, 49, 113, 120, 121, 50, 107, 103, 100, 121, 103, 106, 114, 115, 113, 116, 122, 113, 50, 110, 48, 121, 114, 102, 50, 52, 57, 51, 112, 56, 51, 107, 107, 102, 106, 104, 120, 48, 119]);
/// assert_eq!(bp.calculate_birtday_paradox_expecting_percent_focusing_on_speed_with_taylor(hash.clone(), 0.50), 1.4234013764919992e24);// should be exactly
/// assert_eq!(bp.calculate_birthday_paradox_expecting_percent_focusing_on_speed_with_taylor(hash.clone(), 0.50), 1.4234013764919992e24);// should be exactly
/// ```
pub fn calculate_birtday_paradox_expecting_percent_focusing_on_speed_with_taylor(&self, hash_to_process: Vec<u8>, probability_expectation: f64) -> f64 {
pub fn calculate_birthday_paradox_expecting_percent_focusing_on_speed_with_taylor(&self, hash_to_process: Vec<u8>, probability_expectation: f64) -> f64 {
let alphabet_size = self.alphabet.get_encoding().len();
let hash_output_bytes_len: u32 = hash_to_process.len().clone() as u32;

Expand All @@ -103,7 +103,7 @@ impl BirtdayParadox {
}


pub fn calculate_birtday_paradox(&self, objects: u64, times: u64) -> u64 {
pub fn calculate_birthday_paradox(&self, objects: u64, times: u64) -> u64 {
self.calculate_permuted_choice_number(objects, times) / times
}

Expand All @@ -124,10 +124,10 @@ impl BirtdayParadox {
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::frequency_analysis::coincidence_index::CoincidenceIndexGuesser;
/// use cryptatools_core::utils::alphabets::Alphabet;
/// use cryptatools_core::utils::convert::Encode;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirtdayParadox;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirthdayParadox;
///
/// let ascii_alphabet = Alphabet::new_empty().ascii_printable_only_encoding();
/// let bp = BirtdayParadox::new(ascii_alphabet.into());
/// let bp = BirthdayParadox::new(ascii_alphabet.into());
/// assert_eq!(bp.calculate_permuted_choice_number(5, 2), 10);
/// assert_eq!(bp.calculate_permuted_choice_number(2, 2), 1);
/// ```
Expand All @@ -141,10 +141,10 @@ impl BirtdayParadox {
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::frequency_analysis::coincidence_index::CoincidenceIndexGuesser;
/// use cryptatools_core::utils::alphabets::Alphabet;
/// use cryptatools_core::utils::convert::Encode;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirtdayParadox;
/// use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirthdayParadox;
///
/// let ascii_alphabet = Alphabet::new_empty().ascii_printable_only_encoding();
/// let bp = BirtdayParadox::new(ascii_alphabet.into());
/// let bp = BirthdayParadox::new(ascii_alphabet.into());
/// assert_eq!(bp.factorial(0), 1);
/// assert_eq!(bp.factorial(1), 1);
/// assert_eq!(bp.factorial(2), 2);
Expand Down
6 changes: 6 additions & 0 deletions cryptatools-core/src/cryptatools.udl
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,10 @@ interface CoincidenceIndexGuesser {
constructor(Alphabet alphabet);
double guess_coincidence_index(sequence<u8> cipher_text_input);
double guess_coincidence_index_statistics_from_file(string file_name);
};

interface BirthdayParadox {
constructor(Alphabet alphabet);
u64 calculate_birthday_paradox_expecting_percent_focusing_on_precision(sequence<u8> hash_to_process, f64 probability_expectation);
f64 calculate_birthday_paradox_expecting_percent_focusing_on_speed_with_taylor(sequence<u8> hash_to_process, f64 probability_expectation);
};
2 changes: 2 additions & 0 deletions cryptatools-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ use crate::utils::alphabets::{Encoding, Alphabet, split_bytes_by_characters_repr
use crate::cryptography::classical::encryption::monoalphabetic_ciphers::caesar_number::CaesarNumberAlgorithm;
use crate::cryptography::classical::encryption::transpositional_ciphers::columnar_transposition::ColumnarTranspositionAlgorithm;
use crate::cryptanalysis::general_cryptanalysis_methods::frequency_analysis::coincidence_index::CoincidenceIndexGuesser;
use crate::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirthdayParadox;


uniffi_macros::include_scaffolding!("cryptatools");
4 changes: 2 additions & 2 deletions doc-examples/ethereum-colision-evaluation/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use ethers::prelude::*;

use cryptatools_core::utils::alphabets::Alphabet;
use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirtdayParadox;
use cryptatools_core::cryptanalysis::general_cryptanalysis_methods::hash_cryptanalysis::birthday_paradox::BirthdayParadox;

const WSS_URL: &str = "wss://mainnet.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27";

#[tokio::main]
async fn main() -> eyre::Result<()> {
let hexadecimal_alphabet = Alphabet::full_hexadecimal_alphabet();
let bp = BirtdayParadox::new(hexadecimal_alphabet.into());
let bp = BirthdayParadox::new(hexadecimal_alphabet.into());

let provider = Provider::<Ws>::connect(WSS_URL).await?;
let mut stream = provider.subscribe_blocks().await?.take(1);
Expand Down

0 comments on commit 761ccaf

Please sign in to comment.