aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/or/circuituse.c23
-rw-r--r--src/feature/hs/hs_cache.c2
-rw-r--r--src/feature/hs/hs_circuit.c1
-rw-r--r--src/feature/hs/hs_client.c130
-rw-r--r--src/feature/hs/hs_client.h2
-rw-r--r--src/feature/hs/hs_pow.c27
-rw-r--r--src/feature/hs/hs_pow.h23
-rw-r--r--src/test/test_hs_client.c2
-rw-r--r--src/test/test_hs_pow_slow.c15
9 files changed, 142 insertions, 83 deletions
diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c
index b78f72e835..ac9005e1d4 100644
--- a/src/core/or/circuituse.c
+++ b/src/core/or/circuituse.c
@@ -564,14 +564,6 @@ circuit_expire_building(void)
continue;
}
- /* Ignore circuits that are waiting for an introduction to a service with
- * PoW enabled, it can take an arbitrary amount of time. They will get
- * cleaned up if the SOCKS connection is closed. */
- if (TO_ORIGIN_CIRCUIT(victim)->hs_with_pow_circ &&
- victim->purpose == CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) {
- continue;
- }
-
build_state = TO_ORIGIN_CIRCUIT(victim)->build_state;
if (build_state && build_state->onehop_tunnel)
cutoff = begindir_cutoff;
@@ -2560,6 +2552,11 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
circ->hs_ident =
hs_ident_circuit_new(&edge_conn->hs_ident->identity_pk);
}
+ if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
+ if (hs_client_setup_intro_circ_auth_key(circ) < 0) {
+ return 0;
+ }
+ }
if (circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND &&
circ->base_.state == CIRCUIT_STATE_OPEN)
circuit_has_opened(circ);
@@ -3012,6 +3009,16 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn)
conn, CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT, &introcirc);
if (retval < 0) return -1; /* failed */
+ if (rendcirc && introcirc) {
+ /* Let's fill out the hs_ident fully as soon as possible, so that
+ * unreachability counts can be updated properly even if circuits close
+ * early. */
+ tor_assert_nonfatal(!ed25519_public_key_is_zero(
+ &introcirc->hs_ident->intro_auth_pk));
+ ed25519_pubkey_copy(&rendcirc->hs_ident->intro_auth_pk,
+ &introcirc->hs_ident->intro_auth_pk);
+ }
+
if (retval > 0) {
/* one has already sent the intro. keep waiting. */
tor_assert(introcirc);
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c
index dcca1d7086..0cc7dfd031 100644
--- a/src/feature/hs/hs_cache.c
+++ b/src/feature/hs/hs_cache.c
@@ -581,6 +581,8 @@ cache_client_intro_state_lookup(const ed25519_public_key_t *service_pk,
tor_assert(service_pk);
tor_assert(auth_key);
+ tor_assert_nonfatal(!ed25519_public_key_is_zero(service_pk));
+ tor_assert_nonfatal(!ed25519_public_key_is_zero(auth_key));
/* Lookup the intro state cache for this service key. */
cache = digest256map_get(hs_cache_client_intro_state, service_pk->pubkey);
diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c
index 92217d760a..d5188b514f 100644
--- a/src/feature/hs/hs_circuit.c
+++ b/src/feature/hs/hs_circuit.c
@@ -251,6 +251,7 @@ create_intro_circuit_identifier(const hs_service_t *service,
ident = hs_ident_circuit_new(&service->keys.identity_pk);
ed25519_pubkey_copy(&ident->intro_auth_pk, &ip->auth_key_kp.pubkey);
+ tor_assert_nonfatal(!ed25519_public_key_is_zero(&ident->intro_auth_pk));
return ident;
}
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index 2a620da953..6303b8fe75 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -549,6 +549,7 @@ find_desc_intro_point_by_ident(const hs_ident_circuit_t *ident,
tor_assert(ident);
tor_assert(desc);
+ tor_assert_nonfatal(!ed25519_public_key_is_zero(&ident->intro_auth_pk));
SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
const hs_desc_intro_point_t *, ip) {
@@ -634,15 +635,8 @@ send_introduce1(origin_circuit_t *intro_circ,
return -1; /* transient failure */
}
- /* Cell has been sent successfully. Copy the introduction point
- * authentication and encryption key in the rendezvous circuit identifier so
- * we can compute the ntor keys when we receive the RENDEZVOUS2 cell. */
- memcpy(&rend_circ->hs_ident->intro_enc_pk, &ip->enc_key,
- sizeof(rend_circ->hs_ident->intro_enc_pk));
- ed25519_pubkey_copy(&rend_circ->hs_ident->intro_auth_pk,
- &intro_circ->hs_ident->intro_auth_pk);
-
- /* Now, we wait for an ACK or NAK on this circuit. */
+ /* Cell has been sent successfully.
+ * Now, we wait for an ACK or NAK on this circuit. */
circuit_change_purpose(TO_CIRCUIT(intro_circ),
CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT);
/* Set timestamp_dirty, because circuit_expire_building expects it to
@@ -657,6 +651,17 @@ send_introduce1(origin_circuit_t *intro_circ,
* tackle. If asked for higher, we solve it at this cap. */
#define CLIENT_MAX_POW_EFFORT 10000
+/** Set a client-side minimum effort. If the client is choosing to increase
+ * effort on retry, it will always pick a value >= this lower limit. */
+#define CLIENT_MIN_RETRY_POW_EFFORT 8
+
+/** Client effort will double on every retry until this level is hit */
+#define CLIENT_POW_EFFORT_DOUBLE_UNTIL 1000
+
+/** After we reach DOUBLE_UNTIL, client effort is multiplied by this amount
+ * on every retry until we reach MAX_POW_EFFORT. */
+#define CLIENT_POW_RETRY_MULTIPLIER (1.5f)
+
/** Send an INTRODUCE1 cell along the intro circuit and populate the rend
* circuit identifier with the needed key material for the e2e encryption.
* Return 0 on success, -1 if there is a transient error such that an action
@@ -731,37 +736,76 @@ consider_sending_introduce1(origin_circuit_t *intro_circ,
goto perm_err;
}
- /* If the descriptor contains PoW parameters then the service is
- * expecting a PoW solution in the INTRODUCE cell, which we solve here. */
- if (have_module_pow() &&
- desc->encrypted_data.pow_params &&
- desc->encrypted_data.pow_params->suggested_effort > 0) {
- log_debug(LD_REND, "PoW params present in descriptor.");
+ /* Copy the introduction point authentication and encryption key
+ * in the rendezvous circuit identifier so we can compute the ntor keys
+ * when we receive the RENDEZVOUS2 cell. */
+ memcpy(&rend_circ->hs_ident->intro_enc_pk, &ip->enc_key,
+ sizeof(rend_circ->hs_ident->intro_enc_pk));
- /* make sure we can't be tricked into hopeless quests */
- if (desc->encrypted_data.pow_params->suggested_effort >
- CLIENT_MAX_POW_EFFORT) {
+ /* Optionally choose to solve a client puzzle for this connection. This
+ * is only available if we have PoW support at compile time, and if the
+ * service has provided a PoW seed in its descriptor. The puzzle is enabled
+ * any time effort is nonzero, which can be recommended by the service or
+ * self-imposed as a result of previous timeouts.
+ */
+ if (have_module_pow() && desc->encrypted_data.pow_params) {
+ hs_pow_solver_inputs_t pow_inputs = {
+ .effort = desc->encrypted_data.pow_params->suggested_effort
+ };
+ memcpy(pow_inputs.seed, desc->encrypted_data.pow_params->seed,
+ sizeof pow_inputs.seed);
+ log_debug(LD_REND, "PoW params present in descriptor, suggested_effort=%u",
+ pow_inputs.effort);
+
+ if (pow_inputs.effort > CLIENT_MAX_POW_EFFORT) {
log_notice(LD_REND, "Onion service suggested effort %d which is "
"higher than we want to solve. Solving at %d instead.",
- desc->encrypted_data.pow_params->suggested_effort,
- CLIENT_MAX_POW_EFFORT);
-
- /* clobber it in-place. hopefully this won't have bad side effects. */
- desc->encrypted_data.pow_params->suggested_effort =
- CLIENT_MAX_POW_EFFORT;
+ pow_inputs.effort, CLIENT_MAX_POW_EFFORT);
+ pow_inputs.effort = CLIENT_MAX_POW_EFFORT;
}
- /* send it to the client-side pow cpuworker for solving. */
- intro_circ->hs_currently_solving_pow = 1;
- if (0 != hs_pow_queue_work(intro_circ->global_identifier,
- rend_circ->global_identifier,
- desc->encrypted_data.pow_params)) {
- log_debug(LD_REND, "Failed to enqueue PoW request");
+ const hs_cache_intro_state_t *state =
+ hs_cache_client_intro_state_find(&intro_circ->hs_ident->identity_pk,
+ &intro_circ->hs_ident->intro_auth_pk);
+ uint32_t unreachable_count = state ? state->unreachable_count : 0;
+ if (state) {
+ log_debug(LD_REND, "hs_cache state during PoW consideration, "
+ "error=%d timed_out=%d unreachable_count=%u",
+ state->error, state->timed_out, state->unreachable_count);
+ }
+ uint64_t new_effort = pow_inputs.effort;
+ for (unsigned n_retry = 0; n_retry < unreachable_count; n_retry++) {
+ if (new_effort >= CLIENT_MAX_POW_EFFORT) {
+ break;
+ }
+ if (new_effort < CLIENT_POW_EFFORT_DOUBLE_UNTIL) {
+ new_effort <<= 1;
+ } else {
+ new_effort = (uint64_t) (CLIENT_POW_RETRY_MULTIPLIER * new_effort);
+ }
+ new_effort = MAX((uint64_t)CLIENT_MIN_RETRY_POW_EFFORT, new_effort);
+ new_effort = MIN((uint64_t)CLIENT_MAX_POW_EFFORT, new_effort);
+ }
+ if (pow_inputs.effort != (uint32_t)new_effort) {
+ log_notice(LD_REND, "Increasing PoW effort from %d to %d after intro "
+ "point unreachable_count=%d",
+ pow_inputs.effort, (int)new_effort, unreachable_count);
+ pow_inputs.effort = (uint32_t)new_effort;
}
- /* can't proceed with the intro1 cell yet, so yield back to the
- * main loop */
- goto tran_err;
+ if (pow_inputs.effort > 0) {
+ /* send it to the client-side pow cpuworker for solving. */
+ intro_circ->hs_currently_solving_pow = 1;
+ if (hs_pow_queue_work(intro_circ->global_identifier,
+ rend_circ->global_identifier,
+ &pow_inputs) != 0) {
+ log_warn(LD_REND, "Failed to enqueue PoW request");
+ }
+
+ /* can't proceed with the intro1 cell yet, so yield back to the
+ * main loop */
+ goto tran_err;
+ }
}
/* move on to the next phase: actually try to send it */
@@ -796,8 +840,8 @@ consider_sending_introduce1(origin_circuit_t *intro_circ,
*
* Return 0 if everything went well, otherwise return -1 in the case of errors.
*/
-static int
-setup_intro_circ_auth_key(origin_circuit_t *circ)
+int
+hs_client_setup_intro_circ_auth_key(origin_circuit_t *circ)
{
const hs_descriptor_t *desc;
const hs_desc_intro_point_t *ip;
@@ -843,13 +887,6 @@ client_intro_circ_has_opened(origin_circuit_t *circ)
log_info(LD_REND, "Introduction circuit %u has opened. Attaching streams.",
(unsigned int) TO_CIRCUIT(circ)->n_circ_id);
- /* This is an introduction circuit so we'll attach the correct
- * authentication key to the circuit identifier so it can be identified
- * properly later on. */
- if (setup_intro_circ_auth_key(circ) < 0) {
- return;
- }
-
connection_ap_attach_pending(1);
}
@@ -2047,6 +2084,7 @@ hs_client_circuit_cleanup_on_free(const circuit_t *circ)
orig_circ = CONST_TO_ORIGIN_CIRCUIT(circ);
tor_assert(orig_circ->hs_ident);
+ const ed25519_public_key_t *intro_pk = &orig_circ->hs_ident->intro_auth_pk;
has_timed_out =
(circ->marked_for_close_orig_reason == END_CIRC_REASON_TIMEOUT);
@@ -2061,22 +2099,22 @@ hs_client_circuit_cleanup_on_free(const circuit_t *circ)
safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)),
failure);
+ tor_assert_nonfatal(!ed25519_public_key_is_zero(intro_pk));
hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
- &orig_circ->hs_ident->intro_auth_pk,
- failure);
+ intro_pk, failure);
break;
case CIRCUIT_PURPOSE_C_INTRODUCING:
if (has_timed_out || !orig_circ->build_state) {
break;
}
+ tor_assert_nonfatal(!ed25519_public_key_is_zero(intro_pk));
failure = INTRO_POINT_FAILURE_UNREACHABLE;
log_info(LD_REND, "Failed v3 intro circ for service %s to intro point %s "
"(while building circuit). Marking as unreachable.",
safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)));
hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
- &orig_circ->hs_ident->intro_auth_pk,
- failure);
+ intro_pk, failure);
break;
default:
break;
diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h
index e87cc00b75..234306a3c3 100644
--- a/src/feature/hs/hs_client.h
+++ b/src/feature/hs/hs_client.h
@@ -119,6 +119,8 @@ int hs_client_any_intro_points_usable(const ed25519_public_key_t *service_pk,
int hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk);
void hs_client_dir_info_changed(void);
+int hs_client_setup_intro_circ_auth_key(origin_circuit_t *circ);
+
int hs_client_send_introduce1(origin_circuit_t *intro_circ,
origin_circuit_t *rend_circ);
diff --git a/src/feature/hs/hs_pow.c b/src/feature/hs/hs_pow.c
index 199c290004..1f6932a55d 100644
--- a/src/feature/hs/hs_pow.c
+++ b/src/feature/hs/hs_pow.c
@@ -177,7 +177,7 @@ unpack_equix_solution(const uint8_t *bytes_in,
* store the solution in pow_solution_out. Returns 0 on success and -1
* otherwise. Called by a client. */
int
-hs_pow_solve(const hs_pow_desc_params_t *pow_params,
+hs_pow_solve(const hs_pow_solver_inputs_t *pow_inputs,
hs_pow_solution_t *pow_solution_out)
{
int ret = -1;
@@ -185,17 +185,15 @@ hs_pow_solve(const hs_pow_desc_params_t *pow_params,
uint8_t *challenge = NULL;
equix_ctx *ctx = NULL;
- tor_assert(pow_params);
+ tor_assert(pow_inputs);
tor_assert(pow_solution_out);
-
- /* Select E (just using suggested for now) */
- uint32_t effort = pow_params->suggested_effort;
+ const uint32_t effort = pow_inputs->effort;
/* Generate a random nonce N. */
crypto_rand((char *)nonce, sizeof nonce);
/* Build EquiX challenge (C || N || INT_32(E)). */
- challenge = build_equix_challenge(pow_params->seed, nonce, effort);
+ challenge = build_equix_challenge(pow_inputs->seed, nonce, effort);
ctx = build_equix_ctx(EQUIX_CTX_SOLVE);
if (!ctx) {
@@ -218,7 +216,7 @@ hs_pow_solve(const hs_pow_desc_params_t *pow_params,
/* Store the effort E. */
pow_solution_out->effort = effort;
/* We only store the first 4 bytes of the seed C. */
- memcpy(pow_solution_out->seed_head, pow_params->seed,
+ memcpy(pow_solution_out->seed_head, pow_inputs->seed,
sizeof(pow_solution_out->seed_head));
/* Store the solution S */
memcpy(&pow_solution_out->equix_solution, sol_bytes, sizeof sol_bytes);
@@ -353,8 +351,8 @@ hs_pow_free_service_state(hs_pow_service_state_t *state)
*/
typedef struct pow_worker_job_t {
- /** Input: The pow challenge we need to solve. */
- hs_pow_desc_params_t *pow_params;
+ /** Inputs for the PoW solver (seed, chosen effort) */
+ hs_pow_solver_inputs_t pow_inputs;
/** State: we'll look these up to figure out how to proceed after. */
uint32_t intro_circ_identifier;
@@ -377,15 +375,15 @@ pow_worker_threadfn(void *state_, void *work_)
pow_worker_job_t *job = work_;
job->pow_solution_out = tor_malloc_zero(sizeof(hs_pow_solution_t));
- if (hs_pow_solve(job->pow_params, job->pow_solution_out)) {
- log_info(LD_REND, "Haven't solved the PoW yet. Returning.");
+ if (hs_pow_solve(&job->pow_inputs, job->pow_solution_out)) {
+ log_warn(LD_REND, "Failed to run the proof of work solver");
tor_free(job->pow_solution_out);
job->pow_solution_out = NULL; /* how we signal that we came up empty */
return WQ_RPL_REPLY;
}
/* we have a winner! */
- log_info(LD_REND, "cpuworker pow: we have a winner!");
+ log_info(LD_REND, "cpuworker has a proof of work solution");
return WQ_RPL_REPLY;
}
@@ -397,7 +395,6 @@ pow_worker_job_free(pow_worker_job_t *job)
{
if (!job)
return;
- tor_free(job->pow_params);
tor_free(job->pow_solution_out);
tor_free(job);
}
@@ -470,14 +467,14 @@ pow_worker_replyfn(void *work_)
int
hs_pow_queue_work(uint32_t intro_circ_identifier,
uint32_t rend_circ_identifier,
- const hs_pow_desc_params_t *pow_params)
+ const hs_pow_solver_inputs_t *pow_inputs)
{
tor_assert(in_main_thread());
pow_worker_job_t *job = tor_malloc_zero(sizeof(*job));
job->intro_circ_identifier = intro_circ_identifier;
job->rend_circ_identifier = rend_circ_identifier;
- job->pow_params = tor_memdup(pow_params, sizeof(hs_pow_desc_params_t));
+ memcpy(&job->pow_inputs, pow_inputs, sizeof job->pow_inputs);
workqueue_entry_t *work;
work = cpuworker_queue_work(WQ_PRI_LOW,
diff --git a/src/feature/hs/hs_pow.h b/src/feature/hs/hs_pow.h
index fe78a48d9a..6e3611be69 100644
--- a/src/feature/hs/hs_pow.h
+++ b/src/feature/hs/hs_pow.h
@@ -56,6 +56,17 @@ typedef struct hs_pow_desc_params_t {
time_t expiration_time;
} hs_pow_desc_params_t;
+/** The inputs to the PoW solver, derived from the descriptor data and the
+ * client's per-connection effort choices. */
+typedef struct hs_pow_solver_inputs_t {
+ /** Seed value from a current descriptor */
+ uint8_t seed[HS_POW_SEED_LEN];
+
+ /** Effort chosen by the client. May be higher or ower than
+ * suggested_effort in the descriptor. */
+ uint32_t effort;
+} hs_pow_solver_inputs_t;
+
/** State and parameters of PoW defenses, stored in the service state. */
typedef struct hs_pow_service_state_t {
/* If PoW defenses are enabled this is a priority queue containing acceptable
@@ -124,7 +135,7 @@ typedef struct hs_pow_solution_t {
#define have_module_pow() (1)
/* API */
-int hs_pow_solve(const hs_pow_desc_params_t *pow_params,
+int hs_pow_solve(const hs_pow_solver_inputs_t *pow_inputs,
hs_pow_solution_t *pow_solution_out);
int hs_pow_verify(const hs_pow_service_state_t *pow_state,
@@ -135,16 +146,16 @@ void hs_pow_free_service_state(hs_pow_service_state_t *state);
int hs_pow_queue_work(uint32_t intro_circ_identifier,
uint32_t rend_circ_identifier,
- const hs_pow_desc_params_t *pow_params);
+ const hs_pow_solver_inputs_t *pow_inputs);
#else /* !defined(HAVE_MODULE_POW) */
#define have_module_pow() (0)
static inline int
-hs_pow_solve(const hs_pow_desc_params_t *pow_params,
+hs_pow_solve(const hs_pow_solver_inputs_t *pow_inputs,
hs_pow_solution_t *pow_solution_out)
{
- (void)pow_params;
+ (void)pow_inputs;
(void)pow_solution_out;
return -1;
}
@@ -173,11 +184,11 @@ hs_pow_free_service_state(hs_pow_service_state_t *state)
static inline int
hs_pow_queue_work(uint32_t intro_circ_identifier,
uint32_t rend_circ_identifier,
- const hs_pow_desc_params_t *pow_params)
+ const hs_pow_solver_inputs_t *pow_inputs)
{
(void)intro_circ_identifier;
(void)rend_circ_identifier;
- (void)pow_params;
+ (void)pow_inputs;
return -1;
}
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index 11a5589d21..f873d90212 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -177,6 +177,7 @@ helper_get_circ_and_stream_for_test(origin_circuit_t **circ_out,
/* prop224: Setup hs ident on the circuit */
or_circ->hs_ident = hs_ident_circuit_new(&service_pk);
+ or_circ->hs_ident->intro_auth_pk.pubkey[0] = 42;
TO_CIRCUIT(or_circ)->state = CIRCUIT_STATE_OPEN;
@@ -1186,6 +1187,7 @@ test_socks_hs_errors(void *arg)
circ->purpose = CIRCUIT_PURPOSE_C_REND_READY;
ocirc = TO_ORIGIN_CIRCUIT(circ);
ocirc->hs_ident = hs_ident_circuit_new(&service_kp.pubkey);
+ ocirc->hs_ident->intro_auth_pk.pubkey[0] = 42;
ocirc->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
/* Code path will log this exit so build it. */
ocirc->build_state->chosen_exit = extend_info_new("TestNickname", digest,
diff --git a/src/test/test_hs_pow_slow.c b/src/test/test_hs_pow_slow.c
index fdade2d3fa..e7d1311cee 100644
--- a/src/test/test_hs_pow_slow.c
+++ b/src/test/test_hs_pow_slow.c
@@ -187,17 +187,16 @@ test_hs_pow_vectors(void *arg)
uint8_t rng_bytes[HS_POW_NONCE_LEN];
hs_pow_solution_t output;
hs_pow_solution_t solution = { 0 };
- hs_pow_desc_params_t params = {
- .type = HS_POW_DESC_V1,
- .suggested_effort = vectors[vec_i].effort,
+ hs_pow_solver_inputs_t input = {
+ .effort = vectors[vec_i].effort,
};
- tt_int_op(strlen(seed_hex), OP_EQ, 2 * sizeof params.seed);
+ tt_int_op(strlen(seed_hex), OP_EQ, 2 * sizeof input.seed);
tt_int_op(strlen(solve_rng_hex), OP_EQ, 2 * sizeof rng_bytes);
tt_int_op(strlen(nonce_hex), OP_EQ, 2 * sizeof solution.nonce);
tt_int_op(strlen(sol_hex), OP_EQ, 2 * sizeof solution.equix_solution);
- tt_int_op(base16_decode((char*)params.seed, HS_POW_SEED_LEN,
+ tt_int_op(base16_decode((char*)input.seed, HS_POW_SEED_LEN,
seed_hex, 2 * HS_POW_SEED_LEN),
OP_EQ, HS_POW_SEED_LEN);
tt_int_op(base16_decode((char*)rng_bytes, sizeof rng_bytes,
@@ -210,11 +209,11 @@ test_hs_pow_vectors(void *arg)
sizeof solution.equix_solution,
sol_hex, 2 * sizeof solution.equix_solution),
OP_EQ, HS_POW_EQX_SOL_LEN);
- memcpy(solution.seed_head, params.seed, HS_POW_SEED_HEAD_LEN);
+ memcpy(solution.seed_head, input.seed, HS_POW_SEED_HEAD_LEN);
memset(&output, 0xaa, sizeof output);
testing_enable_prefilled_rng(rng_bytes, HS_POW_NONCE_LEN);
- tt_int_op(0, OP_EQ, hs_pow_solve(&params, &output));
+ tt_int_op(0, OP_EQ, hs_pow_solve(&input, &output));
testing_disable_prefilled_rng();
tt_mem_op(solution.seed_head, OP_EQ, output.seed_head,
@@ -224,7 +223,7 @@ test_hs_pow_vectors(void *arg)
tt_mem_op(&solution.equix_solution, OP_EQ, &output.equix_solution,
sizeof output.equix_solution);
- tt_int_op(testing_one_hs_pow_solution(&output, params.seed), OP_EQ, 0);
+ tt_int_op(testing_one_hs_pow_solution(&output, input.seed), OP_EQ, 0);
}
done: