You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

454 lines
14 KiB

use super::{Felt, RpoDigest, WORD_SIZE, ZERO};
use core::slice;
// EMPTY NODES SUBTREES
// ================================================================================================
/// Contains precomputed roots of empty subtrees in a Merkle rtee of depth 64.
pub struct EmptySubtreeRoots;
impl EmptySubtreeRoots {
/// Returns a static slice with roots of empty subtrees of a Merkle tree starting at the
/// specified depth.
///
/// # Panics
///
/// This function will panic if the provided `depth` is greater than `64`.
pub const fn empty_hashes(depth: u8) -> &'static [RpoDigest] {
assert!(depth < 65);
let ptr = &EMPTY_SUBTREES_64[64 - depth as usize] as *const RpoDigest;
// Safety: this is a static/constant array, so it will never be outlived. If we attempt to
// use regular slices, this wouldn't be a `const` function, meaning we won't be able to use
// the returned value for static/constant definitions.
unsafe { slice::from_raw_parts(ptr, depth as usize + 1) }
}
}
const EMPTY_SUBTREES_64: [RpoDigest; 65] = [
RpoDigest::new([
Felt::new(15321474589252129342),
Felt::new(17373224439259377994),
Felt::new(15071539326562317628),
Felt::new(3312677166725950353),
]),
RpoDigest::new([
Felt::new(12146678323567200178),
Felt::new(14288630174929498478),
Felt::new(13374892366980833045),
Felt::new(11840636859983936891),
]),
RpoDigest::new([
Felt::new(15220380953028059006),
Felt::new(2981707349961006045),
Felt::new(7409523958661360004),
Felt::new(2816116826688969892),
]),
RpoDigest::new([
Felt::new(7829641133220670678),
Felt::new(6170216088031698405),
Felt::new(11814483661801576435),
Felt::new(1762887097744793975),
]),
RpoDigest::new([
Felt::new(1299421782687082884),
Felt::new(9938699043036414489),
Felt::new(10193025806762503939),
Felt::new(12073246492422971113),
]),
RpoDigest::new([
Felt::new(3774016405860870757),
Felt::new(2584714598467121158),
Felt::new(7418645462301488344),
Felt::new(1016804897028793820),
]),
RpoDigest::new([
Felt::new(13238072489118494737),
Felt::new(6917129315345826393),
Felt::new(13736362398490889690),
Felt::new(4929049375601714136),
]),
RpoDigest::new([
Felt::new(2433738165854950976),
Felt::new(6710644905925382197),
Felt::new(10571480102433401045),
Felt::new(16853295309134271298),
]),
RpoDigest::new([
Felt::new(3162775558610426184),
Felt::new(11944004899624546116),
Felt::new(55767976185223284),
Felt::new(5892480272697245897),
]),
RpoDigest::new([
Felt::new(12582634330812132159),
Felt::new(6886254574119140332),
Felt::new(4407453795368410417),
Felt::new(6959805977831121004),
]),
RpoDigest::new([
Felt::new(16001070406220863863),
Felt::new(4426773743735082930),
Felt::new(6860108527212616559),
Felt::new(3994703491288516722),
]),
RpoDigest::new([
Felt::new(9755907048710665826),
Felt::new(13697078808748604851),
Felt::new(17210321635283113095),
Felt::new(1203394006092675979),
]),
RpoDigest::new([
Felt::new(3332855817731547893),
Felt::new(1068928372599561798),
Felt::new(17119375903210334455),
Felt::new(8148601736624954416),
]),
RpoDigest::new([
Felt::new(17265634841675424144),
Felt::new(18322832739735580203),
Felt::new(17896992777163902308),
Felt::new(6189383326950297131),
]),
RpoDigest::new([
Felt::new(9329637674239983584),
Felt::new(2512861030579248721),
Felt::new(10833150484884266896),
Felt::new(7470498642428983444),
]),
RpoDigest::new([
Felt::new(3611140194800558886),
Felt::new(17185933650781587767),
Felt::new(7835232399818923215),
Felt::new(7974155618002781326),
]),
RpoDigest::new([
Felt::new(17483286922353768131),
Felt::new(353378057542380712),
Felt::new(1935183237414585408),
Felt::new(4820339620987989650),
]),
RpoDigest::new([
Felt::new(16172462385444809646),
Felt::new(3268597753131435459),
Felt::new(3481491333654579291),
Felt::new(16487779176137683725),
]),
RpoDigest::new([
Felt::new(16595012576192613315),
Felt::new(16028552537812484518),
Felt::new(13016887826405546773),
Felt::new(14649690775021494057),
]),
RpoDigest::new([
Felt::new(11300236651178143890),
Felt::new(15307634289168527196),
Felt::new(2834866419963148279),
Felt::new(7512874625395280090),
]),
RpoDigest::new([
Felt::new(1148273481270068529),
Felt::new(7411276436636897120),
Felt::new(14325955409748352141),
Felt::new(15577038614919538356),
]),
RpoDigest::new([
Felt::new(13911627859049081064),
Felt::new(13298542751859672529),
Felt::new(18341014824837028242),
Felt::new(5587966507704160144),
]),
RpoDigest::new([
Felt::new(10957185917743597702),
Felt::new(15815185767119166433),
Felt::new(17883994521792846784),
Felt::new(15958104556930886663),
]),
RpoDigest::new([
Felt::new(13148367538964199489),
Felt::new(7372139436485928380),
Felt::new(13408383191801051600),
Felt::new(2114382634401123096),
]),
RpoDigest::new([
Felt::new(14448157482521530067),
Felt::new(17865161921504959156),
Felt::new(10319385198642448897),
Felt::new(364163501511998552),
]),
RpoDigest::new([
Felt::new(9722640569118951143),
Felt::new(16371655672847089887),
Felt::new(12379452272155069993),
Felt::new(11605969747977185617),
]),
RpoDigest::new([
Felt::new(2782512273606877924),
Felt::new(3656296563981095117),
Felt::new(5947388149010135441),
Felt::new(1678144343036748885),
]),
RpoDigest::new([
Felt::new(10347491038074052866),
Felt::new(11061756013655443653),
Felt::new(8901792852813329415),
Felt::new(10002477867799577447),
]),
RpoDigest::new([
Felt::new(16688151588649906570),
Felt::new(12937054427339650762),
Felt::new(2125115528195796454),
Felt::new(4796610823085621719),
]),
RpoDigest::new([
Felt::new(3032620037225059051),
Felt::new(13522881885116127385),
Felt::new(6010511038055304264),
Felt::new(8199256447383686121),
]),
RpoDigest::new([
Felt::new(11250302734399433639),
Felt::new(4970037623163209776),
Felt::new(15776613712371118341),
Felt::new(5554382612311754837),
]),
RpoDigest::new([
Felt::new(5116523511540088640),
Felt::new(12381059245485642368),
Felt::new(2176361879916914688),
Felt::new(11209293198464735683),
]),
RpoDigest::new([
Felt::new(11677748883385181208),
Felt::new(15891398395707500576),
Felt::new(3790704659934033620),
Felt::new(2126099371106695189),
]),
RpoDigest::new([
Felt::new(13948603355603496603),
Felt::new(15902438544472945077),
Felt::new(1969361494026622497),
Felt::new(17326911676634210553),
]),
RpoDigest::new([
Felt::new(16081431322775411514),
Felt::new(13201312030265587002),
Felt::new(18283434127959076535),
Felt::new(9889802180847551599),
]),
RpoDigest::new([
Felt::new(8490051641633132830),
Felt::new(11985660456681176415),
Felt::new(12193381039977027251),
Felt::new(17563185381678568385),
]),
RpoDigest::new([
Felt::new(3870617340693651786),
Felt::new(2748490321246408799),
Felt::new(8501743976565218963),
Felt::new(1660720190266083389),
]),
RpoDigest::new([
Felt::new(2121119282758520982),
Felt::new(9042267662074029772),
Felt::new(15431993929052434204),
Felt::new(10659345458998811701),
]),
RpoDigest::new([
Felt::new(15206763021853065070),
Felt::new(15268692497656424421),
Felt::new(13335448435922172445),
Felt::new(3421340628484408379),
]),
RpoDigest::new([
Felt::new(5175159910654039438),
Felt::new(10258564296733764665),
Felt::new(235961379704359454),
Felt::new(18007006485615491006),
]),
RpoDigest::new([
Felt::new(9455184082727641653),
Felt::new(6634498452861935579),
Felt::new(18189776179964984407),
Felt::new(3546641211720870472),
]),
RpoDigest::new([
Felt::new(2566088177506289568),
Felt::new(7785941571143323572),
Felt::new(13948908169667863201),
Felt::new(8557252288425473395),
]),
RpoDigest::new([
Felt::new(8801845050152766755),
Felt::new(514652983374395586),
Felt::new(13975919271481418443),
Felt::new(17480955484347349170),
]),
RpoDigest::new([
Felt::new(7078477424334594989),
Felt::new(9975053207879493059),
Felt::new(5220656123503260168),
Felt::new(13795787984352794188),
]),
RpoDigest::new([
Felt::new(1478357986561897612),
Felt::new(3963701567400985039),
Felt::new(10269836564499521403),
Felt::new(11874873630603798755),
]),
RpoDigest::new([
Felt::new(936391814816943993),
Felt::new(6085855616346025677),
Felt::new(5782721339195502211),
Felt::new(10409491632083436908),
]),
RpoDigest::new([
Felt::new(11138475264090866271),
Felt::new(17799626597540451271),
Felt::new(17968790388406362807),
Felt::new(9539434947296310791),
]),
RpoDigest::new([
Felt::new(13051724588530357940),
Felt::new(8058102530250142518),
Felt::new(1861782711432586670),
Felt::new(2928050228215055187),
]),
RpoDigest::new([
Felt::new(10650694022550988030),
Felt::new(5634734408638476525),
Felt::new(9233115969432897632),
Felt::new(1437907447409278328),
]),
RpoDigest::new([
Felt::new(9720135276484706819),
Felt::new(9350120041401976641),
Felt::new(1348777594376050933),
Felt::new(13138246165242825648),
]),
RpoDigest::new([
Felt::new(10866643979409126085),
Felt::new(13790633638103642042),
Felt::new(6374461622011119670),
Felt::new(5702679962735491362),
]),
RpoDigest::new([
Felt::new(5257277882444261955),
Felt::new(8511211402794551302),
Felt::new(3294838877645533839),
Felt::new(4084864647832858048),
]),
RpoDigest::new([
Felt::new(7948776578097466250),
Felt::new(8630046431048474853),
Felt::new(11549811661672434609),
Felt::new(14329713552208961509),
]),
RpoDigest::new([
Felt::new(734617692582477804),
Felt::new(11871516935077749937),
Felt::new(12085935336918533812),
Felt::new(11028098016323141988),
]),
RpoDigest::new([
Felt::new(10937083382606895486),
Felt::new(12203867463821771187),
Felt::new(13369919265612777227),
Felt::new(2521482611471096233),
]),
RpoDigest::new([
Felt::new(1242037330294600071),
Felt::new(8643213198640797337),
Felt::new(14112360612081236212),
Felt::new(11296904697431650998),
]),
RpoDigest::new([
Felt::new(11958494925108187724),
Felt::new(6059642826232274823),
Felt::new(1563918267677757605),
Felt::new(266509853282035592),
]),
RpoDigest::new([
Felt::new(17288335252189973373),
Felt::new(3243363076395469373),
Felt::new(8880515798614590986),
Felt::new(10260780639137628077),
]),
RpoDigest::new([
Felt::new(1839714959437284152),
Felt::new(12088193186987715006),
Felt::new(10200898335013164008),
Felt::new(12768529781145127245),
]),
RpoDigest::new([
Felt::new(1537615626967151439),
Felt::new(11731506816677487155),
Felt::new(4748463589169553420),
Felt::new(17495851576537541106),
]),
RpoDigest::new([
Felt::new(957733314860117562),
Felt::new(15623410588944187169),
Felt::new(4321611031548662227),
Felt::new(12856104259650439278),
]),
RpoDigest::new([
Felt::new(14827447693720375746),
Felt::new(17296925942589213350),
Felt::new(13524332314559504765),
Felt::new(15663886706087995199),
]),
RpoDigest::new([
Felt::new(18185978518863914335),
Felt::new(936586966360019113),
Felt::new(497299419609993926),
Felt::new(1977881506773614749),
]),
RpoDigest::new([
Felt::new(8635338869442206704),
Felt::new(11671305615285950885),
Felt::new(15253023094703789604),
Felt::new(7398108415970215319),
]),
RpoDigest::new([ZERO; WORD_SIZE]),
];
#[test]
fn all_depths_opens_to_zero() {
use super::Rpo256;
for depth in 1..=64 {
// fetch the subtrees and reverse it so the path is leaf -> root
let mut subtree = EmptySubtreeRoots::empty_hashes(depth).to_vec();
subtree.reverse();
// the length of the subtrees set must be equal to depth + 1 as we also
// include the root
assert_eq!(depth as usize + 1, subtree.len());
// assert the opening is zero
let initial = RpoDigest::new([ZERO; WORD_SIZE]);
assert_eq!(initial, subtree.remove(0));
// compute every node of the path manually and compare with the output
subtree
.into_iter()
.scan(initial, |state, x| {
*state = Rpo256::merge(&[*state; 2]);
Some((x, *state))
})
.for_each(|(x, computed)| assert_eq!(x, computed));
}
}
#[test]
fn arbitrary_inputs_will_generate_sound_slices() {
let min = &EMPTY_SUBTREES_64[0] as *const RpoDigest;
let max = unsafe { min.add(64) };
for depth in 0..=64 {
let subtree = EmptySubtreeRoots::empty_hashes(depth);
let first = &subtree[0] as *const RpoDigest;
let last = &subtree[depth as usize] as *const RpoDigest;
assert!(min <= first && first <= max);
assert!(min <= last && last <= max);
}
}