From f84af7c360adc4f82cde1d30ede00273177ab543 Mon Sep 17 00:00:00 2001 From: Micah Elizabeth Scott Date: Tue, 1 Aug 2023 10:46:25 -0700 Subject: [PATCH 1/2] tor-hspow: Split up hspow_vectors tests This test had one large function for all the verifies and one for all the solves. The solve test was slow enough to be a bottleneck, documented in ticket #991. This patch splits the existing tests up in to one labeled function per solve or verify configuration. Signed-off-by: Micah Elizabeth Scott --- crates/tor-hspow/tests/hspow_vectors.rs | 114 ++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 8 deletions(-) diff --git a/crates/tor-hspow/tests/hspow_vectors.rs b/crates/tor-hspow/tests/hspow_vectors.rs index c73e37929..604c0a419 100644 --- a/crates/tor-hspow/tests/hspow_vectors.rs +++ b/crates/tor-hspow/tests/hspow_vectors.rs @@ -1,13 +1,19 @@ //! Test vectors from the C tor implementation +//! +//! Includes short-running 'verify' tests and longer-running 'solve' tests, +//! with vectors from C tor. +//! +//! The solve tests are still optimized to complete without wasting too much +//! time, by artificially choosing a `first_nonce` only slightly lower than the +//! `expected_nonce` we want to find. use hex_literal::hex; use tor_hscrypto::pk::HsBlindId; use tor_hspow::v1::{Effort, Instance, Nonce, Seed, Solution, SolutionByteArray, SolutionError}; use tor_hspow::Error; -/// Short test vectors from C tor, covering verification only #[test] -fn verify_only() { +fn verify_seed0_effort1_hash_err() { // All zero, but only claims an effort of 1. // Expect it will last until hash sum checks before failing. assert!(matches!( @@ -29,7 +35,10 @@ fn verify_only() { SolutionError::HashSum ))) )); +} +#[test] +fn verify_seed0_effort10_effort_err() { // All zero, but a higher effort claim. Should fail the effort check. assert!(matches!( Instance::new( @@ -50,7 +59,10 @@ fn verify_only() { SolutionError::Effort ))) )); +} +#[test] +fn verify_seed0_effort0_seed_err() { // Seed head mismatch assert!(matches!( Instance::new( @@ -71,7 +83,10 @@ fn verify_only() { SolutionError::Seed ))) )); +} +#[test] +fn verify_effort0_ok() { // Valid zero-effort solution assert!(Instance::new( hex!("1111111111111111111111111111111111111111111111111111111111111111").into(), @@ -88,7 +103,10 @@ fn verify_only() { .unwrap() ) .is_ok()); +} +#[test] +fn verify_effort1m_ok() { // Valid high-effort solution assert!(Instance::new( hex!("1111111111111111111111111111111111111111111111111111111111111111").into(), @@ -105,7 +123,10 @@ fn verify_only() { .unwrap() ) .is_ok()); +} +#[test] +fn verify_effort100k_effort_err() { // The claimed effort must exactly match what's was in the challenge // when the Equi-X proof was created, or it will fail either the // Effort or HashSum checks. @@ -128,7 +149,10 @@ fn verify_only() { SolutionError::Effort ))) )); +} +#[test] +fn verify_seed86_effort100k_effort_err() { // Otherwise good solution but with a corrupted nonce. This may fail // either the Effort or HashSum checks. assert!(matches!( @@ -150,7 +174,10 @@ fn verify_only() { SolutionError::Effort ))) )); +} +#[test] +fn verify_seed86_effort100k_ok() { assert!(Instance::new( hex!("bfd298428562e530c52bdb36d81a0e293ef4a0e94d787f0f8c0c611f4f9e78ed").into(), hex!("86fb0acf4932cda44dbb451282f415479462dd10cb97ff5e7e8e2a53c3767a7f").into() @@ -198,13 +225,8 @@ fn solve_and_verify( assert!(instance.verifier().check(&solution).is_ok()); } -/// Longer running tests from C tor, covering solve and verify both -/// -/// These tests are still optimized to complete without wasting too much time, -/// by artificially choosing a `first_nonce` only slightly lower than the -/// `expected_nonce` we want to find. #[test] -fn solver() { +fn solve_effort0_aa_11_55() { solve_and_verify( 0_u32.into(), hex!("55555555555555555555555555555555").into(), @@ -213,6 +235,10 @@ fn solver() { hex!("55555555555555555555555555555555").into(), hex!("4312f87ceab844c78e1c793a913812d7"), ); +} + +#[test] +fn solve_effort1_aa_11_55() { solve_and_verify( 1_u32.into(), hex!("55555555555555555555555555555555").into(), @@ -221,6 +247,10 @@ fn solver() { hex!("55555555555555555555555555555555").into(), hex!("84355542ab2b3f79532ef055144ac5ab"), ); +} + +#[test] +fn solve_effort1_aa_10_55() { solve_and_verify( 1_u32.into(), hex!("55555555555555555555555555555555").into(), @@ -229,6 +259,10 @@ fn solver() { hex!("55555555555555555555555555555555").into(), hex!("115e4b70da858792fc205030b8c83af9"), ); +} + +#[test] +fn solve_effort2_aa_11_55() { solve_and_verify( 2_u32.into(), hex!("55555555555555555555555555555555").into(), @@ -237,6 +271,10 @@ fn solver() { hex!("55555555555555555555555555555555").into(), hex!("4600a93a535ed76dc746c99942ab7de2"), ); +} + +#[test] +fn solve_effort10_aa_11_56() { solve_and_verify( 10_u32.into(), hex!("55555555555555555555555555555555").into(), @@ -245,6 +283,10 @@ fn solver() { hex!("56555555555555555555555555555555").into(), hex!("128bbda5df2929c3be086de2aad34aed"), ); +} + +#[test] +fn solve_effort10_aa_11_01() { solve_and_verify( 10_u32.into(), hex!("ffffffffffffffffffffffffffffffff").into(), @@ -253,6 +295,10 @@ fn solver() { hex!("01000000000000000000000000000000").into(), hex!("203af985537fadb23f3ed5873b4c81ce"), ); +} + +#[test] +fn solve_effort1k_aa_41_01() { solve_and_verify( 1337_u32.into(), hex!("7fffffffffffffffffffffffffffffff").into(), @@ -261,6 +307,10 @@ fn solver() { hex!("01000000000000000000000000000000").into(), hex!("31c377cb72796ed80ae77df6ac1d6bfd"), ); +} + +#[test] +fn solve_effort30k_aa_11_36() { solve_and_verify( 31337_u32.into(), hex!("34a20000000000000000000000000000").into(), @@ -269,6 +319,10 @@ fn solver() { hex!("36a20000000000000000000000000000").into(), hex!("ca6899b91113aaf7536f28db42526bff"), ); +} + +#[test] +fn solve_effort100_aa_11_56() { solve_and_verify( 100_u32.into(), hex!("55555555555555555555555555555555").into(), @@ -277,6 +331,10 @@ fn solver() { hex!("56555555555555555555555555555555").into(), hex!("3a4122a240bd7abfc922ab3cbb9479ed"), ); +} + +#[test] +fn solve_effort1k_aa_11_d4() { solve_and_verify( 1000_u32.into(), hex!("d3555555555555555555555555555555").into(), @@ -285,6 +343,10 @@ fn solver() { hex!("d4555555555555555555555555555555").into(), hex!("338cc08f57697ce8ac2e4b453057d6e9"), ); +} + +#[test] +fn solve_effort10k_aa_11_c8() { solve_and_verify( 10_000_u32.into(), hex!("c5715555555555555555555555555555").into(), @@ -293,6 +355,10 @@ fn solver() { hex!("c8715555555555555555555555555555").into(), hex!("9f2d3d4ed831ac96ad34c25fb59ff3e2"), ); +} + +#[test] +fn solve_effort100k_aa_11_42() { solve_and_verify( 100_000_u32.into(), hex!("418d5655555555555555555555555555").into(), @@ -301,6 +367,10 @@ fn solver() { hex!("428d5655555555555555555555555555").into(), hex!("9863f3acd2d15adfd244a7ca61d4c6ff"), ); +} + +#[test] +fn solve_effort1m_aa_11_59() { solve_and_verify( 1_000_000_u32.into(), hex!("58217255555555555555555555555555").into(), @@ -309,6 +379,10 @@ fn solver() { hex!("59217255555555555555555555555555").into(), hex!("0f3db97b9cac20c1771680a1a34848d3"), ); +} + +#[test] +fn solve_effort1_c5_bf_d1() { solve_and_verify( 1_u32.into(), hex!("d0aec1669384bfe5ed39cd724d6c7954").into(), @@ -317,6 +391,10 @@ fn solver() { hex!("d1aec1669384bfe5ed39cd724d6c7954").into(), hex!("462606e5f8c2f3f844127b8bfdd6b4ff"), ); +} + +#[test] +fn solve_effort1_86_bf_b4() { solve_and_verify( 1_u32.into(), hex!("b4d0e611e6935750fcf9406aae131f62").into(), @@ -325,6 +403,10 @@ fn solver() { hex!("b4d0e611e6935750fcf9406aae131f62").into(), hex!("9f3fbd50b1a83fb63284bde44318c0fd"), ); +} + +#[test] +fn solve_effort1_9d_be_b4() { solve_and_verify( 1_u32.into(), hex!("b4d0e611e6935750fcf9406aae131f62").into(), @@ -333,6 +415,10 @@ fn solver() { hex!("b4d0e611e6935750fcf9406aae131f62").into(), hex!("161baa7490356292d020065fdbe55ffc"), ); +} + +#[test] +fn solve_effort1_86_bf_40() { solve_and_verify( 1_u32.into(), hex!("40559fdbc34326d9d2f18ed277469c63").into(), @@ -341,6 +427,10 @@ fn solver() { hex!("40559fdbc34326d9d2f18ed277469c63").into(), hex!("fa649c6a2c5c0bb6a3511b9ea4b448d1"), ); +} + +#[test] +fn solve_effort10k_86_bf_36() { solve_and_verify( 10_000_u32.into(), hex!("34569fdbc34326d9d2f18ed277469c63").into(), @@ -349,6 +439,10 @@ fn solver() { hex!("36569fdbc34326d9d2f18ed277469c63").into(), hex!("2802951e623c74adc443ab93e99633ee"), ); +} + +#[test] +fn solve_effort100k_86_bf_2e() { solve_and_verify( 100_000_u32.into(), hex!("2cff9fdbc34326d9d2f18ed277469c63").into(), @@ -357,6 +451,10 @@ fn solver() { hex!("2eff9fdbc34326d9d2f18ed277469c63").into(), hex!("400cb091139f86b352119f6e131802d6"), ); +} + +#[test] +fn solve_effort1m_86_bf_55() { solve_and_verify( 1_000_000_u32.into(), hex!("5243b3dbc34326d9d2f18ed277469c63").into(), From f40255cb953e6f104d5c0e4db902d33c41196043 Mon Sep 17 00:00:00 2001 From: Micah Elizabeth Scott Date: Tue, 1 Aug 2023 10:52:40 -0700 Subject: [PATCH 2/2] tor-hspow: Shorten the solve_effort1k_aa_41_01 test The solve tests are all tunable so that we can balance execution time with test coverage. A longer solve will test more random programs and it will test more of the nonce increment function, minor benefits at the cost of much more CPU. The starting nonce in solve_effort1k_aa_41_01 was set so that we would exercise a rollover in bit 7 of the nonce increment before the full width rollover, but this wasn't a particularly helpful place to test and certainly not worth the 13+ seconds it takes on my machine. This patch bumps the starting nonce to a value much closer to the target, and still including the full-width rollover. Brings solve_effort1k_aa_41_01 down from 13.2 seconds to 0.5 sec for me. For ticket #991 Signed-off-by: Micah Elizabeth Scott --- crates/tor-hspow/tests/hspow_vectors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tor-hspow/tests/hspow_vectors.rs b/crates/tor-hspow/tests/hspow_vectors.rs index 604c0a419..275c10e08 100644 --- a/crates/tor-hspow/tests/hspow_vectors.rs +++ b/crates/tor-hspow/tests/hspow_vectors.rs @@ -301,7 +301,7 @@ fn solve_effort10_aa_11_01() { fn solve_effort1k_aa_41_01() { solve_and_verify( 1337_u32.into(), - hex!("7fffffffffffffffffffffffffffffff").into(), + hex!("feffffffffffffffffffffffffffffff").into(), hex!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").into(), hex!("4111111111111111111111111111111111111111111111111111111111111111").into(), hex!("01000000000000000000000000000000").into(),