Skip to main content

🔑Linux系统下PBC库的安装

·600 words·3 mins
Yalois
Author
Yalois
freedom

开学网络安全实验课程的老师要教椭圆曲线,首先就是配置PBC库,Linux作为我的主系统,必须是要配上的。

Linux系统下PBC库的安装
#

0.编译前环境安装
#

sudo apt-get install m4
sudo apt-get install flex
sudo apt-get install bison

1.下载gmp和pbc并解压源码
#

pbc是依赖于gmp的,所以需要先安装gmp

下载gmp源码

官网:https://gmplib.org/

image-20240904154749656

下载gmp-6.3.0.tar.xz,并解压

tar -xf gmp-6.3.0.tar.xz

下载pbc源码

https://crypto.stanford.edu/pbc/download.html

image-20240904155436476

继续解压

tar -zxvf pbc-0.5.14.tar.gz

image-20240904155645649

2.编译安装gmp
#

依次执行列面的命令,如果没有出现error代表安装成功

cd gmp-6.3.0
./configure
make
sudo make install

image-20240904155727983

./configure最终结果如下

image-20240904234546013

make最终结果如下

image-20240904234722433

sudo make install最终结果如下

image-20240904234830296

3.编译安装PBC
#

cd ..
cd pbc-0.5.14
./configure
make
sudo make install

image-20240904160105585

./configure结果如下

image-20240904235131837

make结果如下

image-20240904235215875

sudo make install的结果

image-20240904235246785

4.gcc编译代码测试
#

写入下面的代码到test.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pbc/pbc.h> // Include the PBC library (Pairing-Based Cryptography)
#include <pbc/pbc.h> // Ensure you have installed libpbc-dev

// Function to get the current time (in seconds)
double get_time() {
    return (double)clock() / CLOCKS_PER_SEC;
}

int main(void) {
    pairing_t pairing;
    element_t s, x, r;
    element_t P, Ppub, Qu, Du, Su, Xu, Yu, V;
    element_t Tl, T2;
    double time1, time2;
    int byte;

    // Initialize pairing parameters
    pbc_param_t param;
    pbc_param_init_a_gen(param, 160, 512); // Example parameters, adjust as needed
    pairing_init_pbc_param(pairing, param);

    // Initialize elements
    element_init_Zr(s, pairing);
    element_init_Zr(r, pairing);
    element_init_Zr(x, pairing);
    element_init_G1(P, pairing);
    element_init_G1(Ppub, pairing);
    element_init_G1(Qu, pairing);
    element_init_G1(Su, pairing);
    element_init_G1(Du, pairing);
    element_init_G1(Xu, pairing);
    element_init_G1(Yu, pairing);
    element_init_G1(V, pairing);
    element_init_GT(Tl, pairing);
    element_init_GT(T2, pairing);

    if (!pairing_is_symmetric(pairing)) {
        fprintf(stderr, "only works with symmetric pairing\n");
        exit(1);
    }

    printf("Basic CL-PKE scheme\n");
    printf("Setup\n");
    time1 = get_time();

    // Generate random values
    element_random(s); // Generate KGC random master key
    element_random(P); // Generate generator P
    element_mul_zn(Ppub, P, s); // Compute Ppub = sP

    time2 = get_time();
    element_printf("P=%B\n", P);
    element_printf("s=%B\n", s);
    element_printf("Ppub=%B\n", Ppub);
    printf("the time of setup phase=%fs\n", time2 - time1);

    // Partial private key extraction phase
    printf("Partial private key extraction\n");
    time1 = get_time();
    element_random(Qu); // Simulate ID corresponding to Qu
    element_mul_zn(Du, Qu, s); // Compute partial private key Du = sQ
    time2 = get_time();
    element_printf("partial private key Du=%B\n", Du);
    printf("the time of partial private key extract phase=%fs\n", time2 - time1);

    // Set secret value phase
    printf("Set secret value\n");
    time1 = get_time();
    element_random(x);
    time2 = get_time();
    element_printf("secret value=%B\n", x);
    printf("the time of set secret value phase=%fs\n", time2 - time1);

    // Set private key phase
    printf("Set private key\n");
    time1 = get_time();
    element_mul_zn(Su, Du, x); // Compute Su = Du * x
    time2 = get_time();
    printf("the private key is\n");
    element_printf("Su=%B\n", Su);
    printf("the time of set private key phase=%fs\n", time2 - time1);

    // Set public key phase
    printf("Set public key\n");
    time1 = get_time();
    element_mul_zn(Xu, P, x); // Compute Xu = xP
    element_mul_zn(Yu, Ppub, x); // Compute Yu = xPpub
    time2 = get_time();
    printf("the public key is\n");
    element_printf("Xu=%B\n", Xu);
    element_printf("Yu=%B\n", Yu);
    printf("the time of set public key phase=%fs\n", time2 - time1);

    // Encrypt phase
    printf("Encrypt\n");
    time1 = get_time();
    pairing_apply(Tl, Xu, Ppub, pairing); // Compute Tl = e(Xu, Ppub)
    pairing_apply(T2, Yu, P, pairing); // Compute T2 = e(Yu, P)

    // Check public key validity
    if (!element_cmp(Tl, T2)) {
        element_random(r);
        element_mul_zn(V, P, r); // Compute V = rP
        pairing_apply(Tl, Yu, Qu, pairing); // Compute Tl = e(Yu, Qu)
        element_pow_zn(Tl, Tl, r); // Compute Tl = Tl^r
        element_printf("V=%B\n", V);
        element_printf("e(Yu, Qu)^r=%B\n", Tl);
    } else {
        printf("Error! The public key is not correct!\n");
        exit(1);
    }

    time2 = get_time();
    printf("the time of encrypt phase=%fs\n", time2 - time1);

    // Decrypt phase
    printf("Decrypt\n");
    time1 = get_time();
    pairing_apply(T2, V, Su, pairing); // Compute T2 = e(V, Su)
    time2 = get_time();
    element_printf("e(V, Su) =%B\n", T2);
    printf("the time of decrypt phase=%fs\n", time2 - time1);
    
    byte = element_length_in_bytes(V); // Get byte length of V
    printf("the bytes of ciphertext=%d\n", byte + 128);

    // Clear defined elements and pairing variables
    element_clear(P);
    element_clear(Ppub);
    element_clear(s);
    element_clear(Qu);
    element_clear(Du);
    element_clear(Xu);
    element_clear(Su);
    element_clear(Yu);
    element_clear(Tl);
    element_clear(T2);
    element_clear(r);
    element_clear(x);
    element_clear(V);
    pairing_clear(pairing);
    
    return 0;
}

在test.c同目录下使用gcc编译

gcc test.c -I/usr/local/include -L/usr/local/lib -lpbc -lgmp

运行a.out

image-20240905001324441

返回如上图所示结果代表一切正常

!!!get_time函数有点问题,测试代码,不要用。

5.额外问题
#

问题1:编译完之后运行程序报错
#

./a.out: error while loading shared libraries: libpbc.so.1: cannot open shared object file: No such file or directory

执行下面命令之后再运行

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH