简体   繁体   English

在Mac OS 10.8上使用dev / urandom生成非常慢的随机数

[英]Very Slow Random Number Generation using dev/urandom on Mac OS 10.8

I am writing a program that uses Paillier Cryptosystem to encrypt a matrix. 我正在编写一个使用Paillier Cryptosystem来加密矩阵的程序。 To encrypt a 50 x 50 matrix it takes about 12 seconds! 要加密50 x 50矩阵,大约需要12秒! That's painfully long considering I intend to encrypt matrices of sizes 5000 x 5000 and above. 考虑到我打算加密大小为5000 x 5000及以上的矩阵,这是痛苦的。 Profiling the program on Xcode I figured out that this paillier_get_rand_devurandom() is the culprit. 在Xcode上分析程序我发现这个paillier_get_rand_devurandom()是罪魁祸首。

This is the call trace snapshot : 这是调用跟踪快照:

在此输入图像描述

Here's the source code of this particular Paillier C library function 这是此特定Paillier C库函数的源代码

    void paillier_get_rand_devurandom( void* buf, int len )
    {
          paillier_get_rand_file(buf, len, "/dev/urandom");
    }  


    void paillier_get_rand_file( void* buf, int len, char* file )
   {
         FILE* fp;
         void* p;

         fp = fopen(file, "r");

         p = buf;
         while( len )
         {
             size_t s;
             s = fread(p, 1, len, fp);
             p += s;
             len -= s;
         }

        fclose(fp);
    }

And in case, 如果是的话,

    <http://www.en.wikipedia.org/wiki/Paillier_cryptosystem>
    Paillier Cryptosytem C library : <http://acsc.cs.utexas.edu/libpaillier/> 

I have read that random number generation using dev/random is slow whereas with dev/urandom its much faster. 我已经读过使用dev / random的随机数生成很慢而使用dev / urandom则更快。 In my case both are equally slow. 在我的情况下,两者都同样缓慢。 Can this random number generation be made faster? 这个随机数生成能否更快?

EDIT: Here's an example 编辑:这是一个例子

    #include <stdio.h>
    #include <stdlib.h>
    #include <gmp.h>
    #include<paillier.h>


   int main(void)
   {

       paillier_pubkey_t* pub;//The public key
   paillier_prvkey_t* prv;//The private key 


       paillier_keygen(1024, &pub, &prv,paillier_get_rand_devurandom);


      paillier_ciphertext_t* ca;
      paillier_ciphertext_t* cb;
      paillier_ciphertext_t* res;


      paillier_plaintext_t* a;
      paillier_plaintext_t* b;
      paillier_plaintext_t* sum;



     a=paillier_plaintext_from_ui(45);
     b=paillier_plaintext_from_ui(100);


     //This is the encryption function 
     ca=paillier_enc(0, pub, a, paillier_get_rand_devurandom);
     cb=paillier_enc(0, pub, b, paillier_get_rand_devurandom);


     res=paillier_create_enc_zero();


     paillier_mul(pub, res,ca, cb);

     sum=paillier_dec(0, pub, prv, res);


     gmp_printf("The sum is : %Zd\n",sum);


     return 0;

   }

And this is the encryption function signature 这是加密函数签名

    /*
Encrypt the given plaintext with the given public key using
randomness from get_rand for blinding. If res is not null, its
contents will be overwritten with the result. Otherwise, a new
paillier_ciphertext_t will be allocated and returned.
    */
    paillier_ciphertext_t* paillier_enc( paillier_ciphertext_t* res,
                                           paillier_pubkey_t* pub,
                        paillier_plaintext_t* pt,
                         paillier_get_rand_t get_rand );

Sorry this question is only getting longer 对不起,这个问题只会越来越长

 The actual scale_encrypt_T()

 void scale_encrypt_T(char *scaledTfile)
{
    ...
    ...

//Printing scaled and then encrypted T[][] in a file 
for(i=0;i<n;i++)
{
    for(j=0;j<n;j++)
    {
        void *buf2;

        //T[][] is the 50 x 50 matrix 
        temp=(int)(T[i][j]*pow(10,6));  //Scale factor q = 10 to the power of 6

        p0=paillier_plaintext_from_ui(temp);

        //c0 is the cipher text
         /***So this is where its taking so long***/
        c0=paillier_enc(0, pub, p0, paillier_get_rand_devurandom);


        buf2=paillier_ciphertext_to_bytes(PAILLIER_BITS_TO_BYTES(pub->bits)*2, c0);

        fwrite(buf2, 1, PAILLIER_BITS_TO_BYTES(pub->bits)*2, fpt);
        free(buf2);

    }

}

Supposing that n is 50, your code is doing 2500 separate encryptions. 假设n为50,您的代码将进行2500次单独加密。 Each encryption may require some random data. 每次加密可能需要一些随机数据。

It will be more efficient to do one encryption by encrypting the entire array in one call to paillier_enc . 通过在一次调用paillier_enc加密整个数组来进行一次加密会更有效率。 I am not familiar with the libpaillier API, but it looks like you would do this by arranging for all the data of the 50-by-50 array to be in contiguous memory, then use paillier_plaintext_from_bytes to package the entire array into a paillier_plaintext_t object, then use pallier_enc with that object. 我不熟悉libpaillier API,但看起来你会通过将50-by-50数组的所有数据安排在连续的内存中来实现,然后使用paillier_plaintext_from_bytes将整个数组打包成paillier_plaintext_t对象,然后使用pallier_enc与该对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM