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

Propagate private and public key changes to coin flipping

parent d505f0de
No related branches found
No related tags found
No related merge requests found
......@@ -18,7 +18,7 @@ use rand::prelude::*;
use num_bigint::BigUint;
use num_traits::One;
use super::crypto_system::{Message, Ciphertext};
use super::crypto_system::{Plaintext, Ciphertext, PrivateKey, PublicKey};
fn check_quadratic_residuoity(y: &BigUint, N: &BigUint, P: &BigUint, Q: &BigUint) -> bool {
if !(gcd::compute(y, N).is_one()) {
......@@ -31,7 +31,7 @@ fn check_quadratic_residuoity(y: &BigUint, N: &BigUint, P: &BigUint, Q: &BigUint
}
// Returns N, y, P, Q
pub fn generate_keys(size: usize) -> (BigUint, BigUint, BigUint , BigUint) {
pub fn generate_keys(size: usize) -> (PrivateKey, PublicKey) {
// I really hate constants - Mihails
let P = prime_gen::gen_prime(size);
let Q = prime_gen::gen_prime(size);
......@@ -43,17 +43,20 @@ pub fn generate_keys(size: usize) -> (BigUint, BigUint, BigUint , BigUint) {
y = astarzstar::rand_astar(&N);
}
let privkey = PrivateKey { p: P, q: Q };
let pubkey = PublicKey { N: N, y: y };
// publicize N, y
// keep private P, Q
return (N, y, P, Q);
(privkey, pubkey)
}
pub fn guess_whether_quadratic_residue(N: &BigUint, y: &BigUint, q: &BigUint) -> bool {
let jacobi = jacobi::compute(q, N);
pub fn guess_whether_quadratic_residue(pubkey: &PublicKey, q: &BigUint) -> bool {
let jacobi = jacobi::compute(q, &pubkey.N);
if jacobi != 1 {
return false;
}
if y == q {
if &pubkey.y == q {
return false;
}
......@@ -78,10 +81,10 @@ pub fn values_sender(n: usize, N: &BigUint) -> Ciphertext {
/* The receiver receives the big numbers and
* sends guesses */
pub fn values_receiver(N: &BigUint, y: &BigUint, b: &Ciphertext) -> Message {
let mut a: Message = Message::with_capacity(b.len());
pub fn values_receiver(pubkey: &PublicKey, b: &Ciphertext) -> Plaintext {
let mut a: Plaintext = Plaintext::with_capacity(b.len());
for i in 0..b.len() {
a.push(guess_whether_quadratic_residue(N, y, &b[i]));
a.push(guess_whether_quadratic_residue(&pubkey, &b[i]));
}
return a;
}
......@@ -89,12 +92,12 @@ pub fn values_receiver(N: &BigUint, y: &BigUint, b: &Ciphertext) -> Message {
/* The sender receives the guesses and knows
* whether the receiver succeeded their coin throws
* from the original numbers that the sender also has */
pub fn values_checker(b: &Ciphertext, a: &Message, P: &BigUint, Q: &BigUint) -> Message {
pub fn values_checker(b: &Ciphertext, a: &Plaintext, privkey: &PrivateKey) -> Plaintext {
assert_eq!(b.len(), a.len());
let mut m: Message = Message::with_capacity(a.len());
let mut m: Plaintext = Plaintext::with_capacity(a.len());
for i in 0..a.len() {
let a_guessed = a[i];
let b_knows = quadratic_residues::is_n(&b[i], P, Q);
let b_knows = quadratic_residues::is_n(&b[i], &privkey.p, &privkey.q);
if a_guessed == b_knows {
m.push(true);
} else {
......
......@@ -8,7 +8,7 @@ mod jacobi;
mod quadratic_residues;
mod coin_flipping;
use crypto_system::{Ciphertext, Message};
use crypto_system::{Ciphertext, Plaintext};
fn main() {
let (N, y, P, Q) = coin_flipping::generate_keys(10);
......@@ -43,18 +43,18 @@ fn main() {
let b_q: Vec<bool> = b.iter().map(|x| quadratic_residues::is_n(&(x.clone()), &P, &Q)).collect::<Vec<_>>();
println!("Their quadratic residuoity is as follows: {:?}", b_q);
let a: Message = coin_flipping::values_receiver(&N, &y, &b);
let a: Plaintext = coin_flipping::values_receiver(&N, &y, &b);
println!("A did 10 guesses: {:?}", a);
let c: Ciphertext = crypto_system::encrypt(&a, &N, &y);
println!("A encrypted their guesses to send them to B: {:?}", c);
let a_d: Message = crypto_system::decrypt(&c, &P, &Q);
let a_d: Plaintext = crypto_system::decrypt(&c, &P, &Q);
print!("B decrypted A's guesses: {:?}. They ", a_d);
if a_d != a {print!("do not ");}
println!("match what A sent.");
let m: Message = coin_flipping::values_checker(&b, &a, &P, &Q);
let m: Plaintext = coin_flipping::values_checker(&b, &a, &P, &Q);
println!("Here are the results of the coin flips: {:?}", m);
println!("...");
......@@ -62,9 +62,9 @@ fn main() {
println!("Generating 10000 values...");
let b: Ciphertext = coin_flipping::values_sender(10000usize, &N);
println!("Generated 10000 values...");
let a: Message = coin_flipping::values_receiver(&N, &y, &b);
let a: Plaintext = coin_flipping::values_receiver(&N, &y, &b);
println!("Generated 10000 guesses...");
let m: Message = coin_flipping::values_checker(&b, &a, &P, &Q);
let m: Plaintext = coin_flipping::values_checker(&b, &a, &P, &Q);
println!("Checked 10000 guesses...");
let n: usize = m.iter().map(|&x| if x {1usize} else {0usize}).sum();
let f = (n as f64) / (10000f64);
......
......@@ -5,43 +5,68 @@ mod gcd;
mod jacobi;
mod quadratic_residues;
mod card_deck;
mod coin_flipping;
use crypto_system::{Ciphertext, Plaintext};
fn main() {
let cards = card_deck::gen_card_deck(32, 8);
println!("{:?}", cards);
let (privkey, pubkey) = coin_flipping::generate_keys(10);
let q = astarzstar::rand_astar(&pubkey.N);
let b_answers = coin_flipping::guess_whether_quadratic_residue(&pubkey, &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, &privkey.p, &privkey.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 = {}; ", pubkey.N, pubkey.y, privkey.p, privkey.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);
println!("...");
println!("Now we try the aggregate coin-flipping.");
let b: Ciphertext = coin_flipping::values_sender(10usize, &pubkey.N);
println!("B generated 10 values: {:?}", b);
let p1 = prime_gen::gen_prime(32);
let mut p2 = prime_gen::gen_prime(32);
while &p1 == &p2 {
p2 = prime_gen::gen_prime(32);
}
println!("Generated primes");
//p1 and p2 are unequal primes (private key)
let privkey = crypto_system::PrivateKey{p: p1, q: p2};
let n = &privkey.p*&privkey.q; //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_n(&y, &privkey.p, &privkey.q) {
//We regenerate y until its not a quadratic residue
y = astarzstar::rand_astar(&n);
}
//Now (n, y) is the public key
let message: Vec<bool> = vec![true, true, false, false, true];
let pubkey = crypto_system::PublicKey{N: n, y: y};
let b_q: Vec<bool> = b.iter().map(|x| quadratic_residues::is_n(&(x.clone()), &privkey.p, &privkey.q)).collect::<Vec<_>>();
println!("Their quadratic residuoity is as follows: {:?}", b_q);
let a: Plaintext = coin_flipping::values_receiver(&pubkey, &b);
println!("A did 10 guesses: {:?}", a);
let c: Ciphertext = crypto_system::encrypt(&a, &pubkey);
println!("A encrypted their guesses to send them to B: {:?}", c);
let cipher = crypto_system::encrypt(&message, &pubkey);
for i in 0..5 {
println!("{}", cipher[i]);
}
let decrypted_message = crypto_system::decrypt(&cipher, &privkey);
for i in 0..5 {
println!("{}", decrypted_message[i]);
}
println!("{:?}", cards[0]);
let encr_card : card_deck::EncrCard = crypto_system::encrypt_card(&cards[0], &pubkey);
println!("{:?}", encr_card);
println!("{:?}", crypto_system::decrypt_card(&Box::new(encr_card), &privkey));
let a_d: Plaintext = crypto_system::decrypt(&c, &privkey);
print!("B decrypted A's guesses: {:?}. They ", a_d);
if a_d != a {print!("do not ");}
println!("match what A sent.");
let m: Plaintext = coin_flipping::values_checker(&b, &a, &privkey);
println!("Here are the results of the coin flips: {:?}", m);
println!("...");
println!("Now let's check that aggregate coin-flipping is not biased.");
println!("Generating 10000 values...");
let b: Ciphertext = coin_flipping::values_sender(10000usize, &pubkey.N);
println!("Generated 10000 values...");
let a: Plaintext = coin_flipping::values_receiver(&pubkey, &b);
println!("Generated 10000 guesses...");
let m: Plaintext = coin_flipping::values_checker(&b, &a, &privkey);
println!("Checked 10000 guesses...");
let n: usize = m.iter().map(|&x| if x {1usize} else {0usize}).sum();
let f = (n as f64) / (10000f64);
println!("Frequency of true over 10000 flips: {}", f);
}
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