98 lines
2.6 KiB
Rust
98 lines
2.6 KiB
Rust
|
use blst::{
|
||
|
min_pk::{PublicKey, Signature},
|
||
|
BLST_ERROR,
|
||
|
};
|
||
|
use common::{types::Bytes32, utils::bytes32_to_node};
|
||
|
use eyre::Result;
|
||
|
use ssz_rs::prelude::*;
|
||
|
|
||
|
use crate::types::{Header, SignatureBytes};
|
||
|
|
||
|
pub fn calc_sync_period(slot: u64) -> u64 {
|
||
|
let epoch = slot / 32; // 32 slots per epoch
|
||
|
epoch / 256 // 256 epochs per sync committee
|
||
|
}
|
||
|
|
||
|
pub fn is_aggregate_valid(sig_bytes: &SignatureBytes, msg: &[u8], pks: &[&PublicKey]) -> bool {
|
||
|
let dst: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
|
||
|
let sig_res = Signature::from_bytes(&sig_bytes);
|
||
|
match sig_res {
|
||
|
Ok(sig) => sig.fast_aggregate_verify(true, msg, dst, &pks) == BLST_ERROR::BLST_SUCCESS,
|
||
|
Err(_) => false,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn is_proof_valid<L: Merkleized>(
|
||
|
attested_header: &Header,
|
||
|
leaf_object: &mut L,
|
||
|
branch: &Vec<Bytes32>,
|
||
|
depth: usize,
|
||
|
index: usize,
|
||
|
) -> bool {
|
||
|
let res: Result<bool> = (move || {
|
||
|
let leaf_hash = leaf_object.hash_tree_root()?;
|
||
|
let state_root = bytes32_to_node(&attested_header.state_root)?;
|
||
|
let branch = branch_to_nodes(branch.to_vec())?;
|
||
|
|
||
|
let is_valid = is_valid_merkle_branch(&leaf_hash, branch.iter(), depth, index, &state_root);
|
||
|
Ok(is_valid)
|
||
|
})();
|
||
|
|
||
|
if let Ok(is_valid) = res {
|
||
|
is_valid
|
||
|
} else {
|
||
|
false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(SimpleSerialize, Default, Debug)]
|
||
|
struct SigningData {
|
||
|
object_root: Bytes32,
|
||
|
domain: Bytes32,
|
||
|
}
|
||
|
|
||
|
#[derive(SimpleSerialize, Default, Debug)]
|
||
|
struct ForkData {
|
||
|
current_version: Vector<u8, 4>,
|
||
|
genesis_validator_root: Bytes32,
|
||
|
}
|
||
|
|
||
|
pub fn compute_signing_root(object_root: Bytes32, domain: Bytes32) -> Result<Node> {
|
||
|
let mut data = SigningData {
|
||
|
object_root,
|
||
|
domain,
|
||
|
};
|
||
|
Ok(data.hash_tree_root()?)
|
||
|
}
|
||
|
|
||
|
pub fn compute_domain(
|
||
|
domain_type: &[u8],
|
||
|
fork_version: Vector<u8, 4>,
|
||
|
genesis_root: Bytes32,
|
||
|
) -> Result<Bytes32> {
|
||
|
let fork_data_root = compute_fork_data_root(fork_version, genesis_root)?;
|
||
|
let start = domain_type;
|
||
|
let end = &fork_data_root.as_bytes()[..28];
|
||
|
let d = [start, end].concat();
|
||
|
Ok(d.to_vec().try_into().unwrap())
|
||
|
}
|
||
|
|
||
|
fn compute_fork_data_root(
|
||
|
current_version: Vector<u8, 4>,
|
||
|
genesis_validator_root: Bytes32,
|
||
|
) -> Result<Node> {
|
||
|
let current_version = current_version.try_into()?;
|
||
|
let mut fork_data = ForkData {
|
||
|
current_version,
|
||
|
genesis_validator_root,
|
||
|
};
|
||
|
Ok(fork_data.hash_tree_root()?)
|
||
|
}
|
||
|
|
||
|
pub fn branch_to_nodes(branch: Vec<Bytes32>) -> Result<Vec<Node>> {
|
||
|
branch
|
||
|
.iter()
|
||
|
.map(|elem| bytes32_to_node(elem))
|
||
|
.collect::<Result<Vec<Node>>>()
|
||
|
}
|