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