Implement E=3 RSA broadcast attack to finish set 5
parent
86c28caf12
commit
9a5544f5a0
12
src/main.rs
12
src/main.rs
|
@ -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"));
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ impl Keypair {
|
|||
}
|
||||
|
||||
pub struct RsaPublicKey {
|
||||
e: BigNum,
|
||||
n: BigNum,
|
||||
pub e: BigNum,
|
||||
pub n: BigNum,
|
||||
}
|
||||
|
||||
pub struct RsaPrivateKey {
|
||||
|
|
48
src/set5.rs
48
src/set5.rs
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
pub fn challenge41() -> Option<()> {
|
||||
// println!("[xxxx] Challenge 41: TBD");
|
||||
None
|
||||
}
|
Loading…
Reference in New Issue