开学网络安全实验课程的老师要教椭圆曲线,首先就是配置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/
下载gmp-6.3.0.tar.xz,并解压
tar -xf gmp-6.3.0.tar.xz
下载pbc源码
https://crypto.stanford.edu/pbc/download.html
继续解压
tar -zxvf pbc-0.5.14.tar.gz
2.编译安装gmp #
依次执行列面的命令,如果没有出现error代表安装成功
cd gmp-6.3.0
./configure
make
sudo make install
./configure最终结果如下
make最终结果如下
sudo make install最终结果如下
3.编译安装PBC #
cd ..
cd pbc-0.5.14
./configure
make
sudo make install
./configure结果如下
make结果如下
sudo make install的结果
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
返回如上图所示结果代表一切正常
!!!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