Parcourir la source

Count AES operations

Ian Goldberg il y a 1 an
Parent
commit
0ac3de8dd2
9 fichiers modifiés avec 57 ajouts et 38 suppressions
  1. 1 1
      Makefile
  2. 3 1
      aes.hpp
  3. 7 0
      mpcio.cpp
  4. 2 0
      mpcio.hpp
  5. 5 4
      preproc.cpp
  6. 7 5
      prg.hpp
  7. 12 12
      rdpf.cpp
  8. 19 6
      rdpf.hpp
  9. 1 9
      types.hpp

+ 1 - 1
Makefile

@@ -1,6 +1,6 @@
 all: prac
 
-CXXFLAGS=-march=native -std=c++17 -Wall -ggdb
+CXXFLAGS=-march=native -std=c++17 -Wall -Wno-ignored-attributes -ggdb -O3
 LDFLAGS=-ggdb
 LDLIBS=-lbsd -lboost_system -lboost_context -lboost_chrono -lboost_thread -lpthread
 

+ 3 - 1
aes.hpp

@@ -61,7 +61,8 @@ static inline void AES_128_Key_Expansion (AESkey &key, __m128i rawkey)
     Key_Schedule[10] = temp1;
 }
 
-static inline void AES_ECB_encrypt(__m128i &ciphertext, __m128i plaintext, const AESkey &key)
+static inline void AES_ECB_encrypt(__m128i &ciphertext, __m128i plaintext,
+    const AESkey &key, size_t &op_counter)
 {
     __m128i tmp;
     int j;
@@ -72,6 +73,7 @@ static inline void AES_ECB_encrypt(__m128i &ciphertext, __m128i plaintext, const
     }
     tmp = _mm_aesenclast_si128 (tmp,key[j]);
     ciphertext=tmp;
+    ++op_counter;
 }
 
 #endif

+ 7 - 0
mpcio.cpp

@@ -179,9 +179,11 @@ void MPCIO::reset_stats()
 {
     msgs_sent.clear();
     msg_bytes_sent.clear();
+    aes_ops.clear();
     for (size_t i=0; i<num_threads; ++i) {
         msgs_sent.push_back(0);
         msg_bytes_sent.push_back(0);
+        aes_ops.push_back(0);
     }
     steady_start = boost::chrono::steady_clock::now();
     cpu_start = boost::chrono::process_cpu_clock::now();
@@ -191,12 +193,16 @@ void MPCIO::dump_stats(std::ostream &os)
 {
     size_t tot_msgs_sent = 0;
     size_t tot_msg_bytes_sent = 0;
+    size_t tot_aes_ops = 0;
     for (auto& n : msgs_sent) {
         tot_msgs_sent += n;
     }
     for (auto& n : msg_bytes_sent) {
         tot_msg_bytes_sent += n;
     }
+    for (auto& n : aes_ops) {
+        tot_aes_ops += n;
+    }
     auto steady_elapsed =
         boost::chrono::steady_clock::now() - steady_start;
     auto cpu_elapsed =
@@ -204,6 +210,7 @@ void MPCIO::dump_stats(std::ostream &os)
 
     os << tot_msgs_sent << " messages sent\n";
     os << tot_msg_bytes_sent << " message bytes sent\n";
+    os << tot_aes_ops << " local AES operations\n";
     os << lamport << " Lamport clock (latencies)\n";
     os << boost::chrono::duration_cast
         <boost::chrono::milliseconds>(steady_elapsed) <<

+ 2 - 0
mpcio.hpp

@@ -165,6 +165,7 @@ struct MPCIO {
     atomic_lamport_t lamport;
     std::vector<size_t> msgs_sent;
     std::vector<size_t> msg_bytes_sent;
+    std::vector<size_t> aes_ops;
     boost::chrono::steady_clock::time_point steady_start;
     boost::chrono::process_cpu_clock::time_point cpu_start;
 
@@ -279,6 +280,7 @@ public:
     inline int player() { return mpcio.player; }
     inline bool preprocessing() { return mpcio.preprocessing; }
     inline bool is_server() { return mpcio.player == 2; }
+    inline size_t& aes_ops() { return mpcio.aes_ops[thread_num]; }
 };
 
 // Set up the socket connections between the two computational parties

+ 5 - 4
preproc.cpp

@@ -81,8 +81,9 @@ void preprocessing_comp(MPCIO &mpcio, int num_threads, char **args)
                     for (unsigned int i=0; i<num; ++i) {
                         coroutines.emplace_back(
                             [&](yield_t &yield) {
-                                RDPF rdpf;
-                                rdpf_gen(tio, yield, rdpf, type);
+                                RegXS ri;
+                                ri.randomize();
+                                RDPF rdpf(tio, yield, ri, type);
                             });
                     }
                 }
@@ -164,8 +165,8 @@ void preprocessing_server(MPCServerIO &mpcsrvio, int num_threads, char **args)
                         for (unsigned int i=0; i<num; ++i) {
                             coroutines.emplace_back(
                                 [&](yield_t &yield) {
-                                    RDPF rdpf;
-                                    rdpf_gen(stio, yield, rdpf, depth);
+                                    RegXS ri;
+                                    RDPF rdpf(stio, yield, ri, depth);
                                 });
                         }
                     }

+ 7 - 5
prg.hpp

@@ -13,22 +13,24 @@ static const struct PRGkey {
 
 // Compute one of the children of node seed; whichchild=0 for
 // the left child, 1 for the right child
-static inline void prg(__m128i &out, __m128i seed, bool whichchild)
+static inline void prg(__m128i &out, __m128i seed, bool whichchild,
+    size_t &op_counter)
 {
     __m128i in = set_lsb(seed, whichchild);
     __m128i mid;
-    AES_ECB_encrypt(mid, set_lsb(seed, whichchild), prgkey.k);
+    AES_ECB_encrypt(mid, set_lsb(seed, whichchild), prgkey.k, op_counter);
     out = _mm_xor_si128(mid, in);
 }
 
 // Compute both children of node seed
-static inline void prgboth(__m128i &left, __m128i &right, __m128i seed)
+static inline void prgboth(__m128i &left, __m128i &right, __m128i seed,
+    size_t &op_counter)
 {
     __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_ECB_encrypt(mid1, set_lsb(seed, 1), prgkey.k);
+    AES_ECB_encrypt(mid0, set_lsb(seed, 0), prgkey.k, op_counter);
+    AES_ECB_encrypt(mid1, set_lsb(seed, 1), prgkey.k, op_counter);
     left = _mm_xor_si128(mid0, in0);
     right = _mm_xor_si128(mid1, in1);
 }

+ 12 - 12
rdpf.cpp

@@ -5,34 +5,34 @@
 #include "aes.hpp"
 #include "prg.hpp"
 
-// Construct a DPF of the given depth to be used for random-access
-// memory reads and writes.  The DPF is construction collaboratively by
-// P0 and P1, with the server P2 helping by providing various kinds of
+// Construct a DPF with the given (XOR-shared) target location, and
+// of the given depth, to be used for random-access memory reads and
+// writes.  The DPF is construction collaboratively by P0 and P1,
+// with the server P2 helping by providing various kinds of
 // correlated randomness, such as MultTriples and AndTriples.
-void rdpf_gen(MPCTIO &tio, yield_t &yield,
-    RDPF &rdpf, nbits_t depth)
+RDPF::RDPF(MPCTIO &tio, yield_t &yield,
+    RegXS target, nbits_t depth)
 {
     int player = tio.player();
+    size_t &aesops = tio.aes_ops();
 
     // Choose a random seed
-    DPFnode seed;
     arc4random_buf(&seed, sizeof(seed));
     // Ensure the flag bits (the lsb of each node) are different
     seed = set_lsb(seed, !!player);
     printf("seed: "); for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&seed)[15-i]); } printf("\n");
-    rdpf.seed = seed;
 
     AESkey prgkey;
     __m128i key = _mm_set_epi64x(314159265, 271828182);
     AES_128_Key_Expansion(prgkey, key);
     __m128i left, right;
-    AES_ECB_encrypt(left, set_lsb(seed, 0), prgkey);
-    AES_ECB_encrypt(right, set_lsb(seed, 1), prgkey);
+    AES_ECB_encrypt(left, set_lsb(seed, 0), prgkey, aesops);
+    AES_ECB_encrypt(right, set_lsb(seed, 1), prgkey, aesops);
 
     __m128i nleft, nright, oleft, oright;
-    prg(nleft, seed, 0);
-    prg(nright, seed, 1);
-    prgboth(oleft, oright, seed);
+    prg(nleft, seed, 0, aesops);
+    prg(nright, seed, 1, aesops);
+    prgboth(oleft, oright, seed, aesops);
     printf("left : "); for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&left)[15-i]); } printf("\n");
     printf("nleft: "); for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&nleft)[15-i]); } printf("\n");
     printf("oleft: "); for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&oleft)[15-i]); } printf("\n");

+ 19 - 6
rdpf.hpp

@@ -1,15 +1,28 @@
 #ifndef __RDPF_HPP__
 #define __RDPF_HPP__
 
+#include <vector>
+
 #include "mpcio.hpp"
 #include "coroutine.hpp"
 #include "types.hpp"
 
-// Construct a DPF of the given depth to be used for random-access
-// memory reads and writes.  The DPF is construction collaboratively by
-// P0 and P1, with the server P2 helping by providing various kinds of
-// correlated randomness, such as MultTriples and AndTriples.
-void rdpf_gen(MPCTIO &tio, yield_t &yield,
-    RDPF &rdpf, nbits_t depth);
+struct RDPF {
+    // The 128-bit seed
+    DPFnode seed;
+    // correction words; the depth of the DPF is the length of this
+    // vector
+    std::vector<DPFnode> cw;
+    // correction flag bits: the one for level i is bit i of this word
+    value_t cfbits;
+
+    // Construct a DPF with the given (XOR-shared) target location, and
+    // of the given depth, to be used for random-access memory reads and
+    // writes.  The DPF is construction collaboratively by P0 and P1,
+    // with the server P2 helping by providing various kinds of
+    // correlated randomness, such as MultTriples and AndTriples.
+    RDPF(MPCTIO &tio, yield_t &yield,
+        RegXS target, nbits_t depth);
+};
 
 #endif

+ 1 - 9
types.hpp

@@ -189,14 +189,6 @@ using DPFnode = __m128i;
 // only used while creating RDPFs in the preprocessing phase, so we
 // never need to store them.
 
-// You can't put __m128i types directly into a tuple because of
-// alignment attributes, but you can put them in a structure.
-struct AndTriple {
-    DPFnode X, Y, Z;
-};
-
-struct RDPF {
-    DPFnode seed;
-};
+using AndTriple = std::tuple<DPFnode, DPFnode, DPFnode>;
 
 #endif