WIP: add checksum to shard

This commit is contained in:
Ryan Heywood 2025-04-15 18:35:13 -04:00
parent 64c75085f4
commit 739921d915
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
1 changed files with 41 additions and 12 deletions

View File

@ -25,7 +25,7 @@ use keyfork_prompt::{
},
Message as PromptMessage, PromptHandler,
};
use sha2::Sha256;
use sha2::{Digest, Sha256};
use x25519_dalek::{EphemeralSecret, PublicKey};
const PLAINTEXT_LENGTH: u8 = 32 // shard
@ -59,6 +59,21 @@ impl std::fmt::Display for RetryScanMnemonic {
}
}
fn calculate_checksum(slice: &[u8]) -> Vec<u8> {
// generate a verification checksum
// this checksum should be expensive to calculate
let mut payload = vec![];
for _ in 0..1_000_000 {
payload.extend(slice);
let mut hasher = Sha256::new();
hasher.update(&payload);
let result = hasher.finalize();
payload.clear();
payload.extend(result);
}
payload
}
#[cfg(feature = "openpgp")]
pub mod openpgp;
@ -273,14 +288,23 @@ pub trait Format {
.expect(bug!(POISONED_MUTEX))
.prompt_message(PromptMessage::Text(QRCODE_PROMPT.to_string()))?;
loop {
if let Ok(Some(qrcode_content)) = keyfork_qrcode::scan_camera(
std::time::Duration::from_secs(*QRCODE_TIMEOUT),
0,
) {
if let Ok(Some(qrcode_content)) =
keyfork_qrcode::scan_camera(std::time::Duration::from_secs(*QRCODE_TIMEOUT), 0)
{
let decoded_data = BASE64_STANDARD
.decode(qrcode_content)
.expect(bug!("qrcode should contain base64 encoded data"));
pubkey_data = Some(decoded_data.try_into().map_err(|_| InvalidData)?);
let data: [u8; 32] = decoded_data.try_into().map_err(|_| InvalidData)?;
let checksum = calculate_checksum(&data);
let small_sum = &checksum[..8];
let small_mnemonic = Mnemonic::from_raw_bytes(small_sum);
let mut prompt = prompt.lock().expect(bug!(POISONED_MUTEX));
prompt.prompt_message(PromptMessage::Text(format!(
"Is THIS your card???? If not, press ctrl+c!: {small_mnemonic}"
)))?;
pubkey_data = Some(data);
break;
} else {
let mut prompt = prompt.lock().expect(bug!(POISONED_MUTEX));
@ -535,15 +559,21 @@ pub fn remote_decrypt(w: &mut impl Write) -> Result<(), Box<dyn std::error::Erro
&BASE64_STANDARD.encode(qrcode_data),
ErrorCorrection::Highest,
) {
let checksum = calculate_checksum(key_mnemonic.as_bytes());
let small_sum = &checksum[..8];
let small_mnemonic = Mnemonic::from_raw_bytes(small_sum);
pm.prompt_message(PromptMessage::Text(format!(
concat!(
"QR code #{iter} will be displayed after this prompt. ",
"Send the QR code to the next shardholder. ",
"Only the next shardholder should scan the QR code."
"Only the next shardholder should scan the QR code. ",
),
iter = iter
iter = iter,
)))?;
pm.prompt_message(PromptMessage::Data(qrcode))?;
pm.prompt_message(PromptMessage::Text(format!(
"The following should be sent to verify the QR code: {small_mnemonic}"
)))?;
}
}
@ -562,10 +592,9 @@ pub fn remote_decrypt(w: &mut impl Write) -> Result<(), Box<dyn std::error::Erro
{
pm.prompt_message(PromptMessage::Text(QRCODE_PROMPT.to_string()))?;
loop {
if let Ok(Some(qrcode_content)) = keyfork_qrcode::scan_camera(
std::time::Duration::from_secs(*QRCODE_TIMEOUT),
0,
) {
if let Ok(Some(qrcode_content)) =
keyfork_qrcode::scan_camera(std::time::Duration::from_secs(*QRCODE_TIMEOUT), 0)
{
let decoded_data = BASE64_STANDARD
.decode(qrcode_content)
.expect(bug!("qrcode should contain base64 encoded data"));