init in gitea

This commit is contained in:
2024-08-01 11:25:35 +08:00
commit 94006c220f
5 changed files with 366 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

115
Cargo.lock generated Normal file
View 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
View 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
View 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
View 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);
}