commit 3aa29c52b6a4dba599ab75310f3c639874e7f22a
parent 568004d863978acfeb2880deca980ec5f96547c5
Author: Nick Mathewson <nickm@torproject.org>
Date: Sun, 20 Apr 2025 10:37:38 -0400
Polyval: add ability to store key separately.
This will help reduce storage, since we never actually need
to keep a running total outside of a function.
Diffstat:
5 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/src/ext/polyval/ctmul.c b/src/ext/polyval/ctmul.c
@@ -197,7 +197,7 @@ static void
pv_mul_y_h(polyval_t *pv)
{
uint32_t *yw = pv->y.v;
- const uint32_t *hw = pv->h.v;
+ const uint32_t *hw = pv->key.h.v;
/*
* Throughout the loop we handle the y and h values as arrays
diff --git a/src/ext/polyval/ctmul64.c b/src/ext/polyval/ctmul64.c
@@ -80,11 +80,11 @@ pv_mul_y_h(polyval_t *pv)
y0 = pv->y.lo;
y1 = pv->y.hi;
- h0 = pv->h.lo;
- h1 = pv->h.hi;
+ h0 = pv->key.h.lo;
+ h1 = pv->key.h.hi;
// TODO(nm) does it actually make sense for us to precompute this?
- h0r = pv->hr.lo;
- h1r = pv->hr.hi;
+ h0r = pv->key.hr.lo;
+ h1r = pv->key.hr.hi;
h2 = h0 ^ h1;
h2r = h0r ^ h1r;
diff --git a/src/ext/polyval/pclmul.c b/src/ext/polyval/pclmul.c
@@ -156,7 +156,7 @@ void pv_mul_y_h(polyval_t *pv)
{
__m128i yw, h1w, h1x;
- h1w = pv->h;
+ h1w = pv->key.h;
BK(h1w, h1x);
{
diff --git a/src/ext/polyval/polyval.c b/src/ext/polyval/polyval.c
@@ -66,7 +66,7 @@ static inline void pv_xor_y(polyval_t *, u128 v);
/**
* Initialize any derived fields in pv.
*/
-static inline void pv_init_extra(polyval_t *pv);
+static inline void pv_init_extra(polyval_key_t *pv);
/* ========
* The function which we expect our backend to implement.
@@ -140,7 +140,7 @@ pv_xor_y(polyval_t *pv, u128 v)
pv->y = _mm_xor_si128(pv->y, v);
}
static inline void
-pv_init_extra(polyval_t *pv)
+pv_init_extra(polyval_key_t *pv)
{
(void)pv;
}
@@ -173,7 +173,7 @@ pv_xor_y(polyval_t *pv, u128 val)
pv->y.hi ^= val.hi;
}
static inline void
-pv_init_extra(polyval_t *pv)
+pv_init_extra(polyval_key_t *pv)
{
pv->hr.lo = rev64(pv->h.lo);
pv->hr.hi = rev64(pv->h.hi);
@@ -208,18 +208,29 @@ pv_xor_y(polyval_t *pv, u128 val)
}
}
static inline void
-pv_init_extra(polyval_t *pv)
+pv_init_extra(polyval_key_t *pv)
{
(void)pv;
}
#endif
void
+polyval_key_init(polyval_key_t *pvk, const uint8_t *key)
+{
+ pvk->h = u128_from_bytes(key);
+ pv_init_extra(pvk);
+}
+void
polyval_init(polyval_t *pv, const uint8_t *key)
{
- pv->h = u128_from_bytes(key);
+ polyval_key_init(&pv->key, key);
+ memset(&pv->y, 0, sizeof(u128));
+}
+void
+polyval_init_from_key(polyval_t *pv, const polyval_key_t *key)
+{
+ memcpy(&pv->key, key, sizeof(polyval_key_t));
memset(&pv->y, 0, sizeof(u128));
- pv_init_extra(pv);
}
void
polyval_add_block(polyval_t *pv, const uint8_t *block)
diff --git a/src/ext/polyval/polyval.h b/src/ext/polyval/polyval.h
@@ -54,17 +54,22 @@ typedef struct pv_u128_ {
} pv_u128_;
#endif
-/**
- * State for an instance of the polyval hash.
- **/
-typedef struct polyval_t {
- /** The key itself. */
+/** A key for a polyval hash, plus any precomputed key material. */
+typedef struct polyval_key_t {
pv_u128_ h;
#ifdef PV_USE_CTMUL64
/** The elements of the key in bit-reversed form.
* (Used as an optimization.) */
pv_u128_ hr;
#endif
+} polyval_key_t;
+
+/**
+ * State for an instance of the polyval hash.
+ **/
+typedef struct polyval_t {
+ /** The key used for this instance of polyval. */
+ polyval_key_t key;
/** The accumulator */
pv_u128_ y;
} polyval_t;
@@ -82,11 +87,19 @@ typedef struct polyval_t {
*/
#define POLYVAL_TAG_LEN 16
+/** Do any necessary precomputation from a polyval key,
+ * and store it.
+ */
+void polyval_key_init(polyval_key_t *, const uint8_t *key);
/**
* Initialize a polyval instance with a given key.
*/
void polyval_init(polyval_t *, const uint8_t *key);
/**
+ * Initialize a polyval instance with a preconstructed key.
+ */
+void polyval_init_from_key(polyval_t *, const polyval_key_t *key);
+/**
* Update a polyval instance with a new 16-byte block.
*/
void polyval_add_block(polyval_t *, const uint8_t *block);