init in gitea
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
115
Cargo.lock
generated
Normal file
115
Cargo.lock
generated
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitvec"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||||
|
dependencies = [
|
||||||
|
"funty",
|
||||||
|
"radium",
|
||||||
|
"tap",
|
||||||
|
"wyz",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dske_poc"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bitvec",
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "funty"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.155"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tap"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||||
|
dependencies = [
|
||||||
|
"tap",
|
||||||
|
]
|
||||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "dske_poc"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitvec = "1.0.1"
|
||||||
|
rand = "0.8.5"
|
||||||
39
README.md
Normal file
39
README.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# DSKE Poc
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This is a proof of concept of the DSKE system, the main goal is to demonstrate the algorithm in the DSKE. There are a few assumptions are limitations in this proof-of-concept project.
|
||||||
|
|
||||||
|
1. This is not a working protocol, this project is just to prove the algorithm concept.
|
||||||
|
2. This project is demonstrating a simple DSKE protocol, which means n = k. It is a (n, n) secret sharing scheme.
|
||||||
|
3. The code assumes that the final key sender (Alice) chooses all her security hubs and all her security hubs include the receiver (Bob) as another client.
|
||||||
|
4. The code assumes that all the random bits transfer successfully. Bob won't abort the protocol in the key construction phase.
|
||||||
|
5. The code assumes every security hub and client won't run out of random bits.
|
||||||
|
|
||||||
|
## DSKE Main Phases
|
||||||
|
|
||||||
|
1. PSKM generation and distribution
|
||||||
|
|
||||||
|
the `SecurityHub.register_client` method will generate random bits, store it and return the clone of the random bits. `Client.register_securityhub` method will store the random bits clone so that the security hub and the client will have their copy of the random bits.
|
||||||
|
|
||||||
|
2. Peer identity establishment
|
||||||
|
|
||||||
|
For this proof-of-concept project, the code assumes that the sender (Alice) and the receiver (Bob) are registered in the same security hubs.
|
||||||
|
|
||||||
|
3. Key agreement
|
||||||
|
|
||||||
|
1. Share generation
|
||||||
|
|
||||||
|
The proof-of-concept project will use (n, n) secret sharing scheme in a simple DSKE protocol, using all the security hubs the user registered. The final key S can be checked by the method `Client.generate_final_key`.
|
||||||
|
|
||||||
|
2. Share distribution
|
||||||
|
|
||||||
|
Each security hub will use the method `SecurityHub.generate_key_instruction` to generate a key instruction A (Alice's random bits) XOR B (Bob's random bits).
|
||||||
|
|
||||||
|
3. Key Reconstruction
|
||||||
|
|
||||||
|
Bob can use the method `Client.retrieve_key` to calculate A ^ B ^ B to retrieve A in each share. Bob can reconstruct the final key S by executing XOR in every share in the simple DSKE protocol (n, n) secret sharing scheme.
|
||||||
|
|
||||||
|
4. Key validation
|
||||||
|
|
||||||
|
The proof-of-concept project assumes all the share's key instructions are delivered correctly, the simple DSKE protocol with (n, n) secret sharing scheme won't be abort in this proof-of-concept project.
|
||||||
201
src/main.rs
Normal file
201
src/main.rs
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use rand::Rng;
|
||||||
|
use bitvec::prelude::BitVec;
|
||||||
|
|
||||||
|
struct PSKM {
|
||||||
|
random_bits: BitVec,
|
||||||
|
usage: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SecurityHub {
|
||||||
|
name: String,
|
||||||
|
client_hashmap: HashMap<String, PSKM>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SecurityHub {
|
||||||
|
fn new(name: &str) -> SecurityHub {
|
||||||
|
SecurityHub {
|
||||||
|
name: String::from(name),
|
||||||
|
client_hashmap: HashMap::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate random bits and pre-share to client
|
||||||
|
fn register_client(&mut self, client_name: String) -> BitVec {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
// number of random bits to generate
|
||||||
|
let num_bits = 100;
|
||||||
|
|
||||||
|
let mut random_bits: BitVec = BitVec::with_capacity(num_bits);
|
||||||
|
|
||||||
|
// generate and store the random bits
|
||||||
|
for _ in 0..num_bits {
|
||||||
|
let random_bit: u8 = rng.gen_range(0..=1);
|
||||||
|
random_bits.push(random_bit == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the random bit in security hub
|
||||||
|
self.client_hashmap.insert(client_name, PSKM {
|
||||||
|
random_bits: random_bits.clone(),
|
||||||
|
usage: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// return the clone of random bit to the client
|
||||||
|
return random_bits.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate A ^ B
|
||||||
|
fn generate_key_instruction(&mut self, sender: String, receiver: String, key_size: i32) -> BitVec{
|
||||||
|
// get the random bits of the sender
|
||||||
|
let sender_pskm = self.client_hashmap.get(&sender).unwrap();
|
||||||
|
// get the random bits of the receiver
|
||||||
|
let receiver_pskm = self.client_hashmap.get(&receiver).unwrap();
|
||||||
|
|
||||||
|
let mut key_instruction: BitVec = BitVec::with_capacity(key_size as usize);
|
||||||
|
|
||||||
|
// calculate key instruction A ^ B
|
||||||
|
for i in 0..key_size {
|
||||||
|
let sender_bit = if *sender_pskm.random_bits.get((i + sender_pskm.usage) as usize).unwrap() { true } else { false };
|
||||||
|
let receiver_bit = if *receiver_pskm.random_bits.get((i + receiver_pskm.usage) as usize).unwrap() { true } else { false };
|
||||||
|
let xor_result = sender_bit ^ receiver_bit;
|
||||||
|
key_instruction.push(xor_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// increate the random bits usage by key_size
|
||||||
|
let sender_pskm = self.client_hashmap.get_mut(&sender).unwrap();
|
||||||
|
sender_pskm.usage += key_size;
|
||||||
|
|
||||||
|
let receiver_pskm = self.client_hashmap.get_mut(&receiver).unwrap();
|
||||||
|
receiver_pskm.usage += key_size;
|
||||||
|
|
||||||
|
return key_instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Client {
|
||||||
|
name: String,
|
||||||
|
securityhub_hashmap: HashMap<String, PSKM>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
fn new(name: &str) -> Client {
|
||||||
|
Client {
|
||||||
|
name: String::from(name),
|
||||||
|
securityhub_hashmap: HashMap::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the random bits from security hub
|
||||||
|
fn register_securityhub(&mut self, security_hub_name: String, random_bits: BitVec) {
|
||||||
|
self.securityhub_hashmap.insert(security_hub_name, PSKM {
|
||||||
|
random_bits,
|
||||||
|
usage: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// using the random bits by every security hub and calculate the XOR result
|
||||||
|
fn generate_final_key(&mut self, key_size: i32) -> BitVec {
|
||||||
|
let mut final_key: BitVec = BitVec::with_capacity(key_size as usize);
|
||||||
|
for i in 0..key_size {
|
||||||
|
let mut xor_result: bool = false; // pre-assign the value to false just because the compiler is warning
|
||||||
|
// the the random bits from every security hub, calculate the XOR result
|
||||||
|
for (index, (_, pskm)) in self.securityhub_hashmap.iter().enumerate() {
|
||||||
|
let bit_value = if *pskm.random_bits.get(i as usize + pskm.usage as usize).unwrap() { true } else { false };
|
||||||
|
if index == 0 {
|
||||||
|
xor_result = bit_value
|
||||||
|
} else {
|
||||||
|
xor_result = xor_result ^ bit_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final_key.push(xor_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for every security hub PSKM, increment the usage by key_size
|
||||||
|
for (_, pskm) in self.securityhub_hashmap.iter_mut() {
|
||||||
|
pskm.usage += key_size;
|
||||||
|
}
|
||||||
|
return final_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate A ^ B ^ B
|
||||||
|
fn retrieve_key(&mut self, security_hub_name: String, key_instruction: BitVec, _sender: String) -> BitVec {
|
||||||
|
let mut key: BitVec = BitVec::with_capacity(key_instruction.len());
|
||||||
|
let pskm = self.securityhub_hashmap.get_mut(&security_hub_name).unwrap();
|
||||||
|
for i in 0..key_instruction.len() {
|
||||||
|
let bit_value = if *pskm.random_bits.get((i as usize + pskm.usage as usize) as usize).unwrap() { true } else { false };
|
||||||
|
let xor_result = bit_value ^ *key_instruction.get(i).unwrap();
|
||||||
|
key.push(xor_result);
|
||||||
|
}
|
||||||
|
pskm.usage += key_instruction.len() as i32;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_client_to_security_hub(security_hub: &mut SecurityHub, client: &mut Client) {
|
||||||
|
let random_bits = security_hub.register_client(client.name.clone());
|
||||||
|
client.register_securityhub(security_hub.name.clone(), random_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut security_hub_hash_map: HashMap<String, SecurityHub> = HashMap::new();
|
||||||
|
security_hub_hash_map.insert(String::from("SH1"), SecurityHub::new("SH1"));
|
||||||
|
security_hub_hash_map.insert(String::from("SH2"), SecurityHub::new("SH2"));
|
||||||
|
security_hub_hash_map.insert(String::from("SH3"), SecurityHub::new("SH3"));
|
||||||
|
|
||||||
|
|
||||||
|
let mut client_hash_map: HashMap<String, Client> = HashMap::new();
|
||||||
|
client_hash_map.insert(String::from("Alice"), Client::new("Alice"));
|
||||||
|
client_hash_map.insert(String::from("Bob"), Client::new("Bob"));
|
||||||
|
|
||||||
|
//register client to security hub, pre-share the random bits from security to client
|
||||||
|
register_client_to_security_hub(security_hub_hash_map.get_mut("SH1").unwrap(), client_hash_map.get_mut("Alice").unwrap());
|
||||||
|
register_client_to_security_hub(security_hub_hash_map.get_mut("SH2").unwrap(), client_hash_map.get_mut("Alice").unwrap());
|
||||||
|
register_client_to_security_hub(security_hub_hash_map.get_mut("SH3").unwrap(), client_hash_map.get_mut("Alice").unwrap());
|
||||||
|
|
||||||
|
register_client_to_security_hub(security_hub_hash_map.get_mut("SH1").unwrap(), client_hash_map.get_mut("Bob").unwrap());
|
||||||
|
register_client_to_security_hub(security_hub_hash_map.get_mut("SH2").unwrap(), client_hash_map.get_mut("Bob").unwrap());
|
||||||
|
register_client_to_security_hub(security_hub_hash_map.get_mut("SH3").unwrap(), client_hash_map.get_mut("Bob").unwrap());
|
||||||
|
|
||||||
|
// the final key size
|
||||||
|
let key_size = 20;
|
||||||
|
|
||||||
|
// for simple DSKE protocol, generate XOR of every security hub random bits
|
||||||
|
let final_key_generate_by_alice = client_hash_map.get_mut("Alice").unwrap().generate_final_key(key_size);
|
||||||
|
let final_key_generate_by_alice_bits: String = final_key_generate_by_alice.iter().map(|bit| if *bit { "1" } else { "0" }).collect();
|
||||||
|
println!("Final Key Generate by Alice: {}", final_key_generate_by_alice_bits);
|
||||||
|
|
||||||
|
// generate key instruction in every security hub (assume all Alice's security hub include Bob)
|
||||||
|
let mut key_instruction_vec: Vec<(String, BitVec)> = Vec::new();
|
||||||
|
for (_, (security_hub_name, _)) in client_hash_map.get("Alice").unwrap().securityhub_hashmap.iter().enumerate() {
|
||||||
|
let target_security_hub = String::from(security_hub_name);
|
||||||
|
let key_instruction = security_hub_hash_map.get_mut(security_hub_name).unwrap().generate_key_instruction(String::from("Alice"),String::from("Bob"), key_size);
|
||||||
|
key_instruction_vec.push((target_security_hub, key_instruction));
|
||||||
|
}
|
||||||
|
|
||||||
|
// for every key instruction, calculate A ^ B ^ B to retrieve A
|
||||||
|
let mut alice_bits: Vec<BitVec> = Vec::new();
|
||||||
|
for (security_hub_name, key_instruction) in key_instruction_vec {
|
||||||
|
let alice_bits_retrieve_from_xor = client_hash_map.get_mut("Bob").unwrap().retrieve_key(security_hub_name, key_instruction, String::from("Alice"));
|
||||||
|
alice_bits.push(alice_bits_retrieve_from_xor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reconstruct the final key
|
||||||
|
let mut final_key_reconstruct_by_bob: BitVec = BitVec::with_capacity(key_size as usize);
|
||||||
|
for i in 0..key_size {
|
||||||
|
let mut xor_result: bool = false; // pre-assign the value to false just because the compiler is warning
|
||||||
|
for (index, bit_vec) in alice_bits.iter().enumerate() {
|
||||||
|
let bit_value = if *bit_vec.get(i as usize).unwrap() { true } else { false };
|
||||||
|
if index == 0 {
|
||||||
|
xor_result = bit_value
|
||||||
|
} else {
|
||||||
|
xor_result = xor_result ^ bit_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final_key_reconstruct_by_bob.push(xor_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
let final_key_reconstruct_by_bob_bits: String = final_key_reconstruct_by_bob.iter().map(|bit| if *bit { "1" } else { "0" }).collect();
|
||||||
|
println!("Final Key Reconstruct by Bob: {}", final_key_reconstruct_by_bob_bits);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user