Skip to content

Commit

Permalink
WIP More throughly use SstExtension and Option
Browse files Browse the repository at this point in the history
  • Loading branch information
aewag committed Sep 3, 2024
1 parent 47a9911 commit cd1c936
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 74 deletions.
31 changes: 8 additions & 23 deletions src/hss/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use crate::{
signing::LmsSignature,
},
sst::helper::get_subtree_node_idx,
sst::parameters::SstExtension,
util::helper::read_and_advance,
};

Expand Down Expand Up @@ -59,23 +58,13 @@ impl<H: HashChain> HssPrivateKey<H> {
let parameters = private_key.compressed_parameter.to::<H>()?;
let used_leafs_indexes = private_key.compressed_used_leafs_indexes.to(&parameters);

let sst_ext_option = SstExtension {
signing_entity_idx: private_key.sst_ext.signing_entity_idx,
l0_top_div: private_key.sst_ext.l0_top_div,
};
let sst_ext_option = if sst_ext != SstExtension::default() {
Some(sst_ext)
} else {
None
};

let lms_private_key = LmsPrivateKey {
seed: current_seed.seed.clone(),
lms_tree_identifier: current_seed.lms_tree_identifier,
lmots_parameter: *parameters[0].get_lmots_parameter(),
lms_parameter: *parameters[0].get_lms_parameter(),
used_leafs_index: used_leafs_indexes[0],
sst_ext: sst_ext_option,
sst_ext: private_key.sst_option.clone(),
};
hss_private_key.private_key.push(lms_private_key);

Expand Down Expand Up @@ -126,11 +115,10 @@ impl<H: HashChain> HssPrivateKey<H> {
return hss_expand_aux_data::<H>(Some(aux_data), Some(private_key.seed.as_slice()));
}

let l0_top_div = private_key.sst_ext.l0_top_div;
let opt_l0_top_div = if 0 == l0_top_div {
None
let opt_l0_top_div = if let Some(sst_extension) = &private_key.sst_option {
Some(sst_extension.l0_top_div())
} else {
Some(l0_top_div)
None
};

// Shrink input slice
Expand Down Expand Up @@ -238,12 +226,9 @@ impl<H: HashChain> HssPublicKey<H> {
intermed_nodes: &ArrayVec<[ArrayVec<[u8; MAX_HASH_SIZE]>; MAX_SSTS_SIGNING_ENTITIES]>,
tree_identifier: &[u8; ILEN],
) -> Result<Self, ()> {
if private_key.sst_ext.signing_entity_idx == 0 || private_key.sst_ext.l0_top_div == 0 {
return Err(());
};
let sst_option = private_key.sst_option.clone().ok_or(())?;

let parameters = private_key.compressed_parameter.to::<H>()?;
let levels = parameters.len();
let used_leafs_indexes = private_key.compressed_used_leafs_indexes.to(&parameters);

let top_lms_parameter = parameters[0].get_lms_parameter();
Expand Down Expand Up @@ -273,13 +258,13 @@ impl<H: HashChain> HssPublicKey<H> {
// TODO/Rework: how do we get rid of those repeated "if let Some"?
// Additions for SSTS: add "intermediate node values" from other signing entities to AUX data
if let Some(expanded_aux_data) = opt_expanded_aux_data.as_mut() {
let num_signing_entities = 2usize.pow(private_key.sst_ext.l0_top_div as u32);
let num_signing_entities = 2usize.pow(sst_option.l0_top_div() as u32);
for si in 1..=num_signing_entities as u8 {
// node index of SI intermed node in whole tree:
let idx: usize = get_subtree_node_idx(
si,
top_lms_parameter.get_tree_height(),
private_key.sst_ext.l0_top_div,
sst_option.l0_top_div(),
) as usize;
hss_save_aux_data::<H>(
expanded_aux_data,
Expand All @@ -306,7 +291,7 @@ impl<H: HashChain> HssPublicKey<H> {

Ok(Self {
public_key: lms_keypair.public_key,
level: levels,
level: parameters.len(),
})
}

Expand Down
36 changes: 18 additions & 18 deletions src/hss/reference_impl_private_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,47 +85,47 @@ impl<H: HashChain> SeedAndLmsTreeIdentifier<H> {
}
}

#[derive(Clone, Default, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
#[derive(Default, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
pub struct ReferenceImplPrivateKey<H: HashChain> {
pub compressed_used_leafs_indexes: CompressedUsedLeafsIndexes,
pub compressed_parameter: CompressedParameterSet,
pub sst_ext: SstExtension,
pub seed: Seed<H>,
pub sst_option: Option<SstExtension>,
}

impl<H: HashChain> ReferenceImplPrivateKey<H> {
fn wipe(&mut self) {
self.seed = Seed::default();
self.compressed_parameter = CompressedParameterSet::default();
self.compressed_used_leafs_indexes = CompressedUsedLeafsIndexes::new(0);
self.sst_option = None;
}

pub fn generate(
parameters: &[HssParameter<H>],
seed: &Seed<H>,
sst_extension: Option<SstExtension>,
sst_option: Option<SstExtension>,
) -> Result<Self, ()> {
let sst_ext = sst_extension.unwrap_or_default();

let top_lms_parameter = parameters[0].get_lms_parameter();

let mut used_leafs_index: u32 = 0;
if sst_ext.l0_top_div != 0 {
used_leafs_index = helper::get_sst_first_leaf_idx(
sst_ext.signing_entity_idx,
let used_leafs_index = if let Some(sst_extension) = &sst_option {
helper::get_sst_first_leaf_idx(
sst_extension.signing_entity_idx(),
top_lms_parameter.get_tree_height(),
sst_ext.l0_top_div,
);
}
sst_extension.l0_top_div(),
)
} else {
0
};

let mut arr: [u32; MAX_ALLOWED_HSS_LEVELS] = [0; MAX_ALLOWED_HSS_LEVELS];
arr[0] = used_leafs_index;

let private_key: ReferenceImplPrivateKey<H> = ReferenceImplPrivateKey {
compressed_used_leafs_indexes: CompressedUsedLeafsIndexes::from(&arr, parameters),
compressed_parameter: CompressedParameterSet::from(parameters)?,
sst_ext,
seed: seed.clone(),
sst_option,
};

Ok(private_key)
Expand All @@ -134,9 +134,9 @@ impl<H: HashChain> ReferenceImplPrivateKey<H> {
pub fn to_binary_representation(&self) -> ArrayVec<[u8; IMPL_MAX_PRIVATE_KEY_SIZE]> {
let mut result = ArrayVec::new();

if self.sst_ext != SstExtension::default() {
result.extend_from_slice(&self.sst_ext.signing_entity_idx.to_be_bytes());
result.extend_from_slice(&self.sst_ext.l0_top_div.to_be_bytes());
if let Some(sst_extension) = &self.sst_option {
result.extend_from_slice(&sst_extension.signing_entity_idx().to_be_bytes());
result.extend_from_slice(&sst_extension.l0_top_div().to_be_bytes());
}
result.extend_from_slice(&self.compressed_used_leafs_indexes.count.to_be_bytes());
result.extend_from_slice(&self.compressed_parameter.0);
Expand All @@ -157,8 +157,8 @@ impl<H: HashChain> ReferenceImplPrivateKey<H> {
let mut index = 0;

if data.len() == SST_IMPL_MAX_PRIVATE_KEY_SIZE - MAX_SEED_LEN + H::OUTPUT_SIZE as usize {
let ssts_ext = read_and_advance(data, SST_SIZE, &mut index);
result.sst_ext = SstExtension::from_slice(ssts_ext)?;
let sst_ext = read_and_advance(data, SST_SIZE, &mut index);
result.sst_option = SstExtension::from_slice(sst_ext).ok();
}

let compressed_used_leafs_indexes =
Expand Down
4 changes: 2 additions & 2 deletions src/lms/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ impl<H: HashChain> LmsPrivateKey<H> {
if let Some(my_sst_ext) = &self.sst_ext {
// our last leafs function returns 0..total_num-1, but here we need 1..total_num
1 + get_sst_last_leaf_idx(
my_sst_ext.signing_entity_idx,
my_sst_ext.signing_entity_idx(),
self.lms_parameter.get_tree_height(),
my_sst_ext.l0_top_div,
my_sst_ext.l0_top_div(),
)
} else {
self.lms_parameter.number_of_lm_ots_keys() as u32
Expand Down
23 changes: 11 additions & 12 deletions src/sst/gen_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ pub fn prepare_sst_keygen<H: HashChain>(
if sst_param.get_signing_entity_idx() == 0 || sst_param.get_l0_top_div() == 0 {
return Err(Error::new());
}
let sst_ext = Some(SstExtension {
signing_entity_idx: sst_param.get_signing_entity_idx(),
l0_top_div: sst_param.get_l0_top_div(),
});
let sst_ext = SstExtension::new(
sst_param.get_signing_entity_idx(),
sst_param.get_l0_top_div(),
)
.ok();

// create two representations of private keys because we need their data elements
// -> ReferenceImplPrivateKey and SigningKey
Expand Down Expand Up @@ -74,12 +75,7 @@ pub fn prepare_sst_keygen<H: HashChain>(
.clone_from_slice(tree_identifier);
}

let sst_ext = SstExtension {
signing_entity_idx: rfc_private_key.sst_ext.signing_entity_idx,
l0_top_div: rfc_private_key.sst_ext.l0_top_div,
};

let sst_ext_option = Some(sst_ext);
let sst_option = rfc_private_key.sst_option.clone();

let our_node_index = get_subtree_node_idx(
sst_param.get_signing_entity_idx(),
Expand All @@ -95,7 +91,7 @@ pub fn prepare_sst_keygen<H: HashChain>(
used_leafs_index, // actually not used in "get_tree_element", irrelevant
*sst_param.get_hss_parameters()[0].get_lmots_parameter(),
*sst_param.get_hss_parameters()[0].get_lms_parameter(),
sst_ext_option,
sst_option,
);

let our_intermed_node_value = get_tree_element(
Expand All @@ -114,7 +110,8 @@ pub fn get_num_signing_entities<H: HashChain>(private_key: &[u8]) -> Result<u32,
let rfc_private_key = ReferenceImplPrivateKey::<H>::from_binary_representation(private_key)
.map_err(|_| Error::new())?;

let num_signing_entities = 2u32.pow(rfc_private_key.sst_ext.l0_top_div as u32);
let num_signing_entities =
2u32.pow(rfc_private_key.sst_option.clone().unwrap().l0_top_div() as u32);

Ok(num_signing_entities)
}
Expand All @@ -136,3 +133,5 @@ pub fn finalize_sst_keygen<H: HashChain>(

Ok(verifying_key)
}

//TODO tests needed
44 changes: 25 additions & 19 deletions src/sst/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
#[derive(Clone, PartialEq, Eq)]
pub struct SstsParameter<H: HashChain> {
hss_parameters: ArrayVec<[HssParameter<H>; constants::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]>,
// TODO/Rework: use SstExtension?
l0_top_div: u8,
signing_entity_idx: u8,
sst_extension: SstExtension,
}

impl<H: HashChain> Copy for SstsParameter<H> {}

impl<H: HashChain> SstsParameter<H> {
pub fn new(
hss_params: ArrayVec<[HssParameter<H>; constants::REF_IMPL_MAX_ALLOWED_HSS_LEVELS]>,
Expand All @@ -21,8 +17,7 @@ impl<H: HashChain> SstsParameter<H> {
) -> Self {
SstsParameter {
hss_parameters: hss_params,
l0_top_div,
signing_entity_idx,
sst_extension: SstExtension::new(signing_entity_idx, l0_top_div).unwrap(),
}
}

Expand All @@ -33,32 +28,43 @@ impl<H: HashChain> SstsParameter<H> {
}

pub fn get_l0_top_div(&self) -> u8 {
self.l0_top_div
self.sst_extension.l0_top_div()
}

pub fn get_signing_entity_idx(&self) -> u8 {
self.signing_entity_idx
self.sst_extension.signing_entity_idx()
}
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
#[derive(Debug, Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
pub struct SstExtension {
pub signing_entity_idx: u8, // from 1 to (2^l0_top_div)
pub l0_top_div: u8, // e.g. L-0 LMS height of 5 and l0_top_div = 3: division top/bottom is 3/2 -> 2^3 = 8 signing entities
signing_entity_idx: u8, // from 1 to (2^l0_top_div)
l0_top_div: u8, // e.g. L-0 LMS height of 5 and l0_top_div = 3: division top/bottom is 3/2 -> 2^3 = 8 signing entities
}

impl SstExtension {
// TODO/Review: unlike in all other locations, clippy reports
// "this returns a `Result<_, ()>`" and "use a custom `Error` type instead"
// see "Result<Self, ()>" in "hss/reference_impl_private_key.rs" -> CompressedParameterSet
pub fn new(signing_entity_idx: u8, l0_top_div: u8) -> Result<Self, ()> {
if signing_entity_idx == 0 || l0_top_div == 0 {
return Err(());
}
Ok(Self {
signing_entity_idx,
l0_top_div,
})
}

pub fn from_slice(data: &[u8]) -> Result<Self, ()> {
if data.len() != constants::SST_SIZE {
return Err(());
}
Self::new(data[0], data[1])
}

Ok(SstExtension {
signing_entity_idx: data[0],
l0_top_div: data[1],
})
pub fn signing_entity_idx(&self) -> u8 {
self.signing_entity_idx
}

pub fn l0_top_div(&self) -> u8 {
self.l0_top_div
}
}

0 comments on commit cd1c936

Please sign in to comment.