Browse Source

Adding lookup tables function.

Michele Orrù 7 years ago
parent
commit
5770571d8e
6 changed files with 153 additions and 42 deletions
  1. 0 5
      configure.ac
  2. 136 24
      src/ddlog.c
  3. 5 3
      src/ddlog.h
  4. 1 1
      src/group.h
  5. 11 8
      src/mul_bench.c
  6. 0 1
      src/rms.c

+ 0 - 5
configure.ac

@@ -55,10 +55,6 @@ AC_ARG_ENABLE(debug,
    CFLAGS+=" -DNDEBUG -O3 -march=native")
 
 
-AC_ARG_VAR([failure], [failure prob.])
-AS_IF([test "x$failure" = x], [failure="17"])
-
-
 AC_ARG_VAR([failure], [failure prob.])
 AS_IF([test "x$failure" = x], [failure="17"])
 AC_DEFINE_UNQUOTED([FAILURE], [$failure], [log inverse of the failure probability, default: 17.])
@@ -67,7 +63,6 @@ AC_ARG_VAR([fb_base], [fixed base])
 AS_IF([test "x$fb_base" = x], [fb_base="8"])
 AC_DEFINE_UNQUOTED([FB_BASE], [$fb_base], [log of precomputed base for group operation, default: 8.])
 
-
 AC_ARG_VAR([ss_base], [ss base])
 AS_IF([test "x$ss_base" = x], [ss_base="1"])
 AC_DEFINE_UNQUOTED([SS_BASE], [$ss_base], [log of secret shares representation, default: 1.])

+ 136 - 24
src/ddlog.c

@@ -9,12 +9,12 @@
 #include "group.h"
 #include "hss.h"
 
-uint64_t lookup[0x01 << strip_size];
-uint64_t offset[0x01 << strip_size];
+uint64_t lookup[0x01 << halfstrip_size];
+uint64_t offset[0x01 << halfstrip_size];
 
 static const uint64_t topmask = ~(ULLONG_MAX >> halfstrip_size);
-//static const uint64_t topbigmask = ~(ULLONG_MAX >> strip_size);
-static const uint64_t bottommask = (0x01  << halfstrip_size) -1;
+static const uint64_t bottommask = (0x01  << halfstrip_size) - 1;
+static const uint64_t topbigmask = ~(ULLONG_MAX >> strip_size);
 
 static const uint64_t failuremask = ~(ULLONG_MAX >> FAILURE);
 #define distinguished_limb 0x8000000000000000
@@ -35,49 +35,89 @@ void add_1(uint64_t *b, const size_t start, const size_t len, uint64_t a)
 }
 
 
-#define zdistinguished(x) (((x)[head] & topbigmask)) == 0
 
-uint32_t __attribute__((optimize("unroll-loops"))) convert(uint64_t * nn)
+#define offset_xy_l (64 % halfstrip_size)
+#define offset_xy_r (halfstrip_size - offset_xy_l)
+#define mask_xy_l   ((0x01 << offset_xy_l) - 1)
+#define mask_xy_r   (~(ULLONG_MAX >> offset_xy_r))
+#define strip_xy    (((x & mask_xy_l) << offset_xy_r) | (y >> (64 - offset_xy_r)))
+#define offset_yz_l ((64 - offset_xy_r) % halfstrip_size)
+#define offset_yz_r (halfstrip_size - offset_yz_l)
+#define mask_yz_l   ((0x01 << offset_yz_l) - 1)
+#define strip_yz    (((y & mask_yz_l) << offset_yz_r) | (z >> (64 - offset_yz_r)))
+
+#define next_head      ((head + 23) % 24)
+#define next_next_head ((head + 23*2) % 24)
+#define tail           ((head + 1)  % 24)
+#define next_tail      ((head + 2)  % 24)
+
+
+uint32_t __attribute__((optimize("unroll-loops"))) convert_lookup(uint64_t * nn)
 {
   uint32_t steps;
   size_t head = 23;
-#define next_head  ((head + 23) % 24)
-#define tail       ((head + 1)  % 24)
-#define next_tail  ((head + 2)  % 24)
+  uint32_t w2;
 
   /** Check the most significant block */
   const uint64_t x = nn[head];
-  for (uint32_t w2 = clz(x) + halfstrip_size - (clz(x) % halfstrip_size);
-       w2 < 64 - halfstrip_size;
+  for (w2 = clz(x) + halfstrip_size - (clz(x) % halfstrip_size);
+       w2 < 64 - offset_xy_l - halfstrip_size;
        w2 += halfstrip_size) {
     if (!(x & (topmask >> w2))) {
       const size_t previous = (x >> (64 - halfstrip_size - w2 + halfstrip_size)) & bottommask;
       const uint32_t next   = (x >> (64 - halfstrip_size - w2 - halfstrip_size)) & bottommask;
-      if (next <= lookup[previous]) return w2 - offset[previous] - 1;
+      if (next <= lookup[previous]) {
+        return w2 - offset[previous] - 1;
+      }
     }
   }
 
   for (steps = 64; true; steps += 64) {
     const uint64_t x = nn[head];
     const uint64_t y = nn[next_head];
+    const uint64_t z = nn[next_next_head];
+
+    if (!((x >> offset_xy_l) & bottommask)) {
+      const size_t previous = (x >> (halfstrip_size + offset_xy_l)) & bottommask;
+      const uint64_t next   =  strip_xy;
+      if (next <= lookup[previous]) {
+        return steps - offset_xy_l - halfstrip_size - offset[previous] - 1;
+      }
+    }
 
-    if (!(x & bottommask)) {
-      const size_t previous = (x >> halfstrip_size) & bottommask;
-      const uint32_t next   =  y >> (64 - halfstrip_size);
-      if (next <= lookup[previous]) return steps - halfstrip_size - offset[previous] - 1;
+    if (!strip_xy) {
+      const size_t previous = (x >> offset_xy_l) & bottommask;
+      const uint64_t next   = ((y << offset_xy_r) >> (64 - halfstrip_size));
+      if (next <= lookup[previous]) {
+        return steps - offset_xy_l - offset[previous] - 1;
+      }
     }
 
-    if (!(y & topmask)) {
-      const size_t previous =  x & bottommask;
-      const uint32_t next   = (y >> (64 - 2*halfstrip_size)) & bottommask;
-      if (next <= lookup[previous]) return steps - offset[previous] - 1;
+    if (!((y << offset_xy_r) & topmask)) {
+      const size_t previous = strip_xy;
+      const uint64_t next   = ((y << (offset_xy_r + halfstrip_size)) >> (64 - halfstrip_size));
+      if (next <= lookup[previous]) {
+        return steps + offset_xy_r - offset[previous] - 1;
+      }
     }
 
-    for (uint32_t w2 = halfstrip_size; w2 < 64-halfstrip_size; w2 += halfstrip_size) {
+    for (w2 = halfstrip_size + offset_xy_r;
+         w2 < 64 - halfstrip_size - offset_yz_l;
+         w2 += halfstrip_size) {
       if (!(y & (topmask >> w2))) {
         const size_t previous = (y >> (64 - halfstrip_size - w2 + halfstrip_size)) & bottommask;
-        const uint32_t next   = (y >> (64 - halfstrip_size - w2 - halfstrip_size)) & bottommask;
-        if (next <= lookup[previous]) return steps + w2 - offset[previous] - 1;
+        const uint64_t next   = (y >> (64 - halfstrip_size - w2 - halfstrip_size)) & bottommask;
+        if (next <= lookup[previous]) {
+          return steps + w2 - offset[previous] - 1;
+        }
+      }
+    }
+
+    if (!(y & (topmask >> w2))) {
+      const size_t previous = (y >> (64 - halfstrip_size - w2 + halfstrip_size)) & bottommask;
+      const uint64_t next   = strip_yz;
+      if (next <= lookup[previous]) {
+        return steps + w2 - offset[previous] - 1;
       }
     }
 
@@ -91,7 +131,6 @@ uint32_t __attribute__((optimize("unroll-loops"))) convert(uint64_t * nn)
     nn[tail] = al;
     add_1(nn, next_tail, 24, ah);
   }
-
 }
 
 bool distinguished(mpz_t n)
@@ -111,6 +150,79 @@ uint32_t naif_convert(mpz_t n)
 }
 
 
+uint32_t __attribute__((optimize("unroll-loops"))) convert_ec17(uint64_t * nn)
+{
+  uint32_t steps;
+  size_t head = 23;
+  uint32_t w, w2;
+
+  /** Check the most significant block */
+  const uint64_t x = nn[head];
+  for (w2 = clz(x) + halfstrip_size - (clz(x) % halfstrip_size);
+       w2 < 64 - offset_xy_l - halfstrip_size;
+       w2 += halfstrip_size) {
+    if (!(x & (topmask >> w2))) {
+        for (w = w2-1; !(x & (topmask >> w)); w--);
+        ++w;
+        if (!(x & (topbigmask >> w)))  return w - 1;
+    }
+  }
+
+  for (steps = 64; true; steps += 64) {
+    const uint64_t x = nn[head];
+    const uint64_t y = nn[next_head];
+    const uint64_t z = nn[next_next_head];
+
+    if (!((x >> offset_xy_l) & bottommask)) {
+      for (w=0; !(x >> (halfstrip_size + offset_xy_l + w) & 1); w++);
+      if (!(strip_xy >> w)) {
+        return steps - offset_xy_l - halfstrip_size - w - 1;
+      }
+    }
+
+    if (!strip_xy) {
+      for (w = 0; !((x >> (offset_xy_l + w)) & 1); w++);
+      if (!(y << offset_xy_r & (topmask << w)))
+        return steps - offset_xy_l - w - 1;
+    }
+
+    if (!((y << offset_xy_r) & topmask)) {
+      for (w = 0; !((strip_xy >> w) & 1); w++);
+      if (!((y << (offset_xy_r + halfstrip_size)) & (topmask << w)))
+        return steps + offset_xy_r - w - 1;
+    }
+
+    for (w2 = halfstrip_size + offset_xy_r;
+         w2 < 64 - halfstrip_size - offset_yz_l;
+         w2 += halfstrip_size) {
+      if (!(y & (topmask >> w2))) {
+        for (w = w2-1; !(y & (topmask >> w)); w--);
+        ++w;
+        if (!(y & (topbigmask >> w)))  return steps + w - 1;
+      }
+    }
+
+    if (!(y & (topmask >> w2))) {
+      for (w = w2-1; !(y & (topmask >> w)); w--);
+      w++;
+      if (!(strip_yz >> (w2 - w))) {
+        return steps + w - 1;
+      }
+    }
+
+    /**
+     * We found no distinguished point.
+     */
+    const uint128_t a = (uint128_t) x * gg;
+    const uint64_t al = (uint64_t) a;
+    const uint64_t ah = (a >> 64);
+    head = next_head;
+    nn[tail] = al;
+    add_1(nn, next_tail, 24, ah);
+  }
+
+}
+
 void dlog_precompute()
 {
   for (size_t i = 0; i <= bottommask; i++) {

+ 5 - 3
src/ddlog.h

@@ -9,11 +9,13 @@
 #define strip_size (FAILURE - 1)
 #define halfstrip_size ((strip_size)/2)
 
-extern uint64_t lookup[0x01 << strip_size];
-extern uint64_t offset[0x01 << strip_size];
+extern uint64_t lookup[0x01 << halfstrip_size];
+extern uint64_t offset[0x01 << halfstrip_size];
 
+#define convert convert_ec17
 
-uint32_t convert(uint64_t *nn);
+uint32_t convert_lookup(uint64_t *nn);
+uint32_t convert_ec17(uint64_t *nn);
 uint32_t naif_convert(mpz_t n);
 bool distinguished(mpz_t n);
 

+ 1 - 1
src/group.h

@@ -79,7 +79,7 @@ void mul_modp(mpz_t rop, mpz_t op1, mpz_t op2);
 #define mpz_mul_modp(rop, op1, op2)             \
   do {                                          \
     mpz_mul(rop, op1, op2);                     \
-    remp(rop);                                  \
+    remp(rop);                       \
   } while (0)
 
 #define mpz_mul_ui_modp(rop, op1, op2)          \

+ 11 - 8
src/mul_bench.c

@@ -14,17 +14,20 @@ int main()
   mpz_t test, expected, x, y;
   mpz_inits(test, expected, x, y, NULL);
 
-  INIT_TIMEIT(CLOCK_PROCESS_CPUTIME_ID);
-  for (int i = 0; i < (int) 1e6; i++) {
-    mpz_urandomm(x, _rstate, p);
-    mpz_urandomm(y, _rstate, p);
+  printf("e6time\n");
+  for (int n = 0; n < 0x01 << 16; n++) {
+    INIT_TIMEIT(CLOCK_PROCESS_CPUTIME_ID);
 
-    START_TIMEIT();
-    mul_modp(expected, x, y);
-    END_TIMEIT();
+    for (int i = 0; i < (int) 1e6; i++) {
+      mpz_urandomm(x, _rstate, p);
+      mpz_urandomm(y, _rstate, p);
 
+      START_TIMEIT();
+      mul_modp(expected, x, y);
+      END_TIMEIT();
+    }
+    printf(TIMEIT_FORMAT "\n", GET_TIMEIT());
   }
-  printf(TIMEIT_FORMAT "\n", GET_TIMEIT());
 
   mpz_clears(test, expected, x, y, NULL);
 }

+ 0 - 1
src/rms.c

@@ -12,7 +12,6 @@
 #include "entropy.h"
 #include "group.h"
 #include "hss.h"
-#include "timeit.h"
 
 static inline
 uint32_t mul_single(const elgamal_cipher_t c,