Pairing product with a null element is always null
Hello,
I believe that there is a bad behavior implemented in the function element_prod_pairing, quoted below:
static inline void element_prod_pairing(
element_t out, element_t in1[], element_t in2[], int n) {
pairing_ptr pairing = out->field->pairing;
int i;
PBC_ASSERT(pairing->GT == out->field, "pairing output mismatch");
for(i = 0; i < n; i++) {
PBC_ASSERT(pairing->G1 == in1[i]->field, "pairing 1st input mismatch");
PBC_ASSERT(pairing->G2 == in2[i]->field, "pairing 2nd input mismatch");
if (element_is0(in1[i])) {
element_set0(out);
return;
}
if (element_is0(in2[i])) {
element_set0(out);
return;
}
}
pairing->prod_pairings((element_ptr) out->data, in1, in2, n, pairing);
}
The first loop is looking for null elements and exits with a null (unity) result if it finds any. If the function is to be what it states - a product of pairings - it should just ignore couples with a null element, but not disregard the rest of the input and return a null result. The following snippet shows that the behavior is indeed not the same as what the manual product would produce:
pairing_t params;
// [...] (initialize params)
element_t g1, g1_0, g2, gt, gt_0, gtp1, gtp2;
element_init_G1(g1, params);
element_init_G1(g1_0, params);
element_init_G2(g2, params);
element_init_GT(gt, params);
element_init_GT(gt_0, params);
element_init_GT(gtp1, params);
element_init_GT(gtp2, params);
element_random(g1);
element_set0(g1_0);
element_random(g2);
/* Manual pairing product: */
pairing_apply(gt, g1, g2, params);
pairing_apply(gt_0, g1_0, g2, params);
element_mul(gtp1, gt, gt_0);
/* Pairing product using element_prod_pairing */
element_t in1[2], in2[2];
element_init_G1(in1[0], params);
element_init_G1(in1[1], params);
element_init_G2(in2[0], params);
element_init_G2(in2[1], params);
element_set(in1[0], g1);
element_set(in1[1], g1_0);
element_set(in2[0], g2);
element_set(in2[1], g2);
element_prod_pairing(gtp2, in1, in2, 2);
cout << "gtp1 is gt: " << (!element_cmp(gtp1, gt)) << endl; // Yes
cout << "gtp2 is gt: " << (!element_cmp(gtp2, gt)) << endl; // No
The couples containing a null element should therefore only be removed from the list before the pairing product is computed. Best regards,
Rémi
PS : Is there a better way to put already existing variables in a 'element_t[]' array other than copying them? I've tried to only copy their pointer value, but without success (I am not used to manipulating fixed-sized arrays). Thank you for your advice.
Thanks, and sorry it's taken so long for me to respond.
I think you're right but I'm afraid I wrote that code a long time ago, and I haven't had much time to look into this in detail. Any chance you could supply a patch that fixes these issues?
-Ben
On Sun, Sep 4, 2016 at 9:40 AM, Rémi Bazin [email protected] wrote:
Hello,
I believe that there is a bad behavior implemented in the function element_prod_pairing, quoted below:
static inline void element_prod_pairing( element_t out, element_t in1[], element_t in2[], int n) { pairing_ptr pairing = out->field->pairing; int i; PBC_ASSERT(pairing->GT == out->field, "pairing output mismatch"); for(i = 0; i < n; i++) { PBC_ASSERT(pairing->G1 == in1[i]->field, "pairing 1st input mismatch"); PBC_ASSERT(pairing->G2 == in2[i]->field, "pairing 2nd input mismatch"); if (element_is0(in1[i])) { element_set0(out); return; } if (element_is0(in2[i])) { element_set0(out); return; } } pairing->prod_pairings((element_ptr) out->data, in1, in2, n, pairing); }
The first loop is looking for null elements and exits with a null (unity) result if it finds any. If the function is to be what it states - a product of pairings - it should just ignore couples with a null element, but not disregard the rest of the input and return a null result. The following snippet shows that the behavior is indeed not the same as what the manual product would produce:
pairing_t params; // [...] (initialize params) element_t g1, g1_0, g2, gt, gt_0, gtp1, gtp2; element_init_G1(g1, params); element_init_G1(g1_0, params); element_init_G2(g2, params); element_init_GT(gt, params); element_init_GT(gt_0, params); element_init_GT(gtp1, params); element_init_GT(gtp2, params); element_random(g1); element_set0(g1_0); element_random(g2); /* Manual pairing product: */ pairing_apply(gt, g1, g2, params); pairing_apply(gt_0, g1_0, g2, params); element_mul(gtp1, gt, gt_0); /* Pairing product using element_prod_pairing */ element_t in1[2], in2[2]; element_init_G1(in1[0], params); element_init_G1(in1[1], params); element_init_G2(in2[0], params); element_init_G2(in2[1], params); element_set(in1[0], g1); element_set(in1[1], g1_0); element_set(in2[0], g2); element_set(in2[1], g2); element_prod_pairing(gtp2, in1, in2, 2); cout << "gtp1 is gt: " << (!element_cmp(gtp1, gt)) << endl; // Yes cout << "gtp2 is gt: " << (!element_cmp(gtp2, gt)) << endl; // NoThe couples containing a null element should therefore only be removed from the list before the pairing product is computed. Best regards,
Rémi
PS : Is there a better way to put already existing variables in a 'element_t[]' array other than copying them? I've tried to only copy their pointer value, but without success (I am not used to manipulating fixed-sized arrays). Thank you for your advice.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/blynn/pbc/issues/7, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAOWHx_uSyQFziwwzAmZ3h721_-L06yks5qmvRkgaJpZM4J0kwy .