Counter ASIC 3.0 gates (hash): the v4 unit test follows the amendment (the base program is its own stream over class v3's load slots and era draw; every load site obeys the source rule)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
d8859522d0
commit
4aa0c665e8
1 changed files with 20 additions and 4 deletions
|
|
@ -1739,8 +1739,9 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Counter ASIC 3.0 (6 October 2026): class v4 is class v3 with the latency-shadow block `sh256x27`, drawn after
|
/// Counter ASIC 3.0 (6 October 2026): class v4 is class v3 with the latency-shadow block `sh256x27`, drawn after
|
||||||
/// the base program, so a v4 program's base instructions, attempt and era draw are the v3 program's of the same
|
/// the base program; since the AP-F8-1 amendment (7 October 2026) its base program draws a load's source only
|
||||||
/// seed and era, draw for draw; its generator is 4, its id `program_id(4, seed, attempt)`, its era recorded;
|
/// from registers whose last writer keeps entropy, so it is its own stream over class v3's load slots and era
|
||||||
|
/// draw; its generator is 4, its id `program_id(4, seed, attempt)` with the sub-version suffix, its era recorded;
|
||||||
/// v2 and v3 are untouched.
|
/// v2 and v3 are untouched.
|
||||||
#[test]
|
#[test]
|
||||||
fn program_class_v4_is_class_v3_with_the_shadow_block() {
|
fn program_class_v4_is_class_v3_with_the_shadow_block() {
|
||||||
|
|
@ -1757,9 +1758,24 @@ mod tests {
|
||||||
assert_eq!(v4.generator, GENERATOR_VERSION_V4);
|
assert_eq!(v4.generator, GENERATOR_VERSION_V4);
|
||||||
assert_eq!(v4.program_class(), ProgramClass::V4);
|
assert_eq!(v4.program_class(), ProgramClass::V4);
|
||||||
assert_eq!(v4.era_bytes.as_deref(), Some(&era[..]));
|
assert_eq!(v4.era_bytes.as_deref(), Some(&era[..]));
|
||||||
assert_eq!(v4.instrs, v3.instrs, "the base program is class v3's, draw for draw");
|
// The AP-F8-1 amendment (7 October 2026): class v4's chain draw takes a load's source only from registers
|
||||||
assert_eq!(v4.attempt, v3.attempt);
|
// whose last writer injects or rotates, so its base program is its own stream (the 6 October stream, equal
|
||||||
|
// to class v3's draw for draw, is sub-version 0 and never stamped); the load slots, the op draws and the era
|
||||||
|
// draw are still class v3's, and every load site obeys the rule
|
||||||
assert_eq!(v4.seed, v3.seed);
|
assert_eq!(v4.seed, v3.seed);
|
||||||
|
assert_eq!(
|
||||||
|
v4.instrs.iter().map(|i| i.op.is_load()).collect::<Vec<_>>(),
|
||||||
|
v3.instrs.iter().map(|i| i.op.is_load()).collect::<Vec<_>>(),
|
||||||
|
"the load slots are class v3's"
|
||||||
|
);
|
||||||
|
let mut kept = [false; 8];
|
||||||
|
for (k, i) in v4.instrs.iter().enumerate() {
|
||||||
|
if i.op.is_load() {
|
||||||
|
assert!(kept[i.src as usize], "load #{k} reads r{} whose last writer does not keep entropy", i.src);
|
||||||
|
}
|
||||||
|
kept[i.dst as usize] = i.op.injects() || matches!(i.op, Op::Rotl | Op::Rotr);
|
||||||
|
}
|
||||||
|
assert_ne!(v4.instrs, v3.instrs, "the amended v4 base program is not class v3's (a lossy-sourced load was redrawn)");
|
||||||
assert!(v3.shadow.is_empty() && !v3.has_shadow());
|
assert!(v3.shadow.is_empty() && !v3.has_shadow());
|
||||||
assert_eq!(v4.shadow.len(), 256);
|
assert_eq!(v4.shadow.len(), 256);
|
||||||
assert_eq!(v4.shadow_reps(), 27);
|
assert_eq!(v4.shadow_reps(), 27);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue