0

I'm trying to implement a function defined in a library but I'm having problems to use it. This question help me to implement it, but I couldn't use the function.

Here is the typedef:

typedef void (*paillier_get_rand_t) ( void* buf, int len );

And here is how I implement it:

void get_rand(void* buf, int len) {
  buf = (void *)rand();  // I don't know if it works but isn't the problem
}

And here how I create the pointer to the function and call it.

   int modulus = 4;
    void* buf;
    paillier_pubkey_t* pub;
    paillier_prvkey_t* prv;
    paillier_keygen(modulus, &pub, &prv, &get_rand);                

Question 1) How I send the parameters buf and len? Question 2) Now the error is different:

reference to `paillier_keygen(int, paillier_pubkey_t**, paillier_prvkey_t**, void (*)(void*, int))' undefined

The function paillier_keygen is used to generate the respectives key for the algorithm and the function get_rand is used to obtain the randomness needed by the probabilistic algorithms.

I'm implementing this typedef because I need to do it to be able to use the lib.

EDIT:

I found one function who is already defined and I can use called paillier_get_rand_devurandom.

/* These functions may be passed to the paillier_keygen and paillier_enc functions to provide a source of random numbers. The first reads bytes from /dev/random. On Linux, this device exclusively returns entropy gathered from environmental noise and therefore frequently blocks when not enough is available. The second returns bytes from /dev/urandom. On Linux, this device also returns environmental noise, but augments it with a pseudo-random number generator when not enough is available. The latter is probably the better choice unless you have a specific reason to believe it is insufficient. */

void paillier_get_rand_devurandom( void* buf, int len );

If I used like before

paillier_keygen(modulus, &pub, &prv, paillier_get_rand_devurandom(buf, 4));

I get error: invalid use of void expression

If I used like this:

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

I get:

undefined reference to `paillier_get_rand_devurandom(void*, int)'
undefined reference to `paillier_keygen(int, paillier_pubkey_t**, paillier_prvkey_t**, void (*)(void*, int))'

The library is included. Here I add more info about the signatures:

/* Generate a keypair of length modulusbits using randomness from the provided get_rand function. Space will be allocated for each of the keys, and the given pointers will be set to point to the new paillier_pubkey_t and paillier_prvkey_t structures. The functions paillier_get_rand_devrandom and paillier_get_rand_devurandom may be passed as the final argument. */

void paillier_keygen( int modulusbits,
            paillier_pubkey_t** pub, paillier_prvkey_t** prv, paillier_get_rand_t get_rand );

/* This is the type of the callback functions used to obtain the randomness needed by the probabilistic algorithms. The functions paillier_get_rand_devrandom and paillier_get_rand_devurandom (documented later) may be passed to any library function requiring a paillier_get_rand_t, or you may implement your own. If you implement your own such function, it should fill in "len" random bytes in the array "buf". */

typedef void (*paillier_get_rand_t) ( void* buf, int len );
Community
  • 1
  • 1
Niemand
  • 127
  • 1
  • 12
  • 1
    Try `paillier_get_rand_t fnPtr = &getRand;` and pass `fnPtr` as the argument. – James Adkison Feb 03 '15 at 20:32
  • 2
    I would guess that `paillier_pubkey_t** pub;` is wrong, and instead you should have `paillier_pubkey_t* pub;` and pass to the function with `&pub`. (i.e. it probably expects a pointer to memory that it can access, you are giving something that will crash to access). – crashmstr Feb 03 '15 at 20:35
  • 1
    `buf = (void *)rand(); // I don't know if it works but isn't the problem` certainly makes no sense whatsoever. – Baum mit Augen Feb 03 '15 at 20:35
  • 2
    You define a type `paillier_get_rand_t` but then you never use it anywhere. That indicates to me that you're either leaving off vital code, have a typo somewhere, or you're entirely clueless about what you're doing (in which case you should probably stop. What are you trying to do? If what you're trying to do is understand every nook and cranny of C++ and you have no greater purpose, stop. That's a waste of time. C++ is packed to the brim with overlapping features. You probably already know some equally valid way of accomplishing the same things that this construct might do.) – ArtOfWarfare Feb 03 '15 at 20:37
  • @ArtOfWarfare It's the first time that I work with this kind of functions and pointers. I need to implement it to work with the library wich help me with the encryption in a protocol that I'm implementing. – Niemand Feb 03 '15 at 22:54

3 Answers3

2

I'm guessing a bit here, because you don't show the prototype of all the functions (and their documentation), but you almost certainly want this instead:

paillier_pubkey_t* pub;
paillier_prvkey_t* prv;
paillier_keygen(modulus, &pub, &prv, &get_rand);

With get_rand probably doing something like:

void get_rand(void* buf, int len)
{
    char* bytes = (char*)buf;
    for (int i = 0; i != len; ++i) {
        bytes[i] = rand() & 0xff;
    }
}
Cameron
  • 96,106
  • 25
  • 196
  • 225
  • But then why does he typedef `paillier_get_rand_t` if that's all he wants? – ArtOfWarfare Feb 03 '15 at 20:41
  • 3
    I have a feeling the `paillier` library declares that typedef and he's trying to implement the corresponding function. I made a few guesses based on what idiomatic C interfaces tend to look like. – Cameron Feb 03 '15 at 20:42
  • @Cameron is right, i'm trying to implement the corresponding function to the library `paillier`. I updated the code with more information and the error that I'm getting with your modifications. – Niemand Feb 03 '15 at 22:53
  • 1
    @Niemand: Your question's much clearer, thanks. However, I still don't have enough info to figure out what's not working -- what is the declared signature of the `paillier_keygen` function? (This is what you're trying to use, and so we need to know what it looks like in order to help you use it correctly.) Are you linking against the appropriate library? (The error message you get looks an awful lot like a linker error that would arise if the function was declared and used properly but its compiled code could not be found.) – Cameron Feb 03 '15 at 23:07
  • @Cameron I completed even more the question, sorry to don't that from the beginning. I think that I found the function I have to use, I'm getting the first error again. – Niemand Feb 04 '15 at 02:24
  • 1
    @Niemand: Right, that helps, thanks. It seems I surmised correctly -- both my sample call and your second one with `&paillier_get_rand_devurandom` are correct. Judging from the errors, it looks like you've included the right headers and the code compiles properly, but it fails at link time because the `paillier` library isn't being linked in. You need to link against `libpaillier`. How to do this exactly depends on your compiler, operating system, and whether the library is static or dynamic. – Cameron Feb 04 '15 at 03:17
  • @Cameron I'm compiling with the option -lpaillier and it works, dosn't show any error like: `library not found`. – Niemand Feb 04 '15 at 14:12
2

I found the solution. First of all I import the library like extern, because paillier.h is written in C and I'm using C++.

Just like this:

use #include <gmp.h>
extern "C"{
    #include "paillier.h"
}

After that I also compiled with -lpaillier and also -lgmp.

The final code would be:

paillier_pubkey_t* pub;
    paillier_prvkey_t* prv;
    paillier_keygen(1024, &pub, &prv, paillier_get_rand_devurandom);

There is no need to define any additional function.

Niemand
  • 127
  • 1
  • 12
1

You are dereferencing and invoking the value of get_rand_function when you state the following:

(*get_rand_funtion)(&buf, 4)

Since the declared return type is void, the compiler interprets the result of the expression as void, which is not a valid type for a function parameter. If you desire is to pass a pointer to the function paillier_keygen then @Cameron code is correct. At least in C99 and earlier you may not bind values to function pointer.

Mark
  • 1,128
  • 13
  • 21