Import/export

To be useful, at some stage the signature must be converted to bytes for storage or transmission:

int n = pairing_length_in_bytes_compressed_G1(pairing);
// Alternatively:
// int n = element_length_in_bytes_compressed(sig);
unsigned char *data = malloc(n);
element_to_bytes_compressed(data, sig);

On the other end, the signature must be decompressed:

element_from_bytes_compressed(sig, data);

Eliding _compressed in the above code will also work but the buffer data will be roughly twice as large.

We can save more space by using the x-coordinate of the signature only

int n = pairing_length_in_bytes_x_only_G1(pairing);
// Alternative:
//   int n = element_length_in_bytes_x_only(sig);
unsigned char *data = malloc(n);
element_to_bytes_compressed(data, sig);

but then there is a complication during verification since two different points have the same x-coordinate. One way to solve this problem is to guess one point and try to verify. If that fails, we try the other. It can be shown that the pairing outputs of the two points are inverses of each other, avoiding the need to compute a pairing the second time. (In fact, there are even better ways to handle this.)

int n = pairing_length_in_bytes_x_only_G1(pairing);
//int n = element_length_in_bytes_x_only(sig);
unsigned char *data = malloc(n);

element_to_bytes_x_only(data, sig);

element_from_bytes_x_only(sig, data)

pairing_apply(temp1, sig, g, pairing);
pairing_apply(temp2, h, public_key, pairing);

if (!element_cmp(temp1, temp2)) {
    printf("signature verifies on first guess\n");
} else {
    element_invert(temp1, temp1);
    if (!element_cmp(temp1, temp2)) {
        printf("signature verifies on second guess\n");
    } else {
        printf("signature does not verify\n");
    }
}