Implement E=3 RSA broadcast attack to finish set 5

main
Felix Martin 2022-10-15 14:53:39 -04:00
parent 86c28caf12
commit 9a5544f5a0
4 changed files with 59 additions and 9 deletions

View File

@ -19,6 +19,7 @@ mod set2;
mod set3;
mod set4;
mod set5;
mod set6;
mod sha1;
mod srp;
mod utils;
@ -61,10 +62,11 @@ fn main() {
set5::challenge33();
set5::challenge34();
set5::challenge35();
set5::challenge36();
set5::challenge37().unwrap_or_else(|| println!("[FAIL] challenge 37"));
set5::challenge36().unwrap_or_else(|| println!("[fail] challenge 36"));
set5::challenge37().unwrap_or_else(|| println!("[fail] challenge 37"));
}
set5::challenge38().unwrap_or_else(|| println!("[FAIL] challenge 38"));
set5::challenge39().unwrap_or_else(|| println!("[FAIL] challenge 39"));
set5::challenge40().unwrap_or_else(|| println!("[FAIL] challenge 40"));
set5::challenge38().unwrap_or_else(|| println!("[fail] challenge 38"));
set5::challenge39().unwrap_or_else(|| println!("[fail] challenge 39"));
set5::challenge40().unwrap_or_else(|| println!("[fail] challenge 40"));
set6::challenge41().unwrap_or_else(|| println!("[fail] challenge 41"));
}

View File

@ -29,8 +29,8 @@ impl Keypair {
}
pub struct RsaPublicKey {
e: BigNum,
n: BigNum,
pub e: BigNum,
pub n: BigNum,
}
pub struct RsaPrivateKey {

View File

@ -537,6 +537,50 @@ pub fn challenge39() -> Option<()> {
}
pub fn challenge40() -> Option<()> {
// println!("[xxxx] Challenge 40: implement an E=3 RSA Broadcast attack");
None
let m = BigNum::from_u32(1337).ok()?;
// 1. Capturing any 3 of the ciphertexts and their corresponding pubkeys
let (p_0, _) = rsa::rsa_gen_keys().ok()?;
let (p_1, _) = rsa::rsa_gen_keys().ok()?;
let (p_2, _) = rsa::rsa_gen_keys().ok()?;
let c_0 = rsa::rsa_encrypt(&m, &p_0).ok()?;
let c_1 = rsa::rsa_encrypt(&m, &p_1).ok()?;
let c_2 = rsa::rsa_encrypt(&m, &p_2).ok()?;
// 2. Using the CRT to solve for the number represented by the three ciphertexts (which are
// residues mod their respective pubkeys)
let rsa::RsaPublicKey { e: _, n: n_0 } = p_0;
let rsa::RsaPublicKey { e: _, n: n_1 } = p_1;
let rsa::RsaPublicKey { e: _, n: n_2 } = p_2;
// N_012 is the product of all three moduli
let n_012 = &(&n_0 * &n_1) * &n_2;
let m_s_0 = &n_1 * &n_2;
let m_s_1 = &n_0 * &n_2;
let m_s_2 = &n_0 * &n_1;
// result =
// (c_0 * m_s_0 * invmod(m_s_0, n_0)) +
// (c_1 * m_s_1 * invmod(m_s_1, n_1)) +
// (c_2 * m_s_2 * invmod(m_s_2, n_2)) mod N_012
let result = &(&(&(&(&c_0 * &m_s_0) * &rsa::invmod(&m_s_0, &n_0).ok()?)
+ &(&(&c_1 * &m_s_1) * &rsa::invmod(&m_s_1, &n_1).ok()?))
+ &(&(&c_2 * &m_s_2) * &rsa::invmod(&m_s_2, &n_2).ok()?))
% &n_012;
// 3. Taking the cube root of the resulting number
fn cube_root(n: &BigNum) -> Option<BigNum> {
let b = BigUint::from_bytes_be(&n.to_vec());
let b = b.nth_root(3);
BigNum::from_slice(&b.to_bytes_be()).ok()
}
let m_cubed = &(&m * &m) * &m;
assert_eq!(m_cubed, result, "CRT implementation did not work");
let c = cube_root(&result)?;
assert_eq!(c, m, "cube root implementation did not work");
println!("[okay] Challenge 40: implement an E=3 RSA Broadcast attack");
Some(())
}

4
src/set6.rs Normal file
View File

@ -0,0 +1,4 @@
pub fn challenge41() -> Option<()> {
// println!("[xxxx] Challenge 41: TBD");
None
}