Skip to content
Snippets Groups Projects
Commit 2b58e917 authored by William KOCH's avatar William KOCH
Browse files

Merge branch 'master' of gitlab.binets.fr:william.koch/mental-poker

parents ea666df1 ce867401
No related branches found
No related tags found
No related merge requests found
mod jacobi;
mod prime_gen;
mod gcd;
use num_bigint::BigUint; use num_bigint::BigUint;
use super::prime_gen;
use super::gcd;
use super::jacobi;
pub fn rand_astar(n: &BigUInt) -> BigUInt {
pub fn rand_astar(n: &BigUint) -> BigUint {
loop { loop {
candidate = gen_large_number(n.size(), false); let candidate = prime_gen::gen_large_number(n.bits() as usize, false);
if candidate >= n { if &candidate >= n {
continue; continue;
} }
if gcd::compute(n, &candidate) != 1 { if gcd::compute(n, &candidate) != BigUint::from(1u32) {
continue; continue;
} }
if jacobi::compute(&candidate, n) == -1 { if jacobi::compute(&candidate, n) == -1 {
...@@ -21,11 +22,11 @@ pub fn rand_astar(n: &BigUInt) -> BigUInt { ...@@ -21,11 +22,11 @@ pub fn rand_astar(n: &BigUInt) -> BigUInt {
pub fn rand_zstar(n: &BigUint) -> BigUint { pub fn rand_zstar(n: &BigUint) -> BigUint {
loop { loop {
candidate = gen_large_number(n.size(), false); let candidate = prime_gen::gen_large_number(n.bits() as usize, false);
if candidate >= n { if &candidate >= n {
continue; continue;
} }
if gcd::compute(n, &candidate) != 1 { if gcd::compute(n, &candidate) != BigUint::from(1u32) {
continue; continue;
} }
return candidate; return candidate;
......
mod gen_prime /* coin_flipping.rs
mod quadratic_residues * Part of the Mental Poker project
* Course: MAA313-2020
* Members: William Koch,
* Mihails Valtusovs,
* Olavi Äikäs
* See git history for contributions
*/
// Returns A_N, N, y, P, Q // mod prime_gen;
pub fn generate_keys() -> (Vec::<BigUint> A_N, BigUint, BigUint, BigUint, BigUint) { use super::prime_gen;
let P = prime_gen::gen_prime(512); use super::quadratic_residues;
let Q = prime_gen::gen_prime(512); use super::astarzstar;
use super::jacobi;
use super::gcd;
use rand::prelude::*;
use num_bigint::BigUint;
use num_traits::One;
let N = P * Q; fn check_quadratic_residuoity(y: &BigUint, N: &BigUint, P: &BigUint, Q: &BigUint) -> bool {
if !(gcd::compute(y, N).is_one()) {
return false;
}
if jacobi::compute(y, N) == -1 {
return false;
}
return quadratic_residues::is_n(y, P, Q);
}
// Returns N, y, P, Q
pub fn generate_keys(size: usize) -> (BigUint, BigUint, BigUint , BigUint) {
// I really hate constants - Mihails
let P = prime_gen::gen_prime(size);
let Q = prime_gen::gen_prime(size);
// TODO: Generate A_N let N = &P * &Q;
// A_N =
/* let mut y = astarzstar::rand_astar(&N);
let mut y = sample_from_A_N() while !check_quadratic_residuoity(&y, &N, &P, &Q) {
while !is_quad_res(y, p) { y = astarzstar::rand_astar(&N);
y = sample_from_A_N
} }
*/ // publicize N, y
// keep private P, Q
return (N, y, P, Q);
}
pub fn guess_whether_quadratic_residue(N: &BigUint, y: &BigUint, q: &BigUint) -> bool {
let jacobi = jacobi::compute(q, N);
if jacobi == -1 {
return false;
}
if y == q {
return false;
}
let mut rng = thread_rng();
let flip : bool = rng.gen();
return flip;
} }
\ No newline at end of file
mod prime_gen;
mod astarzstar;
mod crypto_system;
mod gcd;
mod jacobi;
mod quadratic_residues;
mod coin_flipping;
fn main() {
let (N, y, P, Q) = coin_flipping::generate_keys(10);
let q = astarzstar::rand_astar(&N);
let b_answers = coin_flipping::guess_whether_quadratic_residue(&N, &y, &q);
let mut s_b : String = String::from("");
if b_answers { s_b = String::from("is") } else { s_b = String::from("is not") }
let a_knows = quadratic_residues::is_n(&q, &P, &Q);
let mut s_a : String = String::from("");
if a_knows { s_a = String::from("is") } else { s_a = String::from("is not") }
let mut s_w : String = String::from("");
if b_answers == a_knows { s_w = String::from("won") } else { s_w = String::from("lost") }
println!("One run of coin-flipping-in-a-well: ");
println!("A generated N = {}, y = {}, P = {}, Q = {}; ", N, y, P, Q);
println!("A generated q = {}; ", q);
println!("B guessed that q {} a q.r. mod N; ", s_b);
println!("A knows that q {} a q.r. mod N; ", s_a);
println!("B {} this coin flip.", s_w);
}
\ No newline at end of file
use super::astarzstar;
use super::quadratic_residues::is_n;
use num_bigint::{BigUint}; use num_bigint::{BigUint};
use rand::prelude::*
type message = Vec<Bool>; type Message = Vec<bool>;
type ciphertext = Vec<BigUint>; type Ciphertext = Vec<BigUint>;
pub fn encrypt(message: &message, n: &BigUint, y: &BigUint) { pub fn encrypt(message: &Message, n: &BigUint, y: &BigUint) -> Ciphertext {
let mut res: ciphertext = Vec<BigUint>::with_capacity(message.len()); let mut res: Ciphertext = Vec::<BigUint>::with_capacity(message.len());
let mut rng = rand::thread_rng();
for i in 0..message.len() { for i in 0..message.len() {
let xi = rand_zn(n); let xi = astarzstar::rand_zstar(n);
if message[i] { if message[i] {
res[i] = (y*xi*xi) % n; res.push((y*&xi*&xi) % n);
} else { } else {
res[i] = xi.modpow(&BigUint::from(2u32), n); res.push(xi.modpow(&BigUint::from(2u32), n));
} }
} }
return res;
}
pub fn decrypt(cipher: &Ciphertext, p1: &BigUint, p2: &BigUint) -> Message {
let mut res = Message::with_capacity(cipher.len());
for i in 0..cipher.len() {
if is_n(&cipher[i], p1, p2) {
res.push(false);
} else {
res.push(true);
}
}
return res;
} }
mod prime_gen; mod prime_gen;
use rand::seq::SliceRandom; mod astarzstar;
mod crypto_system;
mod gcd;
mod jacobi;
mod quadratic_residues;
fn main() { fn main() {
let mut rng = rand::thread_rng();
let p1 = prime_gen::gen_prime(512); let p1 = prime_gen::gen_prime(512);
let mut p2 = prime_gen::gen_prime(512); let mut p2 = prime_gen::gen_prime(512);
while p1 == p2 { while &p1 == &p2 {
p2 = prime_gen::gen_prime(512) p2 = prime_gen::gen_prime(512);
} }
println!("Generated primes");
//p1 and p2 are unequal primes (private key) //p1 and p2 are unequal primes (private key)
let n = p1*p2; //n is the public key together with some non-residue y to be computed let n = &p1*&p2; //n is the public key together with some non-residue y to be computed
let mut y = astar(n).choose(rng); //astar (vec<bigUInt>) is the coprimes of n with jacobi symbol 1 let mut y = astarzstar::rand_astar(&n); //astar (vec<bigUInt>) is the coprimes of n with jacobi symbol 1
while is_residue(n, y) { while quadratic_residues::is_quadratic_residue_n(&y, &p1, &p2) {
//We regenerate y until its not a quadratic residue //We regenerate y until its not a quadratic residue
y = astar(n).choose(rng); y = astarzstar::rand_astar(&n);
} }
//Now (n, y) is the public key //Now (n, y) is the public key
let message = "Hello world".to_string(); let message: Vec<bool> = vec![true, true, false, false, true];
let cipher = encrypt(&n, &y, &message); let cipher = crypto_system::encrypt(&message, &n, &y);
for i in 0..5 {
println!("{}", cipher[i]);
}
let decrypted_message = crypto_system::decrypt(&cipher, &p1, &p2);
for i in 0..5 {
println!("{}", decrypted_message[i]);
}
} }
/* quadratic_residues.rs
* Part of the Mental Poker project
* Course: MAA313-2020
* Members: William Koch,
* Olavi Äikäs,
* Mihails Valtusovs
* See git history for contributions
*/
use num_bigint::{BigUint}; use num_bigint::{BigUint};
// a is assumed to be co-prime // a is assumed to be co-prime
// quadratic residue check // quadratic residue check
pub fn is_p(a: &BigUint, p: &BigUint) -> bool {
if a.modpow(&((p-1u32)/2u32), p) == BigUint::from(1u32) {
return true;
}
return false;
}
pub fn is_quadratic_residue(a: &BigUint, p: &BigUint) -> bool { pub fn is_n(a: &BigUint, p1: &BigUint, p2: &BigUint) -> bool {
a.modpow((p-1)/2, p) == 1 return is_p(a, p1) && is_p(a, p2);
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment