2022-11-02 03:52:28 +00:00
|
|
|
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_";
|
2022-11-30 01:31:25 +00:00
|
|
|
let sig_res = Signature::from_bytes(sig_bytes);
|
2022-11-02 03:52:28 +00:00
|
|
|
match sig_res {
|
2022-11-30 01:31:25 +00:00
|
|
|
Ok(sig) => sig.fast_aggregate_verify(true, msg, dst, pks) == BLST_ERROR::BLST_SUCCESS,
|
2022-11-02 03:52:28 +00:00
|
|
|
Err(_) => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_proof_valid<L: Merkleized>(
|
|
|
|
attested_header: &Header,
|
|
|
|
leaf_object: &mut L,
|
2022-11-30 01:31:25 +00:00
|
|
|
branch: &[Bytes32],
|
2022-11-02 03:52:28 +00:00
|
|
|
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 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()
|
2022-11-30 01:31:25 +00:00
|
|
|
.map(bytes32_to_node)
|
2022-11-02 03:52:28 +00:00
|
|
|
.collect::<Result<Vec<Node>>>()
|
|
|
|
}
|