Prechádzať zdrojové kódy

A PRG variant for computing (wide) leaves

Ian Goldberg 1 rok pred
rodič
commit
6496353c33
2 zmenil súbory, kde vykonal 85 pridanie a 14 odobranie
  1. 76 9
      prg.hpp
  2. 9 5
      rdpf.tcc

+ 76 - 9
prg.hpp

@@ -1,15 +1,27 @@
 #ifndef __PRG_HPP__
 #define __PRG_HPP__
 
+#include <array>
+
 #include "bitutils.hpp"
 #include "aes.hpp"
 
 static const struct PRGkey {
     AESkey k;
-    PRGkey(__m128i key = _mm_set_epi64x(314159265, 271828182)) {
+    PRGkey(__m128i key) {
         AES_128_Key_Expansion(k, key);
     }
-} prgkey;
+}
+// Digits of e
+prgkey(
+    _mm_set_epi64x(2718281828459045235ULL, 3602874713526624977ULL)
+),
+// Digits of pi
+leafprgkeys[3] = {
+    _mm_set_epi64x(3141592653589793238ULL, 4626433832795028841ULL),
+    _mm_set_epi64x(9716939937510582097ULL, 4944592307816406286ULL),
+    _mm_set_epi64x(2089986280348253421ULL, 1706798214808651328ULL)
+};
 
 // Compute one of the children of node seed; whichchild=0 for
 // the left child, 1 for the right child
@@ -26,13 +38,68 @@ static inline void prg(__m128i &out, __m128i seed, bool whichchild,
 static inline void prgboth(__m128i &left, __m128i &right, __m128i seed,
     size_t &aes_ops)
 {
-    __m128i in0 = set_lsb(seed, 0);
-    __m128i in1 = set_lsb(seed, 1);
-    __m128i mid0, mid1;
-    AES_ECB_encrypt(mid0, set_lsb(seed, 0), prgkey.k, aes_ops);
-    AES_ECB_encrypt(mid1, set_lsb(seed, 1), prgkey.k, aes_ops);
-    left = mid0 ^ in0;
-    right = mid1 ^ in1;
+    __m128i inl = set_lsb(seed, 0);
+    __m128i inr = set_lsb(seed, 1);
+    __m128i midl, midr;
+    AES_ECB_encrypt(midl, inl, prgkey.k, aes_ops);
+    AES_ECB_encrypt(midr, inr, prgkey.k, aes_ops);
+    left = midl ^ inl;
+    right = midr ^ inr;
+}
+
+// Compute one of the leaf children of node seed; whichchild=0 for
+// the left child, 1 for the right child
+template <size_t LWIDTH>
+static inline void prgleaf(std::array<__m128i,LWIDTH> &out,
+    __m128i seed, bool whichchild, size_t &aes_ops)
+{
+    __m128i in = set_lsb(seed, whichchild);
+    __m128i mid0, mid1, mid2;
+    AES_ECB_encrypt(mid0, set_lsb(seed, whichchild), leafprgkeys[0].k, aes_ops);
+    if (LWIDTH > 1) {
+        AES_ECB_encrypt(mid1, set_lsb(seed, whichchild), leafprgkeys[1].k, aes_ops);
+    }
+    if (LWIDTH > 2) {
+        AES_ECB_encrypt(mid2, set_lsb(seed, whichchild), leafprgkeys[2].k, aes_ops);
+    }
+    out[0] = mid0 ^ in;
+    if (LWIDTH > 1) {
+        out[1] = mid1 ^ in;
+    }
+    if (LWIDTH > 2) {
+        out[2] = mid2 ^ in;
+    }
+}
+
+// Compute both of the leaf children of node seed
+template <size_t LWIDTH>
+static inline void prgleafboth(std::array<__m128i,LWIDTH> &left,
+    std::array<__m128i,LWIDTH> &right, __m128i seed, size_t &aes_ops)
+{
+    __m128i inl = set_lsb(seed, 0);
+    __m128i inr = set_lsb(seed, 1);
+    __m128i midl0, midl1, midl2;
+    __m128i midr0, midr1, midr2;
+    AES_ECB_encrypt(midl0, inl, leafprgkeys[0].k, aes_ops);
+    AES_ECB_encrypt(midr0, inr, leafprgkeys[0].k, aes_ops);
+    if (LWIDTH > 1) {
+        AES_ECB_encrypt(midl1, inl, leafprgkeys[1].k, aes_ops);
+        AES_ECB_encrypt(midr1, inr, leafprgkeys[1].k, aes_ops);
+    }
+    if (LWIDTH > 2) {
+        AES_ECB_encrypt(midl2, inl, leafprgkeys[2].k, aes_ops);
+        AES_ECB_encrypt(midr2, inr, leafprgkeys[2].k, aes_ops);
+    }
+    left[0] = midl0 ^ inl;
+    right[0] = midr0 ^ inr;
+    if (LWIDTH > 1) {
+        left[1] = midl1 ^ inl;
+        right[1] = midr1 ^ inr;
+    }
+    if (LWIDTH > 2) {
+        left[2] = midl2 ^ inl;
+        right[2] = midr2 ^ inr;
+    }
 }
 
 #endif

+ 9 - 5
rdpf.tcc

@@ -191,12 +191,16 @@ inline typename RDPF<WIDTH>::LeafNode RDPF<WIDTH>::descend_to_leaf(
 {
     typename RDPF<WIDTH>::LeafNode prgout;
     bool flag = get_lsb(parent);
-    prg(prgout[0], parent, whichchild, aes_ops);
+    prgleaf(prgout, parent, whichchild, aes_ops);
     if (flag) {
-        DPFnode CW = cw[parentdepth];
-        bit_t cfbit = !!(cfbits & (value_t(1)<<parentdepth));
-        DPFnode CWR = CW ^ lsb128_mask[cfbit];
-        prgout[0] ^= (whichchild ? CWR : CW);
+        LeafNode CW = li[0].leaf_cw;
+        LeafNode CWR = CW;
+        for (nbits_t j=0;j<LWIDTH;++j) {
+            bit_t cfbit = !!(leaf_cfbits[j] &
+                (value_t(1)<<(depth()-parentdepth)));
+            CWR[j] ^= lsb128_mask[cfbit];
+        }
+        prgout ^= (whichchild ? CWR : CW);
     }
     return prgout;
 }