-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Can retrieve Shannon's entropy of all stored keys
- Loading branch information
Thomas Prévost
committed
Feb 14, 2024
1 parent
0423fab
commit f23a540
Showing
8 changed files
with
189 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
pub(crate) trait EntropyAccumulator { | ||
fn add_bytes(&mut self, bytes: &[u8]); | ||
fn get_entropy(&self) -> f64; | ||
} | ||
|
||
pub(crate) struct ShannonEntropyAccumulator { | ||
/// Counter for each byte value | ||
bytes_counter: [u64; 256], | ||
/// Total received bytes | ||
total_bytes: u64, | ||
} | ||
|
||
impl ShannonEntropyAccumulator { | ||
pub(crate) fn new() -> Self { | ||
Self { | ||
bytes_counter: [0; 256], | ||
total_bytes: 0, | ||
} | ||
} | ||
} | ||
|
||
impl EntropyAccumulator for ShannonEntropyAccumulator { | ||
fn add_bytes(&mut self, bytes: &[u8]) { | ||
for byte in bytes { | ||
self.bytes_counter[*byte as usize] += 1; | ||
} | ||
self.total_bytes += bytes.len() as u64; | ||
} | ||
|
||
fn get_entropy(&self) -> f64 { | ||
let mut entropy = 0.0; | ||
for count in self.bytes_counter.iter() { | ||
if *count == 0 { | ||
continue; | ||
} | ||
let symbol_probability = *count as f64 / self.total_bytes as f64; | ||
entropy -= symbol_probability * symbol_probability.log2(); | ||
} | ||
entropy | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::entropy::EntropyAccumulator; | ||
|
||
#[test] | ||
fn test_shannon_entropy_accumulator() { | ||
let mut entropy_accumulator_1 = super::ShannonEntropyAccumulator::new(); | ||
entropy_accumulator_1.add_bytes(&[0, 0, 0, 0, 0, 0]); | ||
assert_eq!(entropy_accumulator_1.get_entropy(), 0.0); | ||
|
||
let mut entropy_accumulator_2 = super::ShannonEntropyAccumulator::new(); | ||
entropy_accumulator_2.add_bytes(&[0x00, 0x00, 0x01, 0x01, 0x02]); | ||
assert_eq!(entropy_accumulator_2.get_entropy(), 1.5219280948873621); | ||
|
||
let mut entropy_accumulator_3 = super::ShannonEntropyAccumulator::new(); | ||
entropy_accumulator_3.add_bytes("Souvent sur la montagne, à l’ombre du vieux chêne,\n".as_bytes()); | ||
assert_eq!(entropy_accumulator_3.get_entropy(), 4.465641023041018); | ||
entropy_accumulator_3.add_bytes("Au coucher du soleil, tristement je m’assieds ;\n".as_bytes()); | ||
assert_eq!(entropy_accumulator_3.get_entropy(), 4.507894683096287); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use std::convert::Infallible; | ||
use http_body_util::Full; | ||
use hyper::{body, Request, Response}; | ||
use hyper::body::Bytes; | ||
use log::error; | ||
use crate::qkd_manager::http_response_obj::HttpResponseBody; | ||
use crate::routes::request_context::RequestContext; | ||
|
||
pub(in crate::routes) async fn route_get_entropy_total(rcx: &RequestContext<'_>, _req: Request<body::Incoming>) -> Result<Response<Full<Bytes>>, Infallible> { | ||
// Get the total entropy from stored keys | ||
let entropy = match rcx.qkd_manager.get_total_keys_shannon_entropy().await { | ||
Ok(entropy) => entropy, | ||
Err(e) => { | ||
error!("Error getting total entropy: {}", e.to_string()); | ||
return super::EtsiSaeQkdRoutesV1::internal_server_error(); | ||
} | ||
}; | ||
let total_entropy_response_obj = crate::qkd_manager::http_response_obj::ResponseTotalKeysEntropy { | ||
total_entropy: entropy, | ||
}; | ||
// Return the total entropy as a JSON object response | ||
let total_entropy_response_obj_json = match total_entropy_response_obj.to_json() { | ||
Ok(json) => json, | ||
Err(_) => { | ||
error!("Error serializing total entropy object"); | ||
return super::EtsiSaeQkdRoutesV1::internal_server_error(); | ||
} | ||
}; | ||
Ok(crate::routes::EtsiSaeQkdRoutesV1::json_response_from_str(&total_entropy_response_obj_json)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"total_entropy": 3.6123008763572906 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use const_format::concatcp; | ||
use serial_test::serial; | ||
use crate::common::util::assert_string_equal; | ||
|
||
mod common; | ||
|
||
#[tokio::test] | ||
#[serial] | ||
async fn get_total_entropy() { | ||
const EXPECTED_BODY: &'static str = include_str!("data/total_entropy.json"); | ||
const REQUEST_URL: &'static str = concatcp!("https://", common::HOST_PORT ,"/api/v1/keys/entropy/total"); | ||
|
||
common::setup(); | ||
let reqwest_client = common::setup_cert_auth_reqwest_client(); | ||
|
||
let response = reqwest_client.get(REQUEST_URL).send().await; | ||
assert!(response.is_ok()); | ||
let response = response.unwrap(); | ||
assert_eq!(response.status(), 200); | ||
let response_body = response.text().await.unwrap(); | ||
assert_string_equal(&response_body, EXPECTED_BODY); | ||
} |