add aesecb api
diff --git a/lib/fusion.c b/lib/fusion.c
index 936d726..ec0bc06 100644
--- a/lib/fusion.c
+++ b/lib/fusion.c
@@ -46,7 +46,7 @@
 #include "picotls/fusion.h"
 
 struct ptls_fusion_aesgcm_context {
-    __m128i keys[PTLS_FUSION_AESGCM_ROUNDS + 1];
+    ptls_fusion_aesecb_context_t ecb;
     size_t ghash_cnt;
     struct ptls_fusion_aesgcm_ghash_precompute {
         __m128i H;
@@ -168,7 +168,7 @@
             bits5 = ek0;                                                                                                           \
             state |= STATE_EK0_BEEN_FED;                                                                                           \
         }                                                                                                                          \
-        __m128i k = ctx->keys[0];                                                                                                  \
+        __m128i k = ctx->ecb.keys[0];                                                                                              \
         bits0 = _mm_xor_si128(bits0, k);                                                                                           \
         bits1 = _mm_xor_si128(bits1, k);                                                                                           \
         bits2 = _mm_xor_si128(bits2, k);                                                                                           \
@@ -180,7 +180,7 @@
 /* aes block update */
 #define AESECB6_UPDATE(i)                                                                                                          \
     do {                                                                                                                           \
-        __m128i k = ctx->keys[i];                                                                                                  \
+        __m128i k = ctx->ecb.keys[i];                                                                                              \
         bits0 = _mm_aesenc_si128(bits0, k);                                                                                        \
         bits1 = _mm_aesenc_si128(bits1, k);                                                                                        \
         bits2 = _mm_aesenc_si128(bits2, k);                                                                                        \
@@ -192,7 +192,7 @@
 /* aesenclast */
 #define AESECB6_FINAL()                                                                                                            \
     do {                                                                                                                           \
-        __m128i k = ctx->keys[10];                                                                                                 \
+        __m128i k = ctx->ecb.keys[10];                                                                                             \
         bits0 = _mm_aesenclast_si128(bits0, k);                                                                                    \
         bits1 = _mm_aesenclast_si128(bits1, k);                                                                                    \
         bits2 = _mm_aesenclast_si128(bits2, k);                                                                                    \
@@ -393,7 +393,35 @@
     return _mm_xor_si128(key, t);
 }
 
-ptls_fusion_aesgcm_context_t *ptls_fusion_aesgcm_create(const void *userkey, size_t max_size)
+void ptls_fusion_aesecb_init(ptls_fusion_aesecb_context_t *ctx, const void *key)
+{
+    size_t i = 0;
+
+    ctx->keys[i++] = _mm_loadu_si128((__m128i *)key);
+#define EXPAND(R)                                                                                                                  \
+    do {                                                                                                                           \
+        ctx->keys[i] = expand_key(ctx->keys[i - 1], _mm_aeskeygenassist_si128(ctx->keys[i - 1], R));                               \
+        ++i;                                                                                                                       \
+    } while (0)
+    EXPAND(0x1);
+    EXPAND(0x2);
+    EXPAND(0x4);
+    EXPAND(0x8);
+    EXPAND(0x10);
+    EXPAND(0x20);
+    EXPAND(0x40);
+    EXPAND(0x80);
+    EXPAND(0x1b);
+    EXPAND(0x36);
+#undef EXPAND
+}
+
+void ptls_fusion_aesecb_dispose(ptls_fusion_aesecb_context_t *ctx)
+{
+    ptls_clear_memory(ctx, sizeof(*ctx));
+}
+
+ptls_fusion_aesgcm_context_t *ptls_fusion_aesgcm_create(const void *key, size_t max_size)
 {
     ptls_fusion_aesgcm_context_t *ctx;
     size_t ghash_cnt = (max_size + 15) / 16 + 1; // round-up by block size, plus context to hash AC
@@ -401,32 +429,13 @@
     if ((ctx = malloc(sizeof(*ctx) + sizeof(ctx->ghash[0]) * ghash_cnt)) == NULL)
         return NULL;
 
-    {
-        size_t i = 0;
-        ctx->keys[i++] = _mm_loadu_si128((__m128i *)userkey);
-#define EXPAND(R)                                                                                                                  \
-    do {                                                                                                                           \
-        ctx->keys[i] = expand_key(ctx->keys[i - 1], _mm_aeskeygenassist_si128(ctx->keys[i - 1], R));                               \
-        ++i;                                                                                                                       \
-    } while (0)
-        EXPAND(0x1);
-        EXPAND(0x2);
-        EXPAND(0x4);
-        EXPAND(0x8);
-        EXPAND(0x10);
-        EXPAND(0x20);
-        EXPAND(0x40);
-        EXPAND(0x80);
-        EXPAND(0x1b);
-        EXPAND(0x36);
-#undef EXPAND
-    }
+    ptls_fusion_aesecb_init(&ctx->ecb, key);
 
     ctx->ghash_cnt = ghash_cnt;
-    ctx->ghash[0].H = ctx->keys[0];
+    ctx->ghash[0].H = ctx->ecb.keys[0];
     for (size_t i = 1; i < PTLS_FUSION_AESGCM_ROUNDS; ++i)
-        ctx->ghash[0].H = _mm_aesenc_si128(ctx->ghash[0].H, ctx->keys[i]);
-    ctx->ghash[0].H = _mm_aesenclast_si128(ctx->ghash[0].H, ctx->keys[PTLS_FUSION_AESGCM_ROUNDS]);
+        ctx->ghash[0].H = _mm_aesenc_si128(ctx->ghash[0].H, ctx->ecb.keys[i]);
+    ctx->ghash[0].H = _mm_aesenclast_si128(ctx->ghash[0].H, ctx->ecb.keys[PTLS_FUSION_AESGCM_ROUNDS]);
     ctx->ghash[0].H = _mm_shuffle_epi8(ctx->ghash[0].H, bswap8);
 
     ctx->ghash[0].H = transformH(ctx->ghash[0].H);
@@ -443,7 +452,9 @@
 
 void ptls_fusion_aesgcm_destroy(ptls_fusion_aesgcm_context_t *ctx)
 {
-    ptls_clear_memory(ctx, sizeof(*ctx) + sizeof(ctx->ghash[0]) * ctx->ghash_cnt);
+    ptls_clear_memory(ctx->ghash, sizeof(ctx->ghash[0]) * ctx->ghash_cnt);
+    ctx->ghash_cnt = 0;
+    ptls_fusion_aesecb_dispose(&ctx->ecb);
     free(ctx);
 }