#define USE_AES_RAW
#include "orconfig.h"
+#include "core/or/or.h"
#include "lib/crypt_ops/aes.h"
#include "ext/polyval/polyval.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/arch/bytes.h"
#include "ext/polyval/polyval.h"
#include "core/crypto/relay_crypto_cgo.h"
+#include "core/or/cell_st.h"
#if 0
// XXXX debugging.
#include <string.h>
+static int
+cgo_et_keylen(int aesbits)
+{
+ return (aesbits / 8) + POLYVAL_KEY_LEN;
+}
/** Initialize an instance of the tweakable block cipher,
* using an 'aesbits'-bit AES key.
/** Helper: Compute polyval(KU, H | CMD | X_R). */
static inline void
-compute_et_mask(polyval_key_t *pvk, const et_tweak_t tweak, uint8_t *t_out) {
+compute_et_mask(polyval_key_t *pvk, const et_tweak_t tweak, uint8_t *t_out)
+{
// block 0: tweak.h
// block 1: one byte of command, first 15 bytes of x_r
// block 2...: remainder of x_r, zero-padded.
aes_raw_free(et->kb);
}
+static int
+cgo_prf_keylen(int aesbits)
+{
+ return (aesbits / 8) + POLYVAL_KEY_LEN;
+}
+
/**
* Initialize a psedorandom function from a given key.
* Uses an internal 'aesbits'-bit AES key.
aes_raw_free(prf->k);
}
+static int
+cgo_uiv_keylen(int aesbits)
+{
+ return cgo_et_keylen(aesbits) + cgo_prf_keylen(aesbits);
+}
+
/**
* Initialize the 'uiv' wide-block cipher, using 'aesbits'-bit
* AES keys internally.
cgo_prf_clear(&uiv->s);
}
-// XXXX temporarily suppress unused-function warnings
-void temporary(void);
-void temporary(void)
+/* ====================
+ * High level counter galois onion implementations.
+ */
+
+/**
+ * Return the total number of bytes needed to initialize a cgo_crypt_t.
+ */
+size_t
+cgo_key_material_len(int aesbits)
+{
+ tor_assert(aesbits == 128 || aesbits == 192 || aesbits == 256);
+ return (cgo_uiv_keylen(aesbits) + CGO_TAG_LEN);
+}
+
+/**
+ * Instantiate a CGO authenticated encryption object from the provided
+ * 'keylen' bytes in 'keys'.
+ *
+ * 'keylen' must equal 'cgo_key_material_len(aesbits)'.
+ *
+ * The client and relay must have two cgo_crypt_t objects each:
+ * one for the forward direction, and one for the reverse direction.
+ */
+cgo_crypt_t *
+cgo_crypt_new(cgo_mode_t mode, int aesbits, const uint8_t *keys, size_t keylen)
+{
+ tor_assert(keylen == cgo_key_material_len(aesbits));
+ const uint8_t *end_of_keys = keys + keylen;
+ // Relays encrypt; clients decrypt.
+ // Don't reverse this: UIV+ is only non-malleable for _encryption_.
+ bool encrypt = (mode == CGO_MODE_RELAY);
+ int r;
+
+ cgo_crypt_t *cgo = tor_malloc_zero(sizeof(cgo_crypt_t));
+ r = cgo_uiv_init(&cgo->uiv, aesbits, encrypt, keys);
+ tor_assert(r == 0);
+ keys += cgo_uiv_keylen(aesbits);
+ memcpy(cgo->nonce, keys, CGO_TAG_LEN);
+ keys += CGO_TAG_LEN;
+ tor_assert(keys == end_of_keys);
+
+ cgo->aes_bytes = aesbits / 8;
+
+ return cgo;
+}
+/**
+ * Clean up 'cgo' and free it.
+ */
+void
+cgo_crypt_free_(cgo_crypt_t *cgo)
+{
+ if (!cgo)
+ return;
+ cgo_uiv_clear(&cgo->uiv);
+ memwipe(cgo, 0, sizeof(cgo_crypt_t));
+ tor_free(cgo);
+}
+
+/**
+ * Internal: Run the UIV Update operation on our UIV+ instance.
+ */
+static void
+cgo_crypt_update(cgo_crypt_t *cgo, cgo_mode_t mode)
+{
+ bool encrypt = (mode == CGO_MODE_RELAY);
+ cgo_uiv_update(&cgo->uiv, cgo->aes_bytes * 8, encrypt, cgo->nonce);
+}
+
+/**
+ * Forward CGO encryption operation at a relay:
+ * process an outbound cell from the client.
+ *
+ * If the cell is for this relay, set *'recognized_tag_out'
+ * to point to a CGO_TAG_LEN value that should be used
+ * if we want to acknowledge this cell with an authenticated SENDME.
+ *
+ * The value of 'recognized_tag_out' will become invalid
+ * as soon as any change is made to this 'cgo' object,
+ * or to the cell; if you need it, you should copy it immediately.
+ *
+ * If the cell is not for this relay, set *'recognized_tag_out' to NULL.
+ */
+void
+cgo_crypt_relay_forward(cgo_crypt_t *cgo, cell_t *cell,
+ const uint8_t **recognized_tag_out)
{
- (void)cgo_et_init;
- (void)cgo_et_encrypt;
- (void)cgo_et_decrypt;
- (void)cgo_et_clear;
-
- (void)cgo_prf_init;
- (void)cgo_prf_xor_t0;
- (void)cgo_prf_gen_t1;
- (void)cgo_prf_clear;
-
- (void)cgo_uiv_init;
- (void)cgo_uiv_encrypt;
- (void)cgo_uiv_decrypt;
- (void)cgo_uiv_update;
- (void)cgo_uiv_clear;
+ uiv_tweak_t h = {
+ .h = cgo->tprime,
+ .cmd = cell->command,
+ };
+ cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
+ memcpy(cgo->tprime, cell->payload, CGO_TAG_LEN);
+ if (tor_memeq(cell->payload, cgo->nonce, CGO_TAG_LEN)) {
+ cgo_crypt_update(cgo, CGO_MODE_RELAY);
+ // XXXX: Here and in Arti, we've used tprime as the value
+ // of our tag, but the proposal says to use T. We should
+ // fix that, unless the CGO implementors say it's better!
+ *recognized_tag_out = cgo->tprime;
+ } else {
+ *recognized_tag_out = NULL;
+ }
+}
+
+/**
+ * Backward CGO encryption operation at a relay:
+ * process an inbound cell from another relay, for the client.
+ */
+void
+cgo_crypt_relay_backward(cgo_crypt_t *cgo, cell_t *cell)
+{
+ uiv_tweak_t h = {
+ .h = cgo->tprime,
+ .cmd = cell->command,
+ };
+ cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
+ memcpy(cgo->tprime, cell->payload, CGO_TAG_LEN);
+}
+
+/**
+ * Backward CGO encryption operation at a relay:
+ * encrypt an inbound message that we are originating, for the client.
+ *
+ * The provided cell must have its command value set,
+ * and should have the first CGO_TAG_LEN bytes of its payload unused.
+ *
+ * Set '*tag_out' to a value that we should expect
+ * if we want an authenticated SENDME for this cell.
+ *
+ * The value of 'recognized_tag_out' will become invalid
+ * as soon as any change is made to this 'cgo' object,
+ * or to the cell; if you need it, you should copy it immediately.
+ */
+void
+cgo_crypt_relay_originate(cgo_crypt_t *cgo, cell_t *cell,
+ const uint8_t **tag_out)
+{
+ uiv_tweak_t h = {
+ .h = cgo->tprime,
+ .cmd = cell->command,
+ };
+ memcpy(cell->payload, cgo->nonce, CGO_TAG_LEN);
+ cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
+ memcpy(&cgo->tprime, cell->payload, CGO_TAG_LEN);
+ memcpy(&cgo->nonce, cell->payload, CGO_TAG_LEN);
+ if (tag_out) {
+ // XXXX: Here and elsewhere, we've used tprime as the value
+ // of our tag, but the proposal says to use T. We should
+ // fix that, unless the CGO implementors say it's better!
+ *tag_out = cgo->tprime;
+ }
+ cgo_crypt_update(cgo, CGO_MODE_RELAY);
+}
+
+/**
+ * Forward CGO encryption at a client:
+ * process a cell for a non-destination hop.
+ **/
+void
+cgo_crypt_client_forward(cgo_crypt_t *cgo, cell_t *cell)
+{
+ uint8_t tprime_new[CGO_TAG_LEN];
+ memcpy(tprime_new, cell->payload, CGO_TAG_LEN);
+ uiv_tweak_t h = {
+ .h = cgo->tprime,
+ .cmd = cell->command,
+ };
+ cgo_uiv_decrypt(&cgo->uiv, h, cell->payload);
+ memcpy(cgo->tprime, tprime_new, CGO_TAG_LEN);
+}
+
+/**
+ * Forward CGO encryption at a client:
+ * originate a cell for a given target hop.
+ *
+ * The provided cell must have its command value set,
+ * and should have the first CGO_TAG_LEN bytes of its payload unused.
+ *
+ * Set '*tag_out' to a value that we should expect
+ * if we want an authenticated SENDME for this cell.
+ *
+ * The value of 'recognized_tag_out' will become invalid
+ * as soon as any change is made to this 'cgo' object,
+ * or to the cell; if you need it, you should copy it immediately.
+ */
+void
+cgo_crypt_client_originate(cgo_crypt_t *cgo, cell_t *cell,
+ const uint8_t **tag_out)
+{
+ memcpy(cell->payload, cgo->nonce, CGO_TAG_LEN);
+ cgo_crypt_client_forward(cgo, cell);
+ cgo_crypt_update(cgo, CGO_MODE_CLIENT);
+ // XXXX: Here and elsewhere, we've used tprime as the value
+ // of our tag, but the proposal says to use T. We should
+ // fix that, unless the CGO implementors say it's better!
+ *tag_out = cgo->tprime;
+}
+
+/**
+ * Backward CGO encryption operation at a rclient.
+ * process an inbound cell from a relay.
+ *
+ * If the cell originated from this this relay, set *'recognized_tag_out'
+ * to point to a CGO_TAG_LEN value that should be used
+ * if we want to acknowledge this cell with an authenticated SENDME.
+ *
+ * The value of 'recognized_tag_out' will become invalid
+ * as soon as any change is made to this 'cgo' object,
+ * or to the cell; if you need it, you should copy it immediately.
+ *
+ * If the cell is not from this relay, set *'recognized_tag_out' to NULL.
+ */
+void
+cgo_crypt_client_backward(cgo_crypt_t *cgo, cell_t *cell,
+ const uint8_t **recognized_tag_out)
+{
+ uiv_tweak_t h = {
+ .h = cgo->tprime,
+ .cmd = cell->command,
+ };
+ uint8_t t_orig[CGO_TAG_LEN];
+ memcpy(t_orig, cell->payload, CGO_TAG_LEN);
+
+ cgo_uiv_decrypt(&cgo->uiv, h, cell->payload);
+ memcpy(cgo->tprime, t_orig, CGO_TAG_LEN);
+ if (tor_memeq(cell->payload, cgo->nonce, CGO_TAG_LEN)) {
+ memcpy(cgo->nonce, t_orig, CGO_TAG_LEN);
+ cgo_crypt_update(cgo, CGO_MODE_CLIENT);
+ // XXXX: Here and elsewhere, we've used tprime as the value
+ // of our tag, but the proposal says to use T. We should
+ // fix that, unless the CGO implementors say it's better!
+ *recognized_tag_out = cgo->tprime;
+ } else {
+ *recognized_tag_out = NULL;
+ }
}
#include "lib/testsupport/testsupport.h"
+/**
+ * State to implement forward _or_ reverse crypto between a client and a single
+ * hop on a circuit.
+ *
+ * (There needs to be one of these for each direction.
+ */
+typedef struct cgo_crypt_t cgo_crypt_t;
+
+typedef enum {
+ CGO_MODE_CLIENT,
+ CGO_MODE_RELAY,
+} cgo_mode_t;
+
+/**
+ * Length of a CGO cell tag.
+ *
+ * This is the value used for authenticated SENDMES.
+ **/
+#define CGO_TAG_LEN 16
+
+struct cell_t;
+
+size_t cgo_key_material_len(int aesbits);
+cgo_crypt_t * cgo_crypt_new(cgo_mode_t mode, int aesbits,
+ const uint8_t *keys, size_t keylen);
+void cgo_crypt_free_(cgo_crypt_t *cgo);
+#define cgo_crypt_free(cgo) \
+ FREE_AND_NULL(cgo_crypt_t, cgo_crypt_free_, (cgo))
+
+void cgo_crypt_relay_forward(cgo_crypt_t *cgo, struct cell_t *cell,
+ const uint8_t **recognized_tag_out);
+void cgo_crypt_relay_backward(cgo_crypt_t *cgo, struct cell_t *cell);
+void cgo_crypt_relay_originate(cgo_crypt_t *cgo, struct cell_t *cell,
+ const uint8_t **tag_out);
+void cgo_crypt_client_forward(cgo_crypt_t *cgo, struct cell_t *cell);
+void cgo_crypt_client_originate(cgo_crypt_t *cgo, struct cell_t *cell,
+ const uint8_t **tag_out);
+void cgo_crypt_client_backward(cgo_crypt_t *cgo, struct cell_t *cell,
+ const uint8_t **recognized_tag_out);
+
#ifdef RELAY_CRYPTO_CGO_PRIVATE
/* Internal types and definitions for CGO encryption algorithms.
*
const uint8_t *x_r;
} et_tweak_t;
-
/** Length of expected input to the PRF. */
#define PRF_INPUT_LEN 16
/** Output length for cgo_prf_xor_t0(). */
uint8_t *nonce);
STATIC void cgo_uiv_clear(cgo_uiv_t *uiv);
+struct cgo_crypt_t {
+ cgo_uiv_t uiv;
+ uint8_t nonce[CGO_TAG_LEN];
+ uint8_t tprime[CGO_TAG_LEN];
+ uint8_t aes_bytes;
+};
#endif
#endif /* !defined(TOR_RELAY_CRYPTO_CGO_H) */
{"7c7a284801c7aa0f727f8e24b87a2dca1b7550577924490291a7343924dfd1b9e2b86e4f7db39b77715888f7d3b9aa4ea44bd72a8b1eb79df0d46f25c130fc87", "3c8ecadfbe9ee9587332a6568c7f2476"},
},
};
+
+typedef struct cgo_tv_state_t {
+ const char *keys;
+ const char *nonce;
+ const char *tprime;
+} cgo_tv_state_t;
+
+static const struct cgo_relay_testvec {
+ bool inbound;
+ cgo_tv_state_t state_in;
+ const char *cmd;
+ const char *tag;
+ const char *msg;
+ struct {
+ cgo_tv_state_t state;
+ struct {
+ const char *t_out;
+ const char *msg_out;
+ } result;
+ } output;
+} CGO_RELAY_TESTVECS[] = {
+// All zeros, inbound
+{
+ // Inbound
+ True,
+ // R = {K, N, T'}
+ {"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000"},
+ // AD
+ "00",
+ // T
+ "00000000000000000000000000000000",
+ // C
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ // Output={R', {T_out, C_out}}
+ {{"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "66e94bd4ef8a2c3b884cfa59ca342b2e"}, {"66e94bd4ef8a2c3b884cfa59ca342b2e", "66e94bd4ef8a2c3b884cfa59ca342b2e58e2fccefa7e3061367f1d57a4e7455a0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40deb3fa6794f8fd8f55a88dcbda9d68f2137cc9c83420077e7cf28ab2696b0df05d11452b58ac50aa2eb3a195b61b87e5c65a6dd5d7f7a84065d5a17ff46273086002496db63fa4b91bee387fa3030c95a73f8d0437e0915fbce5d7a62d8dab0a58b2431bc0bede02550f40238969ec780410befccde6944b69dd007debe39a9dbc5e24f519a4bdf478b1d9ec0b67125f28b06efaa55d79412ad628d45089c3c304f94db3a21df6cdaf6d2e2e3b355441eff64ad90527e752a4b2ebb4d0a1070ce2e2982e272fdb7cf4b584b095a0f957fdb828689437e37dc48b2ad379c6f3c6e957ee77afb88c65949ba12eec45c22865e4907ae42aee813898acdf91e2e4c21d828e0a76de2bb6bb6f869e5eef1f618dedd27562812b9a14e8996a5c352df3817e60d6ec20119a52c80a61ec195622627240212decca515feab63e2734587948a836a7de205cfec0c288351c"}},
+},
+// All zeros, outbound
+{
+ // Inbound
+ False,
+ // R = {K, N, T'}
+ {"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000"},
+ // AD
+ "00",
+ // T
+ "00000000000000000000000000000000",
+ // C
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ // Output={R', {T_out, C_out}}
+ {{"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "66e94bd4ef8a2c3b884cfa59ca342b2e"}, {"66e94bd4ef8a2c3b884cfa59ca342b2e", "66e94bd4ef8a2c3b884cfa59ca342b2e58e2fccefa7e3061367f1d57a4e7455a0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40deb3fa6794f8fd8f55a88dcbda9d68f2137cc9c83420077e7cf28ab2696b0df05d11452b58ac50aa2eb3a195b61b87e5c65a6dd5d7f7a84065d5a17ff46273086002496db63fa4b91bee387fa3030c95a73f8d0437e0915fbce5d7a62d8dab0a58b2431bc0bede02550f40238969ec780410befccde6944b69dd007debe39a9dbc5e24f519a4bdf478b1d9ec0b67125f28b06efaa55d79412ad628d45089c3c304f94db3a21df6cdaf6d2e2e3b355441eff64ad90527e752a4b2ebb4d0a1070ce2e2982e272fdb7cf4b584b095a0f957fdb828689437e37dc48b2ad379c6f3c6e957ee77afb88c65949ba12eec45c22865e4907ae42aee813898acdf91e2e4c21d828e0a76de2bb6bb6f869e5eef1f618dedd27562812b9a14e8996a5c352df3817e60d6ec20119a52c80a61ec195622627240212decca515feab63e2734587948a836a7de205cfec0c288351c"}},
+},
+// All ones, inbound
+{
+ // Inbound
+ True,
+ // R = {K, N, T'}
+ {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff"},
+ // AD
+ "ff",
+ // T
+ "ffffffffffffffffffffffffffffffff",
+ // C
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ // Output={R', {T_out, C_out}}
+ {{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "7209baed4b605b158b7eb25de2200e83"}, {"7209baed4b605b158b7eb25de2200e83", "5546c0d2d8da37d92908803d88ff5a646e24a9f9c8c0e9f239726ccc5107d45ed813697aab0b27969930489e47c87475d71b92fc875e268d2ed92fa735b8258c657ff883512adf916a7a8819596e878415da7dc689fc658b862235133b4366e5bea11ece0990a544cb324e27313d67567797213ddb9102e75caca82a15035e44a306c906f8c17e2c88975808b35ad13443849d9ebec10f2c888738ff5b7cb3043b2bbd6098b167746addcc55238fb32d9ef404f3d0f7db0bc5f30aca0cf9ce5f87c989268d18b1069b33bbd5b7818a99603ec0d82871e75cffd1d84e2be1e0f8e8b3678b1ccd7a5a676d83fe0e68f09027ad912d58d2257932750b383e2f2fa3c889ee9d71919cc05d982230c6ff8b7e5e3ed302ed82bed429794c261aa009d231bb6c8675e513313432017cea50843a0309153f7f9d556330f19c38bc5ae6d33d63abaa7ebabd3335c1bf59a2121378288da679259bb1b8a8b027938f3e902c655c781e7f5d9514e53502e7ebc31e344344c3ae2a6397a9a8b846dab8a84174e91664804c7804bab09d6d40aeeb491d6f6184830ac7b5807418a05a7ab9938c3fdc18066b5d503f8c98e83be033b6fba905324267618cc6989b486e0decf7cc897d17be093286a4d4fb5016c3e3323ccc416a30473081473bd471e430194ec4e2ac0af3bca0577b78f4c70e4d"}},
+},
+// All ones, outbound
+{
+ // Inbound
+ False,
+ // R = {K, N, T'}
+ {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff"},
+ // AD
+ "ff",
+ // T
+ "ffffffffffffffffffffffffffffffff",
+ // C
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ // Output={R', {T_out, C_out}}
+ {{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "7209baed4b605b158b7eb25de2200e83"}, {"7209baed4b605b158b7eb25de2200e83", "5546c0d2d8da37d92908803d88ff5a646e24a9f9c8c0e9f239726ccc5107d45ed813697aab0b27969930489e47c87475d71b92fc875e268d2ed92fa735b8258c657ff883512adf916a7a8819596e878415da7dc689fc658b862235133b4366e5bea11ece0990a544cb324e27313d67567797213ddb9102e75caca82a15035e44a306c906f8c17e2c88975808b35ad13443849d9ebec10f2c888738ff5b7cb3043b2bbd6098b167746addcc55238fb32d9ef404f3d0f7db0bc5f30aca0cf9ce5f87c989268d18b1069b33bbd5b7818a99603ec0d82871e75cffd1d84e2be1e0f8e8b3678b1ccd7a5a676d83fe0e68f09027ad912d58d2257932750b383e2f2fa3c889ee9d71919cc05d982230c6ff8b7e5e3ed302ed82bed429794c261aa009d231bb6c8675e513313432017cea50843a0309153f7f9d556330f19c38bc5ae6d33d63abaa7ebabd3335c1bf59a2121378288da679259bb1b8a8b027938f3e902c655c781e7f5d9514e53502e7ebc31e344344c3ae2a6397a9a8b846dab8a84174e91664804c7804bab09d6d40aeeb491d6f6184830ac7b5807418a05a7ab9938c3fdc18066b5d503f8c98e83be033b6fba905324267618cc6989b486e0decf7cc897d17be093286a4d4fb5016c3e3323ccc416a30473081473bd471e430194ec4e2ac0af3bca0577b78f4c70e4d"}},
+},
+// Pseudorandom 1, inbound
+{
+ // Inbound
+ True,
+ // R = {K, N, T'}
+ {"3ab14ee71f417dc6cba5aaaba8eff9c3cd5f408020b4e8586ff734dad4aff593f4d863afbc519eba44d6e8643ae3fabf7ba8cd0803094d82b18acb03c1207927", "e616de4990c8efc5e58131f635f35776", "310495f73b4d20f4d8069bb1d2ed5638"},
+ // AD
+ "88",
+ // T
+ "5de86524ea1542e8f1b8ea118c12d1fd",
+ // C
+ "43f965f6b01b939d972a2b9bd3b2cefe4315da3f97b51af875dc7717b97d9ac37c9e18e4a00fdcc65dde90ebd6c2909fa3e1d83cb07863596408f94334522c1e04688855c44dbee3bad7ab2872c1b87493766c6e0639bcdbbb2717be2d848c37ef034607f6b05facec43f5c1ef99a78631ab8387385cf0b272b0759513807451c63b4ba7f8908e5822b43bea59013c4bba59ab70dd9951ad1d015ccc9b4067aa02cc40d530e2e2bc473906f03a69f5f92183d2094af98edd23199940572edf095a42ec9be535982d6bdf8e525cf2a26011082d0ad019bd3580be817b1049db2e3ca35ee1212b15faa2c35bd4b342c930cc44e77336d84fcbd36454aa3a3cd7961047b58fd26383d1fbe0beb250f8389c1e949728d3d8218b36f4989e3499ced2e660b7ed6a5edb51a36f2fe9f32238f1a318141fcb3bed2c8a34efb5f98b8bccf2548fb542826e6abf3db576ccb064c905c246ecb4ecd5d638e7d3705b549df99de126227485f8dcb499dabc6f3e5d9735a70f1073f708293b2855dd64c981bdfceb8c75bd7d692f7a2d26f453c302d4593af2bb17a785d52bc87914f62056326dbedb8b5d45333dc7fca8d5eea986b1c19ff122b60c74f9220a3eaddf0f40ee105fee1c336c93afef1804a81bb57f918dbd7ef220428dd26c6d83c95e6adcec8f997b8ed810dcdc0bb3867f37",
+ // Output={R', {T_out, C_out}}
+ {{"3ab14ee71f417dc6cba5aaaba8eff9c3cd5f408020b4e8586ff734dad4aff593f4d863afbc519eba44d6e8643ae3fabf7ba8cd0803094d82b18acb03c1207927", "e616de4990c8efc5e58131f635f35776", "84fe1db6790ae6e32e418a70bb70d695"}, {"84fe1db6790ae6e32e418a70bb70d695", "be638eacedc6fbbdf8d9f75f414b3b43ff4fdef3c261a24ffec5eae75a3a1016432bdfc6df956b1e19eb011dc891238d86938ee98d7e0beac3df360818e45aff037e42e345153f5814937d53f92492b03f526c3e85464912742bbb26df3258e7fe0e3fdd7c8b855122543a6d277f896bec6875e6d320d5f329b90d1e57ea2aa9691542c13c9601f7dae18313737387a85eff1ba244be546cd1511782555b8ab90306bd85170e3a489c13f892f4430ae39c49ab1514d05b510709da34651dbe600f68642541ee9ab2163a0e442b6017014c80e05b622d53fa40cbd5eaafbfec34289c5b48c2908a2e7749e1c3f0cceab57bea1f3c925756e477d0c32c1d6262f259a5b20b8234aba22c36604fa6c9f0b953724089b549b7442adae8a91a7a7c3070aad0099d3cb94c17b2f767a8933bbae1de8322d73d9688f6f211b9b3922e758b2407179083490d3bd2d3f366e012f86aa268c2d24ea843953b3cc4a83f33c795f5df035da1c7ef4b160d013d201adcc469def9b4c6334cb9f091f789ba1a23cb2a667564eea9ea3a24c5f1fea54c8f7842ba6266c5405b6cf5f611ee4d0253b09500ce0e704ae2b9aad6271b59ac3e34a446c03c1cf261757c6798d6cc9fe6be8793666d8d046cb5aee99a0598184b3c614444a7b0ed812fe46c1e7ae9a0aee9f49908e705896edf53a3a90f"}},
+},
+// Pseudorandom 1, outbound
+{
+ // Inbound
+ False,
+ // R = {K, N, T'}
+ {"3ab14ee71f417dc6cba5aaaba8eff9c3cd5f408020b4e8586ff734dad4aff593f4d863afbc519eba44d6e8643ae3fabf7ba8cd0803094d82b18acb03c1207927", "e616de4990c8efc5e58131f635f35776", "310495f73b4d20f4d8069bb1d2ed5638"},
+ // AD
+ "88",
+ // T
+ "5de86524ea1542e8f1b8ea118c12d1fd",
+ // C
+ "43f965f6b01b939d972a2b9bd3b2cefe4315da3f97b51af875dc7717b97d9ac37c9e18e4a00fdcc65dde90ebd6c2909fa3e1d83cb07863596408f94334522c1e04688855c44dbee3bad7ab2872c1b87493766c6e0639bcdbbb2717be2d848c37ef034607f6b05facec43f5c1ef99a78631ab8387385cf0b272b0759513807451c63b4ba7f8908e5822b43bea59013c4bba59ab70dd9951ad1d015ccc9b4067aa02cc40d530e2e2bc473906f03a69f5f92183d2094af98edd23199940572edf095a42ec9be535982d6bdf8e525cf2a26011082d0ad019bd3580be817b1049db2e3ca35ee1212b15faa2c35bd4b342c930cc44e77336d84fcbd36454aa3a3cd7961047b58fd26383d1fbe0beb250f8389c1e949728d3d8218b36f4989e3499ced2e660b7ed6a5edb51a36f2fe9f32238f1a318141fcb3bed2c8a34efb5f98b8bccf2548fb542826e6abf3db576ccb064c905c246ecb4ecd5d638e7d3705b549df99de126227485f8dcb499dabc6f3e5d9735a70f1073f708293b2855dd64c981bdfceb8c75bd7d692f7a2d26f453c302d4593af2bb17a785d52bc87914f62056326dbedb8b5d45333dc7fca8d5eea986b1c19ff122b60c74f9220a3eaddf0f40ee105fee1c336c93afef1804a81bb57f918dbd7ef220428dd26c6d83c95e6adcec8f997b8ed810dcdc0bb3867f37",
+ // Output={R', {T_out, C_out}}
+ {{"3ab14ee71f417dc6cba5aaaba8eff9c3cd5f408020b4e8586ff734dad4aff593f4d863afbc519eba44d6e8643ae3fabf7ba8cd0803094d82b18acb03c1207927", "e616de4990c8efc5e58131f635f35776", "84fe1db6790ae6e32e418a70bb70d695"}, {"84fe1db6790ae6e32e418a70bb70d695", "be638eacedc6fbbdf8d9f75f414b3b43ff4fdef3c261a24ffec5eae75a3a1016432bdfc6df956b1e19eb011dc891238d86938ee98d7e0beac3df360818e45aff037e42e345153f5814937d53f92492b03f526c3e85464912742bbb26df3258e7fe0e3fdd7c8b855122543a6d277f896bec6875e6d320d5f329b90d1e57ea2aa9691542c13c9601f7dae18313737387a85eff1ba244be546cd1511782555b8ab90306bd85170e3a489c13f892f4430ae39c49ab1514d05b510709da34651dbe600f68642541ee9ab2163a0e442b6017014c80e05b622d53fa40cbd5eaafbfec34289c5b48c2908a2e7749e1c3f0cceab57bea1f3c925756e477d0c32c1d6262f259a5b20b8234aba22c36604fa6c9f0b953724089b549b7442adae8a91a7a7c3070aad0099d3cb94c17b2f767a8933bbae1de8322d73d9688f6f211b9b3922e758b2407179083490d3bd2d3f366e012f86aa268c2d24ea843953b3cc4a83f33c795f5df035da1c7ef4b160d013d201adcc469def9b4c6334cb9f091f789ba1a23cb2a667564eea9ea3a24c5f1fea54c8f7842ba6266c5405b6cf5f611ee4d0253b09500ce0e704ae2b9aad6271b59ac3e34a446c03c1cf261757c6798d6cc9fe6be8793666d8d046cb5aee99a0598184b3c614444a7b0ed812fe46c1e7ae9a0aee9f49908e705896edf53a3a90f"}},
+},
+// Pseudorandom 2, inbound
+{
+ // Inbound
+ True,
+ // R = {K, N, T'}
+ {"302b0f1333b68c8c2c367b1aa02701e07f715b2fc28f34e124893657a98d5442339c9dc55adec43305e5c03e0b9ac69d35f31e92c6bf9aa066607895b453b89e", "02899ad22f2f01d8768323613476c78c", "db34fd587ddf145c5aa1ac58bef5756d"},
+ // AD
+ "ab",
+ // T
+ "867464943ada7a8decef75a961214f9a",
+ // C
+ "0f0cfeed7dcd312b7b769cc859b20a8e18da16451925a0153ae6a57226fec6b2048dea4584e47e078ecbce0f2ca6413a2bb4e30fd6628a036d1749556adb012d110e23c979dc26c2aee3f24bf2ccf27cfd6d294073a20e9c4c5401c09bc4b2e38b6002b2b320b408b99798db1222034813fd70723a141de5a11679a56b704b1cd8751e919565ea129ce1f9fc2883c7d4cac0d8fd4da61d57501788105ef0d622fca6bfbf72b11a3a03d388c99e4aea582db920872be152bf89dc672383263936d93c0c9915db9b103cbcff5e90f4d9dbae0c4ea8e8464332b9ffaa478735faee477e28355be86f572e2ccca91e60e1874edd1d592b0f4f625276dd5a270a830147365c3fa20168088477c08c56352015ee962d1ce6d24456c96b649921ecffbafa21ff713e2d0da18f2e72e49830ada7878b7fba8eb3700c1db10cbd62ddd6bf1350374a10df5578e6b0774b510d15f11bbe95fd3ed87a8bd68c5110621e12d708f266ee8e48979e2d0fb222c008faea9d9f4ae14951301f9359ed133c5328e6fdd817e83ad84341500752b052bea6432841c801ffd68856c597dc0ce006c89222f1173194044de3d0f75b670923c4de63c683de97990af9430f83ba7510220f56a46e8a47b6ee46a4fcc132d33e059dc3783e3dfe2ecd673588feeb4af5945e18693238520aada42ab371ff4e",
+ // Output={R', {T_out, C_out}}
+ {{"302b0f1333b68c8c2c367b1aa02701e07f715b2fc28f34e124893657a98d5442339c9dc55adec43305e5c03e0b9ac69d35f31e92c6bf9aa066607895b453b89e", "02899ad22f2f01d8768323613476c78c", "61637a70ae9a95105b1e78ff6892e60e"}, {"61637a70ae9a95105b1e78ff6892e60e", "b9b2516c278a8b4bba221b185e990d4814e94b8ea6ef5e7585945ec250c1d427d2c322e3c3f3f406a43408296e0820debb518543be2ed9a18d61b0ac46e1de159101fb6431711f43eb3e35a0ab1451c30e4d895f888cfada66cffe67de67254e8bd4b3e0834f07033206c3449ae8f8ced104c14a0df0ac8fc2757ae63e1cdc99da87f5bc9fc66d2bb5216e641c04f234da501fa721263229948e51ce73c355e302219f6a8f24daeb6c771ff7aeb7f16fc431551618d32c3ea78543bc71d95593a1675b5a1fa936db5945dff819abb197da2dfa460a7619033c9de74679f02fa73badd4ce89a43b25517a12eedd5b3464ca44f4c68e8f14e671f366a541f340b376a5890202f72e15cc22ba1d2573190e3cc65ba042e874d05ed11a16bd5f93a8defb047a223d647b54b0531fc76beb3c7a23766d7cf84479aaa3c25a8b7cc40a31603283aaf98daedc2990c2c4b6006d0a9e80be6bc1a34e65b12a7414acc4046f5f653b0ea2b44e1c93ce1ae8763aa88c366349db4b2305b57030290e989f65d035fdf0375bd889552a79f6647a5810ed2020c1821e78b150501f3e41e4b836ea079fc7b89e215efd9dfb02bcbeb857b0940cb70f64840b40cddf0fc3e3ff3e561b709d8eccbd62b6cb28ebe49003cd1569eb569e87bc24c5d245079da7ae610146aef4225b6f3c6e0ce3aacc"}},
+},
+};
+
+static const struct cgo_relay_originate_testvec {
+ cgo_tv_state_t state_in;
+ const char *cmd;
+ const char *msg;
+ struct {
+ cgo_tv_state_t state;
+ struct {
+ const char *t_out;
+ const char *msg_out;
+ } result;
+ } output;
+} CGO_RELAY_ORIGINATE_TESTVECS[] = {
+// All zeroes, originating
+{
+ // R = {K, N, T'}
+ {"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000"},
+ // AD
+ "00",
+ // M
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ // Output={R', {T_out, C_out}}
+ {{"7941dd0a63d994703e63d94a446804213ab4fb1d2b7ba376590a2c241d1f508dc6a7f418a14503deb89b17aadb2806f73fc06e5d14e675f5ec880023d4f73296", "12dce4a0e5bc792b5b5a55f9c2f30e07", "66e94bd4ef8a2c3b884cfa59ca342b2e"}, {"66e94bd4ef8a2c3b884cfa59ca342b2e", "66e94bd4ef8a2c3b884cfa59ca342b2e58e2fccefa7e3061367f1d57a4e7455a0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40deb3fa6794f8fd8f55a88dcbda9d68f2137cc9c83420077e7cf28ab2696b0df05d11452b58ac50aa2eb3a195b61b87e5c65a6dd5d7f7a84065d5a17ff46273086002496db63fa4b91bee387fa3030c95a73f8d0437e0915fbce5d7a62d8dab0a58b2431bc0bede02550f40238969ec780410befccde6944b69dd007debe39a9dbc5e24f519a4bdf478b1d9ec0b67125f28b06efaa55d79412ad628d45089c3c304f94db3a21df6cdaf6d2e2e3b355441eff64ad90527e752a4b2ebb4d0a1070ce2e2982e272fdb7cf4b584b095a0f957fdb828689437e37dc48b2ad379c6f3c6e957ee77afb88c65949ba12eec45c22865e4907ae42aee813898acdf91e2e4c21d828e0a76de2bb6bb6f869e5eef1f618dedd27562812b9a14e8996a5c352df3817e60d6ec20119a52c80a61ec195622627240212decca515feab63e2734587948a836a7de205cfec0c288351c"}},
+},
+// Pseudorandom 1, originating
+{
+ // R = {K, N, T'}
+ {"3ab14ee71f417dc6cba5aaaba8eff9c3cd5f408020b4e8586ff734dad4aff593f4d863afbc519eba44d6e8643ae3fabf7ba8cd0803094d82b18acb03c1207927", "e616de4990c8efc5e58131f635f35776", "310495f73b4d20f4d8069bb1d2ed5638"},
+ // AD
+ "88",
+ // M
+ "43f965f6b01b939d972a2b9bd3b2cefe4315da3f97b51af875dc7717b97d9ac37c9e18e4a00fdcc65dde90ebd6c2909fa3e1d83cb07863596408f94334522c1e04688855c44dbee3bad7ab2872c1b87493766c6e0639bcdbbb2717be2d848c37ef034607f6b05facec43f5c1ef99a78631ab8387385cf0b272b0759513807451c63b4ba7f8908e5822b43bea59013c4bba59ab70dd9951ad1d015ccc9b4067aa02cc40d530e2e2bc473906f03a69f5f92183d2094af98edd23199940572edf095a42ec9be535982d6bdf8e525cf2a26011082d0ad019bd3580be817b1049db2e3ca35ee1212b15faa2c35bd4b342c930cc44e77336d84fcbd36454aa3a3cd7961047b58fd26383d1fbe0beb250f8389c1e949728d3d8218b36f4989e3499ced2e660b7ed6a5edb51a36f2fe9f32238f1a318141fcb3bed2c8a34efb5f98b8bccf2548fb542826e6abf3db576ccb064c905c246ecb4ecd5d638e7d3705b549df99de126227485f8dcb499dabc6f3e5d9735a70f1073f708293b2855dd64c981bdfceb8c75bd7d692f7a2d26f453c302d4593af2bb17a785d52bc87914f62056326dbedb8b5d45333dc7fca8d5eea986b1c19ff122b60c74f9220a3eaddf0f40ee105fee1c336c93afef1804a81bb57f918dbd7ef220428dd26c6d83c95e6adcec8f997b8ed810dcdc0bb3867f37",
+ // Output={R', {T_out, C_out}}
+ {{"c24b000843784bc008c70b977e62ed82085ed0cda9f841da2c89d1832e763b9e283c36875fa41caae5913293d8014451c10fedddf362849bcaaa1833a3b8fcd8", "497798331f2c32ca4de4b1b55b82c306", "b8b3b69f6e175a5649013ca99c838291"}, {"b8b3b69f6e175a5649013ca99c838291", "94773462bcfb3728ec6f2f4e3b7020234abd8a6fa778a49788509b6452556e951f49a20a552035b38143907c59788c6865dac89ec22af08cc98ed1fcf55debccd3bb18c91340205524b36e1ec0ca0c082f79c575e7e0c77ade4b6084f6b6a12592f9a24c715bc92ee2531641cb11c6e9a462242354d655c392fccc1c84af5217cefb9806eb9990cf36034188600b2a123d860d0c661362f511e7d4eafc46a38c030fbe884a681fedef9c04375793435784579a3640ce2d75d9553936e877c3c24b33e0ffa88d59fed2fbbaf91e446c8d37a6b1400f7dfcd6ba8fa425c36e111a71c661f81ac8824524038a8dab5ac5a17014f4e7af5638e27e14869b51a9a2ff43fc9b3d7205e9f2e9f20c80d52778c26589179631345b0cedcb76d4862e3f88dcd27074da5d8b36ce7f2fbb972dafe327fd0e68620f5b284b1a7f1e64e33df2abd0f4aabe30b0e168f52ea39f1c5755276bc5c25cfa3960c2646ac13cbf2d9d1748e9c8db3664a98b4ef4e6f4a401cde973a62f0d4a6409447dfd2500b916015e50d79eeaa6508295d7959cb45af82b2b1b081b84911f9feeb994ddc5c472b342eef82d611809051658215158b99f5e3002e97f343e3b29eaad6489557573780b13956e4665dd0b859631d9937d4f90e0f810b36babfe8a1371b6eb985fd600d8353962cca9ce5b9d2ebf0da8"}},
+},
+// Pseudorandom 2, originating
+{
+ // R = {K, N, T'}
+ {"302b0f1333b68c8c2c367b1aa02701e07f715b2fc28f34e124893657a98d5442339c9dc55adec43305e5c03e0b9ac69d35f31e92c6bf9aa066607895b453b89e", "02899ad22f2f01d8768323613476c78c", "db34fd587ddf145c5aa1ac58bef5756d"},
+ // AD
+ "ab",
+ // M
+ "0f0cfeed7dcd312b7b769cc859b20a8e18da16451925a0153ae6a57226fec6b2048dea4584e47e078ecbce0f2ca6413a2bb4e30fd6628a036d1749556adb012d110e23c979dc26c2aee3f24bf2ccf27cfd6d294073a20e9c4c5401c09bc4b2e38b6002b2b320b408b99798db1222034813fd70723a141de5a11679a56b704b1cd8751e919565ea129ce1f9fc2883c7d4cac0d8fd4da61d57501788105ef0d622fca6bfbf72b11a3a03d388c99e4aea582db920872be152bf89dc672383263936d93c0c9915db9b103cbcff5e90f4d9dbae0c4ea8e8464332b9ffaa478735faee477e28355be86f572e2ccca91e60e1874edd1d592b0f4f625276dd5a270a830147365c3fa20168088477c08c56352015ee962d1ce6d24456c96b649921ecffbafa21ff713e2d0da18f2e72e49830ada7878b7fba8eb3700c1db10cbd62ddd6bf1350374a10df5578e6b0774b510d15f11bbe95fd3ed87a8bd68c5110621e12d708f266ee8e48979e2d0fb222c008faea9d9f4ae14951301f9359ed133c5328e6fdd817e83ad84341500752b052bea6432841c801ffd68856c597dc0ce006c89222f1173194044de3d0f75b670923c4de63c683de97990af9430f83ba7510220f56a46e8a47b6ee46a4fcc132d33e059dc3783e3dfe2ecd673588feeb4af5945e18693238520aada42ab371ff4e",
+ // Output={R', {T_out, C_out}}
+ {{"60b9d644a620c3f36181f6f3ecbb0be41d400b78822dd3247247d286a5b80baec2dfc3694f119beab9b40fd538844d159e7bf256fb2ce53fe33e4c8763180b0a", "094b5cdc3a49cc51aab3e1f331f03df6", "99daac5f8bdba8f4807e719c768cb3ce"}, {"99daac5f8bdba8f4807e719c768cb3ce", "30db410a04452437045b7f51210bd01eab5d034c146c766ef73a9500b1c7f75d5ea7b1fe47f8eb927bcac6fb756e80cdd48b381a431c858432047410cd526bd91283a53ab94371bff4c4370e8dc8671349316759bdd01bbe432423a66a8497a7091c8056af277112a04c65946dbf82d076e66647456e991ff44c689e57d475956a3c1dd5f1a870e711ed57dc287b96f6437e2e4194e341a2dc5913631eab53f899f09ee41361b4d74c508f42ae972c93d21797342242b7e4e39d24888dfd215458a8e134fb9da152a0b1e5304685919f5dc3da8a0dc04906763075432ce92afe1283b1d344c36832bb54cf47a28c13263fd34558ef1c7827b4d8c1aea20f23316b04d1750bf42b6317a421618c3af00f5469d28aa52e8aef1e76d80754a52982285c1d558c61268d40f2e931c0b3848f70da72b07867df56de689a19f2db0a379207ca462a0bc97a3ea7d111a144454432e4d0eb3ee1fc5f905923effa1b196ce29f9c07d32fabcdfcce4c2d582a7b80b65fff05ffd2b5e7d91fca0817e9458c68d6919ad442ca1d20d77c7c0b6e924af2665d9eeaeeac28692f978eecd4e1d5878ce300f8035d0a7ff6050a172c1d328bb392e4d55198a976d45f7d9670eeb67ed4b79c95b219fc9cf3c7613c128e2224d2799d9459b4941a248589d7bc1cd644ac96aa49e0d630288b73a028"}},
+},
+// Pseudorandom 3, originating
+{
+ // R = {K, N, T'}
+ {"f69da975bf0055353e52a8b3fa834b1bcedf1445e4b2f1dca13f59a306e8040ce64d5922b2b9de5735a96e2fa2e9524e99ce5b8888fd000f570f148191bdb54f", "8e4219f5b72d0bbf1f47005632816b36", "c5301aaf38e66f698293618354d06e0a"},
+ // AD
+ "90",
+ // M
+ "727ee8dff3a22ad873545c040d22a67a6caac97c308a0f4109da1a1d67695d9fd7570a27593fefcdc0ce568ff6f8998a03791e12720a86d95110540073e104a86ba14ac9e58705ff20ebfced49a91d832a635924193dbf14ff995da7d4cbb4752d364908c1096606cee429adad73513bfd848fb6132fad9531178b419d4c6670224e858ff0a413b083b58cb6a8297bc7474e48050ac926c3a568df88feb135e9011d26eb2327c0797fd821a9bca3052e116f26844a2a5d23542ea666f2225700dd134cc166e2cd36f88be6a4b367be083e7d7be99a9205489de7ece3308846fcad66dd249ada0c559999fc3dd9e36036831e3e2aa51d0190b227f3bb54b365ea668009298612308361537b66e143fdb5b3da43a6a141910b7daef3dd4c5a819749c1d5d005c3c39bf7d2d749754614e794c51a965694904d30fa5be6fba2360ccf46c4ed2b4829f6434bb8951e82580a4da3d7075d734c4c12560693b9bacb1ce7ee953d7ce9dec24d7a129e8e582a3e2e1168e7b966c2e435b21f9b7ba83e27023b287e7fc420c5934af909e1a3fcb8415347c5ebd30aebaf6fe11cbea60d8dbe78cd54736dcb6a0cab929175417510d0ab2c4688b91c8d75d5a9b51ff15fddeb1a08402dc7748eb5b9d219f4ecb4116be1765a03fd06fc01d8e366b945cf6557257ef0ec2b74619d4e081c89",
+ // Output={R', {T_out, C_out}}
+ {{"c658a50d452e0ac66a543a15dfb30f791509266d47e259d56374787e3e2ccc49a06c6d2d65553223ace6097a3fb7cee5f4af4602a4c73c8128391e2454b7caa1", "2436c77f19dee78ff65f39967659e7d5", "276d823e18b1a06c0fe224431630b7b2"}, {"276d823e18b1a06c0fe224431630b7b2", "545b61a9a2d88a6f0e389c864fcdec76f5d04b836a1d1a48b26895f4c8829af6de70ac08578f2e1cd054f4a9ab5efbdbd872b712ca451270f472a621a95827a382829d794395ae507ccc1df35a677d069207296faa9c2a1d3a454ada30deac8e3a2fd4cfa69c298f9ae0f6a6d15b2a3404c84233c29fc8e85cdf009dfab83ff18f0a7f9ed8a4d7ef10e6fae321c5c526f01dc5f045ec9504e270cb634b072b03d1a0ef8b013913684b935d2883bdfd49ce8dbde8e603663b7ebe869072d61462aea8f7da0d7bc4be054032995c5f5862493f3e45580d9415a3f68eb083092a4c1066f06725da1751b025efb015683cc1935cfafafe7aef90d9c18f2a5f2cce060716838303ca8b7de3164fc09a9d15ccbedd7c24bd47f9585b3b333012ce3a1718cd8ad493b90695734350ac345c42c911d5038b9f288d2d5da8e1bafe1f22967eef3f705a49310f7ebb0837303ede480564cbd5174d354c15668846ed5e9b40002f831d118aeb1d78fd41a9e80064da3bc0f84fe0898e0e2d81cf20a14baebb1f1d784682fce429625f6a8999177f9e1adf515638280279f5dbbb8eff1fb09ba3782cb6bb49ae28b38883808c69c70a45cf2efb5932c67c77756a9eae3cc63cab0f3554cc55e6fe6f1d1fe6a7fd27c248fa0f491a5c459c0e51bc06d9574cb22c1c4d5aa64b4b66875233bbdd"}},
+},
+};
+
+static const struct cgo_client_originate_testvec {
+ cgo_tv_state_t state_in[3];
+ int target_hop;
+ const char *cmd;
+ const char *msg;
+ struct {
+ cgo_tv_state_t state[3];
+ struct {
+ const char *t_out;
+ const char *msg_out;
+ } result;
+ } output;
+} CGO_CLIENT_ORIGINATE_TESTVECS[] = {
+// All zeros, hop 3/3
+{
+ // S{}
+ {{"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000"}, {"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000"}, {"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000"}},
+ // d
+ 3,
+ // AD
+ "00",
+ // M
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ // Output={S'{}, T, C}
+ {{{"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "af65bb470269ecd7af01f68f1a2b7b78"}, {"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "140f0f1011b5223d79587717ffd9ec3a"}, {"7941dd0a63d994703e63d94a446804213ab4fb1d2b7ba376590a2c241d1f508dc6a7f418a14503deb89b17aadb2806f73fc06e5d14e675f5ec880023d4f73296", "12dce4a0e5bc792b5b5a55f9c2f30e07", "00000000000000000000000000000000"}}, {"1471e71e6fb1f04233a8ec5daa6209e0", "66e94bd4ef8a2c3b884cfa59ca342b2e58e2fccefa7e3061367f1d57a4e7455a0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40deb3fa6794f8fd8f55a88dcbda9d68f2137cc9c83420077e7cf28ab2696b0df05d11452b58ac50aa2eb3a195b61b87e5c65a6dd5d7f7a84065d5a17ff46273086002496db63fa4b91bee387fa3030c95a73f8d0437e0915fbce5d7a62d8dab0a58b2431bc0bede02550f40238969ec780410befccde6944b69dd007debe39a9dbc5e24f519a4bdf478b1d9ec0b67125f28b06efaa55d79412ad628d45089c3c304f94db3a21df6cdaf6d2e2e3b355441eff64ad90527e752a4b2ebb4d0a1070ce2e2982e272fdb7cf4b584b095a0f957fdb828689437e37dc48b2ad379c6f3c6e957ee77afb88c65949ba12eec45c22865e4907ae42aee813898acdf91e2e4c21d828e0a76de2bb6bb6f869e5eef1f618dedd27562812b9a14e8996a5c352df3817e60d6ec20119a52c80a61ec195622627240212decca515feab63e2734587948a836a7de205cfec0c288351c"}},
+},
+// All ones, hop 3/3
+{
+ // S{}
+ {{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff"}, {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff"}, {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff"}},
+ // d
+ 3,
+ // AD
+ "ff",
+ // M
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ // Output={S'{}, T, C}
+ {{{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "3cf25f81c98d0be16ddbbffeefbdc308"}, {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffff", "a9166add184e00b007217cb4e4f52ee5"}, {"be938fc23009440bfb5d7bba1d28428ec0897793bb878b8e1eb3ec1257b88024d551d770b56c9312de3dd4ac64e194c91185a89f2ba01f90b03b3acb93f634df", "4b263f03af0acda2f9721d0f4c0783c7", "ffffffffffffffffffffffffffffffff"}}, {"c8c388584500c58ced7ee209c08b920a", "c0685473f8558a9f9f2f22cfb31f211c6b25b7ebdabf2507b4269636caa01e1f6d4f4f5690c48d6940361059b37516b52b9d9ad93388f964666e7492a6adb91645a02cf39eed4ebd0354d8f484106c04ebb0e53d858c75a44e3145471bf93d09d48af913fdcefa6a0dd3fb730e604035d494f0a5706c3b63424253b7287392a44e9b2f66f765dd7cda20c76a2444a4dfa84170d810eb13e720867170c243ff4d9662b1df15b826c664f1a52e4f57be57b49105895e8ae3b87fd969034f67ae9784d946935dac622cb4cf786ad937174ceab2c766be361f8efc0479aa0b45c5e90da1dcee6802b5acf53dfee7a12e27d55e832b5f77360cd7190522d9057a556b8e1de773a0c29cc20c44dd963395cce1c19633fe1e386a3cc87082d5e645914d96ce3d8dcb9653dedacd8bfc2fe5d7a3e9e205a9c0961dd83d5b5515842fa3291877146081d5d776c4675de92b3f92edd80d7792b9a9f203c6650a33e54822d45a92c7136cf4fdbe6fe698ed6d3596cce17853aa988142a5925e1cd4382fb4d43307c26d57676c1ae5aaec6100de8414f8fc763e87a052f3d7519d539499d90f427c951d91348d9f0c7d77dd454bd8cd80b9b13a1870f95ea19e8dbdfd78ca4cfd520e5bcfcbd751252775165790b250b0d87989a60ccbd4243f8409a28d1d0536d9d9ad51ee474d24a92870b7"}},
+},
+// Pesudorandom 1, hop 1/3
+{
+ // S{}
+ {{"80819c55d001b73b8d51a5c9ce4fc8e2a197bd4891f0f38df791e92fc687c99214992b6749f5b96d6477f7a2821029f714de39b47396fff84b79406ceb667213", "475cec821a2bb29682c9de4ed89fa2bc", "63c839b54659920bbf42c8a76eedc3a9"}, {"79d6e9f34cd2a01b89130bc43002e94a4c3494dfc8db9d11e08d7b8ae7782b38fde2c00e9819d5c619a5c8a92afbabdb727108b5dd4ba9d572b47567685c9e7c", "d6dc99f4ce27ffe7ad3b40c73be86ad8", "eae6b850f1f43e00be741946b5038517"}, {"cc01d778ccfabfad7a442a266aac199e277b38618ba19816d1d668c139367c8ae4c9fc4e6b5a7a214175506d4dffa1c159bc499afc638e6a54a546380b65bcd8", "e459433194d5ce2daf958ef6cb22a391", "34df2febf45efcb197fabf5eef51bf5e"}},
+ // d
+ 1,
+ // AD
+ "00",
+ // M
+ "32b9e80d44f7fd35dc254f1b07cd10ca91e1c9ba7835a9581e99245677c1ecec22de4e30ef1799ab658305c8266d4f1c71e4ad51cd9d5798de85ece04f6ee9636ad4a14a132278df2c34a449b7d53cf71fb4e55affbc7cbc6699b97356a81d4f70591177aa509df7d8ada37bd7c6082059081e8058087bd5e357544b2b2067c62a3cb123592b44bef8ccb5f259e859ac8d6c9cf599605b370a067dced095f96dd03b3577d20b78afeb8c25cbe3b2e52f2105e952603af981a739216fc6fa29f1a417ea501199a74bab8821e828a1e66e8e0de40138aca846902f7e2c5545cb2263a8b148e65fd793abbd831d97771d5ecbc07bcde5b5cfa02489783302174b36f7570c546fcb05b1d1031089b806d9b54d2b0ebf0fa0ce8b486e26c36825b55a1bcdd001b4a6ab3686ae3b5fef3500837a1eb58e44602c87ce6d384d3dab73fc18e662f03a4112c6fd70ee2063a5dd37bc159f2584b8bcc63106ff6f219cb3e45d57e3b78c88fb0acbba7b58f2f3c54d1877160199583876e1a321bfaa813e0ce1e1803fff094e437ca879ab2d85248050f720bfac980a8455f1bd83ad8648af0052a3ff1203a75b033254edcbfc144c53ec72b603b404aac06021d51524953e9d267c912cc82d61b70d47775d80451ae59071ce7596f3dfe60ff0f636ec06689993ed52f8efd7d04415350421",
+ // Output={S'{}, T, C}
+ {{{"d0f4674c280810a523aa25f98bbcff032b4f78f536ab763365384c3f55117e26da677483b85954db5e0840ee66ed269c7089e404f881dea4ecfa1619ca809444", "2b6b31a8b26936bf1823ea99b866d000", "475cec821a2bb29682c9de4ed89fa2bc"}, {"79d6e9f34cd2a01b89130bc43002e94a4c3494dfc8db9d11e08d7b8ae7782b38fde2c00e9819d5c619a5c8a92afbabdb727108b5dd4ba9d572b47567685c9e7c", "d6dc99f4ce27ffe7ad3b40c73be86ad8", "eae6b850f1f43e00be741946b5038517"}, {"cc01d778ccfabfad7a442a266aac199e277b38618ba19816d1d668c139367c8ae4c9fc4e6b5a7a214175506d4dffa1c159bc499afc638e6a54a546380b65bcd8", "e459433194d5ce2daf958ef6cb22a391", "34df2febf45efcb197fabf5eef51bf5e"}}, {"7d05e89f33820206b821fdd7a7465525", "f97feaae58ac1c0e4a69df97b1da3641d0c8795a1ab5e957d94629b9b181129b58bdc5df73588c0068bc67ef14a50d8cb8dd1dce8c1c5ff6b7a0616bbde921f442dd876b3622f88918ba01234920759d4ec3f1079f4d5029b9903fd2b9c60540b89b59134c36b64b58509791cb6b3074f84fed410f27cd4d868a9cb59df2ebe9e3358ed557c4ed2d91e7f3080468734df02536d5e30c27d4021d5ce00eb38b08cde074587fb321510139c4d865da92a4b0ba3833d8b110e3c81e3226099677f91f570add37f6867e9faae6331bc0ca19e475ac75d8dd688b1d77cfa5c28f3e0838bb3f8457bbe7bfb567826cf42913108c268d710253c74dc09def9885c61a3e0ca65231121d746a720d0f6454d09613e9620c0ffe922be22aae5c7e5ac17b083cff28c48c1c205834880689df9dfc5085775695ac3931dce1b05a669c96664fcdb86794d3883de5f9396c351ef26880f8f5d1f64bde7c73fdf177363343a37497de8e9aa4e139c196c9069e4b9a4cfc71e89a8deb80a2a1810e9584002f3d054e64c7e3afd7f215cdac0ea35ae8e6e88c290006ef80c1a193be34f89ac8ac8f03971c2d8f35fa0ceddf9a34d9482bc9cb9787faf942606131abcce19b6ab1aba23bd45c31d15e1189987114f507661916aae148f80b03a3d769a277ca9ce8c2e9d46f4b58319a72627eba3024"}},
+},
+// Pesudorandom 1, hop 3/3
+{
+ // S{}
+ {{"80819c55d001b73b8d51a5c9ce4fc8e2a197bd4891f0f38df791e92fc687c99214992b6749f5b96d6477f7a2821029f714de39b47396fff84b79406ceb667213", "475cec821a2bb29682c9de4ed89fa2bc", "63c839b54659920bbf42c8a76eedc3a9"}, {"79d6e9f34cd2a01b89130bc43002e94a4c3494dfc8db9d11e08d7b8ae7782b38fde2c00e9819d5c619a5c8a92afbabdb727108b5dd4ba9d572b47567685c9e7c", "d6dc99f4ce27ffe7ad3b40c73be86ad8", "eae6b850f1f43e00be741946b5038517"}, {"cc01d778ccfabfad7a442a266aac199e277b38618ba19816d1d668c139367c8ae4c9fc4e6b5a7a214175506d4dffa1c159bc499afc638e6a54a546380b65bcd8", "e459433194d5ce2daf958ef6cb22a391", "34df2febf45efcb197fabf5eef51bf5e"}},
+ // d
+ 3,
+ // AD
+ "00",
+ // M
+ "32b9e80d44f7fd35dc254f1b07cd10ca91e1c9ba7835a9581e99245677c1ecec22de4e30ef1799ab658305c8266d4f1c71e4ad51cd9d5798de85ece04f6ee9636ad4a14a132278df2c34a449b7d53cf71fb4e55affbc7cbc6699b97356a81d4f70591177aa509df7d8ada37bd7c6082059081e8058087bd5e357544b2b2067c62a3cb123592b44bef8ccb5f259e859ac8d6c9cf599605b370a067dced095f96dd03b3577d20b78afeb8c25cbe3b2e52f2105e952603af981a739216fc6fa29f1a417ea501199a74bab8821e828a1e66e8e0de40138aca846902f7e2c5545cb2263a8b148e65fd793abbd831d97771d5ecbc07bcde5b5cfa02489783302174b36f7570c546fcb05b1d1031089b806d9b54d2b0ebf0fa0ce8b486e26c36825b55a1bcdd001b4a6ab3686ae3b5fef3500837a1eb58e44602c87ce6d384d3dab73fc18e662f03a4112c6fd70ee2063a5dd37bc159f2584b8bcc63106ff6f219cb3e45d57e3b78c88fb0acbba7b58f2f3c54d1877160199583876e1a321bfaa813e0ce1e1803fff094e437ca879ab2d85248050f720bfac980a8455f1bd83ad8648af0052a3ff1203a75b033254edcbfc144c53ec72b603b404aac06021d51524953e9d267c912cc82d61b70d47775d80451ae59071ce7596f3dfe60ff0f636ec06689993ed52f8efd7d04415350421",
+ // Output={S'{}, T, C}
+ {{{"80819c55d001b73b8d51a5c9ce4fc8e2a197bd4891f0f38df791e92fc687c99214992b6749f5b96d6477f7a2821029f714de39b47396fff84b79406ceb667213", "475cec821a2bb29682c9de4ed89fa2bc", "959551c3e8dc83f3cf2e0bf11a1acae3"}, {"79d6e9f34cd2a01b89130bc43002e94a4c3494dfc8db9d11e08d7b8ae7782b38fde2c00e9819d5c619a5c8a92afbabdb727108b5dd4ba9d572b47567685c9e7c", "d6dc99f4ce27ffe7ad3b40c73be86ad8", "9e9c84b867f7dbeb705bfcce09431813"}, {"12f2e45f012ffc1430fee1fb322879ba934f887fe2e7e7ce98071c61bc1086dbb2877845f5fb3869d3a4d23cdbcb44c85aeb9e43771755c9be3bbdb42ecac024", "88ba0caf597d953a26064c5872bdea5b", "e459433194d5ce2daf958ef6cb22a391"}}, {"3222f41f846157bdc258ac55d8f7bd6e", "fb76e827b3a0b6b8d031ea07b273c8f47763cd2c7af610dd0109ff42838bc39d5128492788a36426fc5ab17bab4906c7c4a390ceabe14ccc96ac2ec36dac92ed2a579097d1cb2258aef9cf35e950113adbb305b7ac73e1c1ea9b4e10ff39adc6b129cad8020fdcb349fd383595c61bb551d026b84ed74674bcfbbe027b4814713487a53e5aac4120da59d27b0abce7f438294860c211f19160b53deb9ab5abf49996a1d474518196a1020b460282f9dc3802db33c19e3b50d74fc5f8083403227d9801a158977f36cb2eae1525488660b59e5f45f346f24def7044f1b8e714268ff423d8c9b895e936669b4df15a99ba6382b02349f792b2383a4bd632efb6b6a5b7cbb82eaae1b0261f5386844813f23e08eeb68d63162681d51bf0d38beff2c34afc2e57772887f5c0e341ff2b7c003b24d32bb3873c7f6d5b946c36b18eb0ddfe907c201cd42b7373eb52d0c4bd8eed5179a2081504847f7f99fe529139cdde799105e8c05cf8376eaddf4af1f779835910659ff93ad3f55b25defbcc10567d23247a0f2e688363f91f90184cda34d8e4ad80d4f9f47d9d1af9c10474f7e66bef3ad0a49fbdc8020899289bea741a004df514b8ec5bf2443e3de433cd25916b2889fe6a624e65c4b1306d9feb14fbad48e2c212cb4aa8db92c31b87c20da5b493410fdafaab09fdfb57c9aa"}},
+},
+// Pesudorandom 2, hop 2/3
+{
+ // S{}
+ {{"f2a93dfda00e7654585b911e90acdc3a825f88b497f329637bb612464d928e4182f1b360db55231f255e7265b1614d8ee895cde4e5f4768f749c051b25ac261e", "6a017e1dfd3fcee547b526b048204901", "7dae89533c98d159590a3bc5da3d5fb6"}, {"ff9b9925190d45c46e5ac9eae38da326739b3180432cf0c36cd9346699bd022c4dcb3aa2811f8ab0a2a72cfdc9e13b817d0a20cc1b03f51b8133c6d36d2c4ffa", "2e666844518d40d4a1efee952db70f36", "eeb1f87fd5c7a6b016b6df886c3f2f92"}, {"25f3b6dc37742bf020ad710e67f87ee274f5fe5d0c75c9a22da939847d1f4878de7d35867c306f3176d92d2d5900d33dec007edf02644f01046b9deff015c30f", "df6876f95d2387d8f419d018a826ffed", "c16980670fba6dcd755c567c721e0dcd"}},
+ // d
+ 2,
+ // AD
+ "da",
+ // M
+ "346681ef9e47fff29ddaf41628ae3021888028316787f1887b6c099c921a8915b4d7937a9565d928764fae620b57d117ccd75cf8b633f2d1f1404b65f2479c8d8d590a15da2b40b14987d8968b7d210965f158627a72ba31ccecd5727f2dabf17dacc69027ccf4c53da96a75e6d28a15ffecaec1965a62402a1cc5e9cc26be181689132f54956f99192ac9bbb929c5aec7048a6653ad40cbc4fb029ea97bc15c8b05395e822af36a8b949817ee0f022c8f971eefc5b31bb46e095d4aea07fa97854e1ca4a208bebb65a605089f60a21ef5685b67d312edff8b2cc81830eab9d27ab0a7be29b7c88abb995492564772d518a912c6b40f58ab41c0497995d9b593f0387a3e597728d08f5267fba8370a062817cdf506119e0c5cc69900709195a2288322de578af491698360ad1f6b34b341e10eb21e22f6c5a6e12e26250aeb528aaa533d592b268fb22b3e77ada84d478ee9d0f2742cbb54be14503c21e39efcc73774b24bf28747203c5ff456457139fec8a46c8243b4b9738c27972e6d8f0ef9fa18944aaeed4deb437522f04795ecd7bee79f0a6d7c6c6acd90dac9a935d5f252134cd4ca1e2e0c4386fdae67950f1234cda5472e61a32bf9f037c068fe81a955d1e56a92ad1a8f16e6a31bfc0f8b3cef96410a72b92a75b09a0071ff0c0e99dd322ab7d8e4a2a2c2122af6",
+ // Output={S'{}, T, C}
+ {{{"f2a93dfda00e7654585b911e90acdc3a825f88b497f329637bb612464d928e4182f1b360db55231f255e7265b1614d8ee895cde4e5f4768f749c051b25ac261e", "6a017e1dfd3fcee547b526b048204901", "2d8aa5329c2fab108e90f64a904c4def"}, {"64b7371338ad74c249ba606c677f38b5c08ba69a7ae33c1be26ef81ea604a24a968678f48075273c6b35311642a72466fd2a6b059217f66752b0c9e15de40a5f", "5f6d3291d9d5bf3c3bece127fbf3886b", "2e666844518d40d4a1efee952db70f36"}, {"25f3b6dc37742bf020ad710e67f87ee274f5fe5d0c75c9a22da939847d1f4878de7d35867c306f3176d92d2d5900d33dec007edf02644f01046b9deff015c30f", "df6876f95d2387d8f419d018a826ffed", "c16980670fba6dcd755c567c721e0dcd"}}, {"9527488f5d1c2671e0e8139423149285", "c036126d33eea9f7cf865a9ab8e8eaace3a59f1064fa7506d45862ceb119ed854e1ab2f4294c77beb60564e2095f1f219dac41a024361e0fce045947a5e104a6db4b35175b09fca762121d46be7b4b20c674e4a13a53585586c8318549b86c02db4a554e1a43674237136f91e91e75c7ef74e6d4bceeb682e27ffbd2f47ddf667ad89fea7c48e6fbe69b8a3e54eb31585612719394480416296689d427a59b0f3adf4d92fa239c983a2c010cffe9366c01a1c945757ba07aec7c3df58b95f567e8de04d5719c2c7c62cd44668d43777b87db9126b2fccb62b241ec9d9701e8a34125a4dc2653a3de1f77415cafa76bc2713bed61c44001fb23170d716d008f12b236c0380253f2779fe52e6b2c011ffe312617b149c0b2b47055dc832ead1b297ead29028a4a0dbed96809c2aede9b276458a8a6c142a6a7876de3cfba1d4d0dea00095a66b9e925a3593b956a7e734b074941fc60d656e27a7d24f196cfe928400a180a1b7eb591c7b4e394b2c13040a98612e078094586bb197a585505335f4b5f1f721df1ee76ef27a8f6927fc40077be55a45b093d4fa1057a4a88937174885732f91d04a87424539302c7f9590e4d0b62abfdbd0f162fa3c7d750b8f212a2612127fd2443416736578deeccc76284c164a282f94786812031a19f35629e253a86c730f08676fbd0b0b41d"}},
+},
+// Pesudorandom 2, hop 3/3
+{
+ // S{}
+ {{"f2a93dfda00e7654585b911e90acdc3a825f88b497f329637bb612464d928e4182f1b360db55231f255e7265b1614d8ee895cde4e5f4768f749c051b25ac261e", "6a017e1dfd3fcee547b526b048204901", "7dae89533c98d159590a3bc5da3d5fb6"}, {"ff9b9925190d45c46e5ac9eae38da326739b3180432cf0c36cd9346699bd022c4dcb3aa2811f8ab0a2a72cfdc9e13b817d0a20cc1b03f51b8133c6d36d2c4ffa", "2e666844518d40d4a1efee952db70f36", "eeb1f87fd5c7a6b016b6df886c3f2f92"}, {"25f3b6dc37742bf020ad710e67f87ee274f5fe5d0c75c9a22da939847d1f4878de7d35867c306f3176d92d2d5900d33dec007edf02644f01046b9deff015c30f", "df6876f95d2387d8f419d018a826ffed", "c16980670fba6dcd755c567c721e0dcd"}},
+ // d
+ 3,
+ // AD
+ "da",
+ // M
+ "346681ef9e47fff29ddaf41628ae3021888028316787f1887b6c099c921a8915b4d7937a9565d928764fae620b57d117ccd75cf8b633f2d1f1404b65f2479c8d8d590a15da2b40b14987d8968b7d210965f158627a72ba31ccecd5727f2dabf17dacc69027ccf4c53da96a75e6d28a15ffecaec1965a62402a1cc5e9cc26be181689132f54956f99192ac9bbb929c5aec7048a6653ad40cbc4fb029ea97bc15c8b05395e822af36a8b949817ee0f022c8f971eefc5b31bb46e095d4aea07fa97854e1ca4a208bebb65a605089f60a21ef5685b67d312edff8b2cc81830eab9d27ab0a7be29b7c88abb995492564772d518a912c6b40f58ab41c0497995d9b593f0387a3e597728d08f5267fba8370a062817cdf506119e0c5cc69900709195a2288322de578af491698360ad1f6b34b341e10eb21e22f6c5a6e12e26250aeb528aaa533d592b268fb22b3e77ada84d478ee9d0f2742cbb54be14503c21e39efcc73774b24bf28747203c5ff456457139fec8a46c8243b4b9738c27972e6d8f0ef9fa18944aaeed4deb437522f04795ecd7bee79f0a6d7c6c6acd90dac9a935d5f252134cd4ca1e2e0c4386fdae67950f1234cda5472e61a32bf9f037c068fe81a955d1e56a92ad1a8f16e6a31bfc0f8b3cef96410a72b92a75b09a0071ff0c0e99dd322ab7d8e4a2a2c2122af6",
+ // Output={S'{}, T, C}
+ {{{"f2a93dfda00e7654585b911e90acdc3a825f88b497f329637bb612464d928e4182f1b360db55231f255e7265b1614d8ee895cde4e5f4768f749c051b25ac261e", "6a017e1dfd3fcee547b526b048204901", "d0c6f32d192ad998d5fa04b32a872f8e"}, {"ff9b9925190d45c46e5ac9eae38da326739b3180432cf0c36cd9346699bd022c4dcb3aa2811f8ab0a2a72cfdc9e13b817d0a20cc1b03f51b8133c6d36d2c4ffa", "2e666844518d40d4a1efee952db70f36", "c0ae73b766ba40692b47a08c07265205"}, {"7e710ab0fcc90e1919c4996abac395e440e26eadf2df429defc893bfa97eedc55afa0504c9cee635bb933013d5d1fd54ddd30d5dc8fedcc5b55368837e00c085", "43d445810df84f486bdbe4d69637633f", "df6876f95d2387d8f419d018a826ffed"}}, {"0e49b626343b62d9155ffca96b076d70", "d64d402225cfc1e55c277c5827d8fea52c683693568928ad817bdb161852f9bbb6b316c78c4ef24d3b2620bd584e128e709a399a6c320ab5943816d786a0b7d81f0023b522ebac91e4fc79d9f6b3f5dcc22f17f486ef93518e2f885327ebac19daaaa3998dfdcb5880d76a196a8bba54a0b9169427d1f83abf95fcc8f63dfeb03d50d083e11c38a55d2efbe2c607648a5caa3698393faaaf339ca1d4c48cab8184ec20d8dc4ad03793ff1806b802e932c33f00fa0253bc7da8fa560b19cac163bbf26e4507642fcc39b5df28b3941fccbd30e3e00b64f471a51d7555c3d1b6655b0a6d9d33b9cd0494163591675c50ebb5a867e849a9c6ee43a177d7fe9f6aa992c817b26316054b49894f973ae166fb20f2bfc50704f610e2cc61be08e1305fa58f15b716aaacb50c98e0dba34a300a1aa4296f7826f0ad740f36eef6d18205b1118227c285acef158b4093dd541eed76a3492240be48e89fa54cad77b020631413a8b562e655289f94191bc462b71ddf0b41a034ca1c291aa4feb0148207e2ea0d5409e801dcec151b0a5a220ac43b8be70c8c92d6eb4f9c6f44bf0fd3487c5d007ba8ddd8bbbca51fb3c679ffc0a493392039f32e7272f173e71d4a2a5f001f999dd9523c79ca3e32c99260b20f1e960a830bd7ed81d891c316c8851b3470c64b7fb15d7ebdb8d09399e74f"}},
+},
+};
#include "core/crypto/relay_crypto_cgo.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
+#include "core/or/cell_st.h"
#include "test/cgo_vectors.inc"
tt_int_op(r, OP_EQ, sizeof(out)); \
} STMT_END
+#define UNHEX2(out,inp1,inp2) STMT_BEGIN { \
+ tor_free(unhex_tmp); \
+ tor_asprintf(&unhex_tmp, "%s%s", inp1, inp2); \
+ UNHEX(out, unhex_tmp); \
+ } STMT_END
+
static void
test_crypto_cgo_et_testvec(void *arg)
{
cgo_uiv_clear(&uiv2);
}
+static void
+test_crypto_cgo_fwd(void *arg)
+{
+ (void)arg;
+
+ #define N_HOPS 3
+ uint8_t key_material[N_HOPS][112]; // max.
+ cgo_crypt_t *client[N_HOPS];
+ cgo_crypt_t *relays[N_HOPS];
+
+ memset(client, 0, sizeof(client));
+ memset(relays, 0, sizeof(relays));
+
+ for (int bi = 0; bi < (int) ARRAY_LENGTH(AESBITS); ++bi) {
+ const int aesbits = AESBITS[bi];
+
+ size_t klen = cgo_key_material_len(aesbits);
+ tt_uint_op(klen, OP_LE, sizeof(key_material[0]));
+ crypto_rand((char*)&key_material, sizeof(key_material));
+ for (int i = 0; i < N_HOPS; ++i) {
+ client[i] = cgo_crypt_new(CGO_MODE_CLIENT,
+ aesbits, key_material[i], klen);
+ relays[i] = cgo_crypt_new(CGO_MODE_RELAY,
+ aesbits, key_material[i], klen);
+ }
+ for (int trial = 0; trial < 64; ++trial) {
+ int target_hop = crypto_rand_int(3);
+ cell_t cell, cell_orig;
+ uint8_t tag_client[CGO_TAG_LEN];
+ const uint8_t *tagp = NULL;
+
+ memset(&cell, 0, sizeof(cell));
+ if (crypto_rand_int(2) == 0) {
+ cell.command = CELL_RELAY;
+ } else {
+ cell.command = CELL_RELAY_EARLY;
+ }
+ crypto_rand((char*) cell.payload+CGO_TAG_LEN,
+ sizeof(cell.payload)-CGO_TAG_LEN);
+ memcpy(&cell_orig, &cell, sizeof(cell));
+
+ // First the client encrypts the cell...
+ cgo_crypt_client_originate(client[target_hop], &cell, &tagp);
+ tt_assert(tagp);
+ memcpy(tag_client, tagp, CGO_TAG_LEN);
+ for (int i = target_hop - 1; i >= 0; --i) {
+ cgo_crypt_client_forward(client[i], &cell);
+ }
+
+ // Now the relays handle the cell...
+ bool cell_recognized = false;
+ for (int i = 0; i < N_HOPS; ++i) {
+ tagp = NULL;
+ cgo_crypt_relay_forward(relays[i], &cell, &tagp);
+ if (tagp) {
+ tt_int_op(i, OP_EQ, target_hop);
+ tt_mem_op(tagp, OP_EQ, tag_client, CGO_TAG_LEN);
+ cell_recognized = true;
+ break;
+ }
+ }
+ tt_assert(cell_recognized);
+ tt_int_op(cell.command, OP_EQ, cell_orig.command);
+ tt_mem_op(cell.payload + CGO_TAG_LEN, OP_EQ,
+ cell_orig.payload + CGO_TAG_LEN,
+ sizeof(cell.payload) - CGO_TAG_LEN);
+ }
+ for (int i = 0; i < N_HOPS; ++i) {
+ cgo_crypt_free(client[i]);
+ cgo_crypt_free(relays[i]);
+ }
+ }
+
+ done:
+ for (int i = 0; i < N_HOPS; ++i) {
+ cgo_crypt_free(client[i]);
+ cgo_crypt_free(relays[i]);
+ }
+#undef N_HOPS
+}
+
+static void
+test_crypto_cgo_rev(void *arg)
+{
+ (void)arg;
+
+ #define N_HOPS 3
+ uint8_t key_material[N_HOPS][112]; // max.
+ cgo_crypt_t *client[N_HOPS];
+ cgo_crypt_t *relays[N_HOPS];
+
+ memset(client, 0, sizeof(client));
+ memset(relays, 0, sizeof(relays));
+
+ for (int bi = 0; bi < (int) ARRAY_LENGTH(AESBITS); ++bi) {
+ const int aesbits = AESBITS[bi];
+
+ size_t klen = cgo_key_material_len(aesbits);
+ tt_uint_op(klen, OP_LE, sizeof(key_material[0]));
+ crypto_rand((char*)&key_material, sizeof(key_material));
+ for (int i = 0; i < N_HOPS; ++i) {
+ client[i] = cgo_crypt_new(CGO_MODE_CLIENT,
+ aesbits, key_material[i], klen);
+ relays[i] = cgo_crypt_new(CGO_MODE_RELAY,
+ aesbits, key_material[i], klen);
+ }
+ for (int trial = 0; trial < 64; ++trial) {
+ int origin_hop = crypto_rand_int(3);
+ cell_t cell, cell_orig;
+ uint8_t tag_relay[CGO_TAG_LEN];
+ const uint8_t *tagp = NULL;
+
+ memset(&cell, 0, sizeof(cell));
+ cell.command = CELL_RELAY;
+ crypto_rand((char*) cell.payload+CGO_TAG_LEN,
+ sizeof(cell.payload)-CGO_TAG_LEN);
+ memcpy(&cell_orig, &cell, sizeof(cell));
+
+ // First the specified relay encrypts the cell...
+ cgo_crypt_relay_originate(relays[origin_hop], &cell, &tagp);
+ tt_assert(tagp);
+ memcpy(tag_relay, tagp, CGO_TAG_LEN);
+ for (int i = origin_hop - 1; i >= 0; --i) {
+ cgo_crypt_relay_backward(relays[i], &cell);
+ }
+
+ // Now the client handles the cell.
+ bool cell_recognized = false;
+ for (int i = 0; i < N_HOPS; ++i) {
+ tagp = NULL;
+ cgo_crypt_client_backward(client[i], &cell, &tagp);
+ if (tagp) {
+ tt_int_op(i, OP_EQ, origin_hop);
+ tt_mem_op(tagp, OP_EQ, tag_relay, CGO_TAG_LEN);
+ cell_recognized = true;
+ break;
+ }
+ }
+ tt_assert(cell_recognized);
+ tt_int_op(cell.command, OP_EQ, cell_orig.command);
+ tt_mem_op(cell.payload + CGO_TAG_LEN, OP_EQ,
+ cell_orig.payload + CGO_TAG_LEN,
+ sizeof(cell.payload) - CGO_TAG_LEN);
+ }
+ for (int i = 0; i < N_HOPS; ++i) {
+ cgo_crypt_free(client[i]);
+ cgo_crypt_free(relays[i]);
+ }
+ }
+
+ done:
+ for (int i = 0; i < N_HOPS; ++i) {
+ cgo_crypt_free(client[i]);
+ cgo_crypt_free(relays[i]);
+ }
+#undef N_HOPS
+}
+
+static void
+test_crypto_cgo_relay_testvec(void *arg)
+{
+ (void)arg;
+ char *unhex_tmp = NULL;
+ cgo_crypt_t *cgo = NULL;
+ for (int i = 0; i < (int)ARRAY_LENGTH(CGO_RELAY_TESTVECS); ++i) {
+ const struct cgo_relay_testvec *tv = &CGO_RELAY_TESTVECS[i];
+ const int aesbits = 128;
+ uint8_t keys[80], expect_keys[80], expect_tprime[CGO_TAG_LEN], cmd[1];
+ cell_t cell;
+ cell_t expect_cell;
+ tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits));
+ UNHEX2(keys, tv->state_in.keys, tv->state_in.nonce);
+ cgo = cgo_crypt_new(CGO_MODE_RELAY, aesbits, keys, sizeof(keys));
+ tt_assert(cgo);
+ UNHEX(cgo->tprime, tv->state_in.tprime);
+ memset(&cell, 0, sizeof(cell));
+ UNHEX(cmd, tv->cmd);
+ cell.command = cmd[0];
+ UNHEX2(cell.payload, tv->tag, tv->msg);
+
+ memset(&expect_cell, 0, sizeof(expect_cell));
+ expect_cell.command = cell.command;
+ UNHEX2(expect_cell.payload,
+ tv->output.result.t_out, tv->output.result.msg_out);
+ UNHEX2(expect_keys,
+ tv->output.state.keys, tv->output.state.nonce);
+ UNHEX(expect_tprime, tv->output.state.tprime);
+
+ if (tv->inbound) {
+ cgo_crypt_relay_backward(cgo, &cell);
+ } else {
+ const uint8_t *tagp = NULL;
+ cgo_crypt_relay_forward(cgo, &cell, &tagp);
+ tt_ptr_op(tagp, OP_EQ, NULL);
+ }
+
+ tt_mem_op(cell.payload, OP_EQ, expect_cell.payload, sizeof(cell.payload));
+ tt_mem_op(cgo->uiv.uiv_keys_, OP_EQ, expect_keys, 64);
+ tt_mem_op(cgo->nonce, OP_EQ, expect_keys + 64, 16);
+ tt_mem_op(cgo->tprime, OP_EQ, expect_tprime, 16);
+
+ cgo_crypt_free(cgo);
+ }
+ done:
+ tor_free(unhex_tmp);
+ cgo_crypt_free(cgo);
+}
+
+static void
+test_crypto_cgo_relay_originate_testvec(void *arg)
+{
+ (void)arg;
+ char *unhex_tmp = NULL;
+ cgo_crypt_t *cgo = NULL;
+ for (int i = 0; i < (int)ARRAY_LENGTH(CGO_RELAY_ORIGINATE_TESTVECS); ++i) {
+ const struct cgo_relay_originate_testvec *tv =
+ &CGO_RELAY_ORIGINATE_TESTVECS[i];
+ const int aesbits = 128;
+ uint8_t keys[80], expect_keys[80], expect_tprime[CGO_TAG_LEN], cmd[1];
+ cell_t cell;
+ cell_t expect_cell;
+ tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits));
+ UNHEX2(keys, tv->state_in.keys, tv->state_in.nonce);
+ cgo = cgo_crypt_new(CGO_MODE_RELAY, aesbits, keys, sizeof(keys));
+ tt_assert(cgo);
+ UNHEX(cgo->tprime, tv->state_in.tprime);
+ memset(&cell, 0, sizeof(cell));
+ UNHEX(cmd, tv->cmd);
+ cell.command = cmd[0];
+ UNHEX2(cell.payload, "00000000000000000000000000000000", tv->msg);
+
+ memset(&expect_cell, 0, sizeof(expect_cell));
+ expect_cell.command = cell.command;
+ UNHEX2(expect_cell.payload,
+ tv->output.result.t_out, tv->output.result.msg_out);
+ UNHEX2(expect_keys,
+ tv->output.state.keys, tv->output.state.nonce);
+ UNHEX(expect_tprime, tv->output.state.tprime);
+
+ const uint8_t *tagp = NULL;
+ cgo_crypt_relay_originate(cgo, &cell, &tagp);
+ tt_ptr_op(tagp, OP_NE, NULL);
+
+ tt_mem_op(cell.payload, OP_EQ, expect_cell.payload, sizeof(cell.payload));
+ tt_mem_op(cgo->uiv.uiv_keys_, OP_EQ, expect_keys, 64);
+ tt_mem_op(cgo->nonce, OP_EQ, expect_keys + 64, 16);
+ tt_mem_op(cgo->tprime, OP_EQ, expect_tprime, 16);
+
+ cgo_crypt_free(cgo);
+ }
+ done:
+ tor_free(unhex_tmp);
+ cgo_crypt_free(cgo);
+}
+
+static void
+test_crypto_cgo_client_originate_testvec(void *arg)
+{
+ (void) arg;
+ char *unhex_tmp = NULL;
+ cgo_crypt_t *cgo[3] = { NULL, NULL, NULL };
+ for (int tv_i = 0; tv_i < (int)ARRAY_LENGTH(CGO_CLIENT_ORIGINATE_TESTVECS);
+ ++tv_i) {
+ const struct cgo_client_originate_testvec *tv =
+ &CGO_CLIENT_ORIGINATE_TESTVECS[tv_i];
+ const int aesbits = 128;
+ uint8_t keys[80], expect_keys[80], expect_tprime[CGO_TAG_LEN], cmd[1];
+ cell_t cell;
+ cell_t expect_cell;
+ for (int i = 0; i < 3; ++i) {
+ tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits));
+ UNHEX2(keys, tv->state_in[i].keys, tv->state_in[i].nonce);
+ cgo[i] = cgo_crypt_new(CGO_MODE_CLIENT, aesbits, keys, sizeof(keys));
+ tt_assert(cgo[i]);
+ UNHEX(cgo[i]->tprime, tv->state_in[i].tprime);
+ }
+
+ memset(&cell, 0, sizeof(cell));
+ UNHEX(cmd, tv->cmd);
+ cell.command = cmd[0];
+ UNHEX2(cell.payload, "00000000000000000000000000000000", tv->msg);
+
+ memset(&expect_cell, 0, sizeof(expect_cell));
+ expect_cell.command = cell.command;
+ UNHEX2(expect_cell.payload,
+ tv->output.result.t_out, tv->output.result.msg_out);
+
+ tt_int_op(tv->target_hop, OP_GE, 1); // Hop is 0-indexed.
+ int target_hop = tv->target_hop - 1;
+ const uint8_t *tagp = NULL;
+ cgo_crypt_client_originate(cgo[target_hop], &cell, &tagp);
+ tt_ptr_op(tagp, OP_NE, NULL);
+ for (int i = target_hop - 1; i >= 0; --i) {
+ cgo_crypt_client_forward(cgo[i], &cell);
+ }
+ tt_mem_op(cell.payload, OP_EQ, expect_cell.payload, sizeof(cell.payload));
+
+ for (int i = 0; i < 3; ++i) {
+ UNHEX2(expect_keys,
+ tv->output.state[i].keys, tv->output.state[i].nonce);
+ UNHEX(expect_tprime, tv->output.state[i].tprime);
+
+ tt_mem_op(cgo[i]->uiv.uiv_keys_, OP_EQ, expect_keys, 64);
+ tt_mem_op(cgo[i]->nonce, OP_EQ, expect_keys + 64, 16);
+ tt_mem_op(cgo[i]->tprime, OP_EQ, expect_tprime, 16);
+ }
+
+ for (int i = 0; i < 3; ++i)
+ cgo_crypt_free(cgo[i]);
+ }
+ done:
+ tor_free(unhex_tmp);
+ for (int i = 0; i < 3; ++i)
+ cgo_crypt_free(cgo[i]);
+}
+
struct testcase_t crypto_cgo_tests[] = {
{ "et_roundtrip", test_crypto_cgo_et_roundtrip, 0, NULL, NULL },
{ "et_testvec", test_crypto_cgo_et_testvec, 0, NULL, NULL },
{ "uiv_roundtrip", test_crypto_cgo_uiv_roundtrip, 0, NULL, NULL },
{ "uiv_testvec", test_crypto_cgo_uiv_testvec, 0, NULL, NULL },
{ "uiv_update_testvec", test_crypto_cgo_uiv_update_testvec, 0, NULL, NULL },
+ { "cgo_fwd", test_crypto_cgo_fwd, 0, NULL, NULL, },
+ { "cgo_rev", test_crypto_cgo_rev, 0, NULL, NULL, },
+ { "cgo_relay_testvec", test_crypto_cgo_relay_testvec, 0, NULL, NULL },
+ { "cgo_relay_originate_testvec", test_crypto_cgo_relay_originate_testvec,
+ 0, NULL, NULL },
+ { "cgo_client_originate_testvec", test_crypto_cgo_client_originate_testvec,
+ 0, NULL, NULL },
END_OF_TESTCASES
};