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 super::prime_gen;
use super::gcd;
use super::jacobi;
pub fn rand_astar(n: &BigUInt) -> BigUInt {
pub fn rand_astar(n: &BigUint) -> BigUint {
loop {
candidate = gen_large_number(n.size(), false);
if candidate >= n {
let candidate = prime_gen::gen_large_number(n.bits() as usize, false);
if &candidate >= n {
continue;
}
if gcd::compute(n, &candidate) != 1 {
if gcd::compute(n, &candidate) != BigUint::from(1u32) {
continue;
}
if jacobi::compute(&candidate, n) == -1 {
......@@ -21,11 +22,11 @@ pub fn rand_astar(n: &BigUInt) -> BigUInt {
pub fn rand_zstar(n: &BigUint) -> BigUint {
loop {
candidate = gen_large_number(n.size(), false);
if candidate >= n {
let candidate = prime_gen::gen_large_number(n.bits() as usize, false);
if &candidate >= n {
continue;
}
if gcd::compute(n, &candidate) != 1 {
if gcd::compute(n, &candidate) != BigUint::from(1u32) {
continue;
}
return candidate;
......
mod gen_prime
mod quadratic_residues
/* coin_flipping.rs
* 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
pub fn generate_keys() -> (Vec::<BigUint> A_N, BigUint, BigUint, BigUint, BigUint) {
let P = prime_gen::gen_prime(512);
let Q = prime_gen::gen_prime(512);
// mod prime_gen;
use super::prime_gen;
use super::quadratic_residues;
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
// A_N =
let N = &P * &Q;
/*
let mut y = sample_from_A_N()
while !is_quad_res(y, p) {
y = sample_from_A_N
let mut y = astarzstar::rand_astar(&N);
while !check_quadratic_residuoity(&y, &N, &P, &Q) {
y = astarzstar::rand_astar(&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 rand::prelude::*
type message = Vec<Bool>;
type ciphertext = Vec<BigUint>;
type Message = Vec<bool>;
type Ciphertext = Vec<BigUint>;
pub fn encrypt(message: &message, n: &BigUint, y: &BigUint) {
let mut res: ciphertext = Vec<BigUint>::with_capacity(message.len());
let mut rng = rand::thread_rng();
pub fn encrypt(message: &Message, n: &BigUint, y: &BigUint) -> Ciphertext {
let mut res: Ciphertext = Vec::<BigUint>::with_capacity(message.len());
for i in 0..message.len() {
let xi = rand_zn(n);
let xi = astarzstar::rand_zstar(n);
if message[i] {
res[i] = (y*xi*xi) % n;
res.push((y*&xi*&xi) % n);
} 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;
use rand::seq::SliceRandom;
mod astarzstar;
mod crypto_system;
mod gcd;
mod jacobi;
mod quadratic_residues;
fn main() {
let mut rng = rand::thread_rng();
let p1 = prime_gen::gen_prime(512);
let mut p2 = prime_gen::gen_prime(512);
while p1 == p2 {
p2 = prime_gen::gen_prime(512)
while &p1 == &p2 {
p2 = prime_gen::gen_prime(512);
}
println!("Generated primes");
//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 mut y = astar(n).choose(rng); //astar (vec<bigUInt>) is the coprimes of n with jacobi symbol 1
while is_residue(n, y) {
let n = &p1*&p2; //n is the public key together with some non-residue y to be computed
let mut y = astarzstar::rand_astar(&n); //astar (vec<bigUInt>) is the coprimes of n with jacobi symbol 1
while quadratic_residues::is_quadratic_residue_n(&y, &p1, &p2) {
//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
let message = "Hello world".to_string();
let cipher = encrypt(&n, &y, &message);
let message: Vec<bool> = vec![true, true, false, false, true];
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};
// a is assumed to be co-prime
// 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 {
a.modpow((p-1)/2, p) == 1
pub fn is_n(a: &BigUint, p1: &BigUint, p2: &BigUint) -> bool {
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