PBC library 学习笔记(三)

继续学习PBC库中的函数等相关知识

1.pairing function

  • 一个应用在使用之前要先初始化pairing 对象,设置曲线、群以及其他数学概念。然后其他的elements才能被设置初始化,并应用于密码学。
    下载包中子文件param文件夹下已经有自带的一些不用的pairing,在gen子文件夹下可以用于使用者具体去生成参数(后续补上).
    pairing说明:包括三个质数r阶群,pairing就是一个双线性对。pairing_is_symmetric 函数可以用于判断当前所用的pairing是不是对称的。双线性pairing的数据类型pairing_t。相对应的函数操作一般以pairing_开头。

1-1.初始化pairing

用ASCII字符串初始化一个pairing

pairing_t pairing;
pairing_init_set_str(pairing, s);  // Where s is a char *.s字符串是有格式要求的param。如文件夹下的例子
  • 或者调用以下函数初始化

    pairing_t pairing;
    pairing_init_pbc_param(pairing, param);
    //而param是由关于param的函数初始化的
    
  • int pairing_init_set_str(pairing_t pairing, const char *s)
    Initialize pairing from parameters in a ASCIIZ string str Returns 0 on success, 1 on failure.

  • int pairing_init_set_buf(pairing_t pairing, const char *s, size_t len)
    Same, but read at most len bytes. If len is 0, it behaves as the previous function. Returns 0 on success, 1 on failure.
  • void pairing_init_pbc_param(struct pairing_s *pairing, pbc_param_t p)
    Initialize a pairing with pairing parameters p.
  • void pairing_clear(pairing_t pairing)
    Free the space occupied by pairing. Call whenever a pairing_t variable is no longer needed. Only call this after all elements associated with pairing have been cleared, as they need information stored in the pairing structure.

1-2.使用pairing

  • pairing_apply 函数执行pairing操作的其参数:1结果输出Gt;2 G1;3 G2;4 与之相关的pairing_t
  • 说明:定义一个pp若要循环使用同一个变量则可以直接赋值减少计算量
    pairing_pp_t pp;
    pairing_pp_init(pp, x, pairing); // x is some element of G1
    pairing_pp_apply(r1, y1, pp); // r1 = e(x, y1)
    pairing_pp_apply(r2, y2, pp); // r2 = e(x, y2)
    pairing_pp_clear(pp); // don’t need pp anymore
  • 相关函数说明
    • void pairing_pp_init(pairing_pp_t p, element_t in1, pairing_t pairing)
      Get ready to perform a pairing whose first input is in1, and store the results of time-saving precomputation in p.
    • void pairing_pp_clear(pairing_pp_t p)
      Clear p. This should be called after p is no longer needed.
    • void pairing_pp_apply(element_t out, element_t in2, pairing_pp_t p)
      Compute a pairing using in2 and the preprocessed information stored in p and store the output in out. The inputs to the pairing are the element previously used to initialize p and the element in2.
    • void element_pairing(element_t out, element_t in1, element_t in2)
      Computes a pairing: out = e(in1, in2), where in1, in2, out must be in the groups G1, G2, GT.
    • void element_prod_pairing(element_t out, element_t in1[], element_t in2[], int n)
      Computes the product of pairings, that is out = e(in1[0], in2[0]) … e(in1[n-1], in2[n-1]). The arrays in1, in2 must have at least n elements belonging to the groups G1, G2 respectively, and out must belong to the group GT.

1-3.其他pairing的函数说明

  • int pairing_is_symmetric(pairing_t pairing)判断是不是对称的pairing
    Returns true if G1 and G2 are the same group.
  • int pairing_length_in_bytes_G1(pairing_t pairing)G1元素需要多大比特长
    Returns the length in bytes needed to represent an element of G1.
  • int pairing_length_in_bytes_x_only_G1(pairing_t pairing)G1x元素轴需要多长
    Returns the length in bytes needed to represent the x-coordinate of an element of G1.
  • int pairing_length_in_bytes_compressed_G1(pairing_t pairing)G1元素压缩后需要多长
    Returns the length in bytes needed to represent a compressed form of an element of G1. There is some overhead in decompressing.
  • int pairing_length_in_bytes_G2(pairing_t pairing)
    Returns the length in bytes needed to represent an element of G2.
  • int pairing_length_in_bytes_compressed_G2(pairing_t pairing)
    Returns the length in bytes needed to represent a compressed form of an element of G2. There is some overhead in decompressing.
  • int pairing_length_in_bytes_x_only_G2(pairing_t pairing)
    Returns the length in bytes needed to represent the x-coordinate of an element of G2.
  • int pairing_length_in_bytes_GT(pairing_t pairing)
    Returns the length in bytes needed to represent an element of GT.
  • int pairing_length_in_bytes_Zr(pairing_t pairing)
    Returns the length in bytes needed to represent an element of Zr.

2.Element function

群,环,域的元素保存在element_t变量类型中。需要初始化要释放。
element_ 开头的函数要小心使用,避免无必要的使用,debug模式要做如下设置


#define PBC_DEBUG


#include 

开启debug模式,以下全局变量也被设置了
- PBC_ASSERT(expr, msg)
Macro: if expr evaluates to 0, print msg and exit.
- PBC_ASSERT_MATCH2(a, b)
Macro: if elements a and b are from different fields then exit.
- PBC_ASSERT_MATCH3(a, b, c)
Macro: if elements a, b and c are from different fields then exit.

2-1 初始化element

当一个元素被初始化之后就有了代数结构,比如一些有限域或椭圆曲线群
输入G1和G2,输出GT,阶都是r,,Zr 表示模r剩余环(the ring of integers modulo r)
当G1=G2表示对称pairing
- void element_init_G1(element_t e, pairing_t pairing)
- void element_init_G2(element_t e, pairing_t pairing)
- void element_init_GT(element_t e, pairing_t pairing)
Initialize e to be an element of the group G1, G2 or GT of pairing.
- void element_init_Zr(element_t e, pairing_t pairing)
Initialize e to be an element of the ring Z_r of pairing. r is the order of the groups G1, G2 and GT that are involved in the pairing.
- void element_init_same_as(element_t e, element_t e2)
Initialize e to be an element of the algebraic structure that e2 lies in.
- void element_clear(element_t e)
Free the space occupied by e. Call this when the variable e is no longer needed.

2-2 element赋值

  • void element_set0(element_t e)
    Set e to zero.
  • void element_set1(element_t e)
    Set e to one.
  • void element_set_si(element_t e, signed long int i)
    Set e to i.
  • void element_set_mpz(element_t e, mpz_t z)
    Set e to z.
  • void element_set(element_t e, element_t a)
    Set e to a.

2-3改变element

  • void element_to_mpz(mpz_t z, element_t e)
    Converts e to a GMP integer z if such an operation makes sense
  • void element_from_hash(element_t e, void *data, int len)
    Generate an element e deterministically from the len bytes stored in the buffer data.

2-4 element算术

除非特殊说明,否则所有的element都需要事先用特殊的袋鼠结构初始化,G1和G2可以进行加和乘运算,而GT只能有乘运算。
- void element_add(element_t n, element_t a, element_t b)
Set n to a + b.
- void element_sub(element_t n, element_t a, element_t b)
Set n to a - b.
- void element_mul(element_t n, element_t a, element_t b)
Set n = a b.
- void element_mul_mpz(element_t n, element_t a, mpz_t z)
-void element_mul_si(element_t n, element_t a, signed long int z)
Set n = a z, that is a + a + … + a where there are z a’s.
- void element_mul_zn(element_t c, element_t a, element_t z)
z must be an element of a integer mod ring (i.e. Zn for some n). Set c = a z, that is a + a + … + a where there are z a’s.
- void element_div(element_t n, element_t a, element_t b)
Set n = a / b.
- void element_double(element_t n, element_t a)
Set n = a + a.
- void element_halve(element_t n, element_t a)
Set n = a/2
- void element_square(element_t n, element_t a)
Set n = a2
- void element_neg(element_t n, element_t a)
Set n = -a.
- void element_invert(element_t n, element_t a)
Set n to the inverse of a.

2-5Exponentiating elements指数运算

如果一个元素要多次被用到建议采用如下方式减少计算量
element_pp_t g_pp;
element_pp_init(g_pp, g);//g要多次被用到
element_pp_pow(h, pow1, g_pp); // h = g^pow1
element_pp_pow(h, pow2, g_pp); // h = g^pow2
element_pp_pow(h, pow3, g_pp); // h = g^pow3
element_pp_clear(g_pp);

  • void element_pow_mpz(element_t x, element_t a, mpz_t n)
    Set x = an, that is a times a times … times a where there are n a’s.
  • void element_pow_zn(element_t x, element_t a, element_t n)
    Set x = an, where n is an element of a ring ZN for some N (typically the order of the algebraic structure x lies in).
  • void element_pow2_mpz(element_t x, element_t a1, mpz_t n1, element_t a2, mpz_t n2)
    Sets x = a1n1 a2n2, and is generally faster than performing two separate exponentiations.
  • void element_pow2_zn(element_t x, element_t a1, element_t n1, element_t a2, element_t n2)
    Also sets x = a1n1 a2n2, but n1, n2 must be elements of a ring Zn for some integer n.
  • void element_pow3_mpz(element_t x, element_t a1, mpz_t n1, element_t a2, mpz_t n2, element_t a3, mpz_t n3)
    Sets x = a1n1 a2n2 a3n3, generally faster than performing three separate exponentiations.
  • void element_pow3_zn(element_t x, element_t a1, element_t n1, element_t a2, element_t n2, element_t a3, element_t n3)
    Also sets x = a1n1 a2n2 a3n3, but n1, n2, n3 must be elements of a ring Zn for some integer n.
  • void element_pp_init(element_pp_t p, element_t in)
    Prepare to exponentiate an element in, and store preprocessing information in p.
  • void element_pp_clear(element_pp_t p)
    Clear p. Should be called after p is no longer needed.
  • void element_pp_pow(element_t out, mpz_t power, element_pp_t p)
    Raise in to power and store the result in out, where in is a previously preprocessed element, that is, the second argument passed to a previous element_pp_init call.
  • void element_pp_pow_zn(element_t out, element_t power, element_pp_t p)
    Same except power is an element of Zn for some integer n.
  • void element_dlog_brute_force(element_t x, element_t g, element_t h)
    Computes x such that gx = h by brute force, where x lies in a field where element_set_mpz() makes sense.
  • void element_dlog_pollard_rho(element_t x, element_t g, element_t h)
    Computes x such that gx = h using Pollard rho method, where x lies in a field where element_set_mpz() makes sense.

2-6Comparing elements

在同一个代数结构下进行比较

  • int element_is1(element_t n)
    Returns true if n is 1.
  • int element_is0(element_t n)
    Returns true if n is 0.
  • int element_cmp(element_t a, element_t b)
    Returns 0 if a and b are the same, nonzero otherwise.
  • int element_is_sqr(element_t a)
    Returns nonzero if a is a perfect square (quadratic residue), zero otherwise.
  • int element_sgn(element_t a)
  • int element_sign(element_t a)
    If a is zero, returns 0. For nozero a the behaviour depends on the algebraic structure, but has the property that element_sgn(a) = -element_sgn(-a) and element_sgn(a) = 0 implies a = 0 with overwhelming probability.

2-7元素的输入输出

  • size_t element_out_str(FILE * stream, int base, element_t e)
    Output e on stream in base base. The base must be between 2 and 36.
  • int element_printf(const char *format, …)
  • int element_fprintf(FILE * stream, const char *format, …)
  • int element_snprintf(char *buf, size_t size, const char *fmt, …)
  • int element_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
    Same as printf family except also has the B conversion specifier for types of element_t, and Y, Z conversion specifiers for mpz_t. For example if e is of type element_t then
  • element_printf(“%B\n”, e);
    will print the value of e in a human-readable form on standard output.
  • int element_snprint(char *s, size_t n, element_t e)
    Convert an element to a human-friendly string. Behaves as snprintf but only on one element at a time.

2-8Random elements

  • void element_random(element_t e)
    If the e lies in a finite algebraic structure, assigns a uniformly random element to e.

2-9Element import/export

以下函数用于序列化和非序列化element

  • int element_length_in_bytes(element_t e)
    Returns the length in bytes the element e will take to represent
  • int element_to_bytes(unsigned char *data, element_t e)
    Converts e to byte, writing the result in the buffer data. The number of bytes it will write can be determined from calling element_length_in_bytes(). Returns number of bytes written.
  • int element_from_bytes(element_t e, unsigned char *data)
    Reads e from the buffer data, and returns the number of bytes read.
  • int element_to_bytes_x_only(unsigned char *data, element_t e)
    Assumes e is a point on an elliptic curve. Writes the x-coordinate of e to the buffer data
  • int element_from_bytes_x_only(element_t e, unsigned char *data)
    Assumes e is a point on an elliptic curve. Sets e to a point with x-coordinate represented by the buffer data. This is not unique. For each x-coordinate, there exist two different points, at least for the elliptic curves in PBC. (They are inverses of each other.)
  • int element_length_in_bytes_x_only(element_t e)
    Assumes e is a point on an elliptic curve. Returns the length in bytes needed to hold the x-coordinate of e.
  • int element_to_bytes_compressed(unsigned char *data, element_t e)
    If possible, outputs a compressed form of the element e to the buffer of bytes data. Currently only implemented for points on an elliptic curve.
  • int element_from_bytes_compressed(element_t e, unsigned char *data)
    Sets element e to the element in compressed form in the buffer of bytes data. Currently only implemented for points on an elliptic curve.
  • int element_length_in_bytes_compressed(element_t e)
    Returns the number of bytes needed to hold e in compressed form. Currently only implemented for points on an elliptic curve.
  • int element_item_count(element_t e)
    For points, returns the number of coordinates. For polynomials, returns the number of coefficients. Otherwise returns zero.
  • element_t element_item(element_t e, int i)
    For points, returns nth coordinate. For polynomials, returns coefficient of xn. Otherwise returns NULL. The element the return value points to may be modified.
  • element_t element_x(element_t a)
    Equivalent to element_item(a, 0).
  • element_t element_y(element_t a)
    Equivalent to element_item(a, 1).

3Param functions

3-1初始化pairing的参数的初始化


  • int pbc_param_init_set_str(pbc_param_t par, const char *s)
    Initializes pairing parameters from the string s. Returns 0 if successful, 1 otherwise.
  • int pbc_param_init_set_buf(pbc_param_t par, const char *s, size_t len)
    Same, but read at most len bytes. If len is 0, it behaves as the previous function. Returns 0 if successful, 1 otherwise.
  • void pbc_param_out_str(FILE *stream, pbc_param_t p)
    Write pairing parameters to ‘stream’ in a text format.
  • void pbc_param_clear(pbc_param_t p)
    Clear p. Call after p is no longer needed.
    3-2参数的生成

在param文件夹下,a开头的是速度最快的,d和f开头的element
The pbc_cm_t data type holds CM parameters that are used to generate type D and G curves.

  • void pbc_cm_init(pbc_cm_t cm)
    ———-Initializes cm.
  • void pbc_cm_clear(pbc_cm_t cm)
    ———-Clears cm.
  • int pbc_cm_search_d(int (callback)(pbc_cm_t, void ), void *data, unsigned int D, unsigned int bitlimit)
    ———-For a given discriminant D, searches for type D pairings suitable for cryptography (MNT curves of embedding degree 6). The group order is at most bitlimit bits. For each set of CM parameters found, call callback with pbc_cm_t and given void *. If the callback returns nonzero, stops search and returns that value. Otherwise returns 0.
  • int pbc_cm_search_g(int (callback)(pbc_cm_t, void ), void *data, unsigned int D, unsigned int bitlimit)
    ———-For a given discriminant D, searches for type G pairings suitable for cryptography (Freeman curve). The group order is at most bitlimit bits. For each set of CM parameters found, call callback with pbc_cm_t and given void *. If the callback returns nonzero, stops search and returns that value. Otherwise returns 0.
  • void pbc_param_init_a_gen(pbc_param_t par, int rbits, int qbits)
    ———-Generate type A pairing parameters and store them in p, where the group order r is rbits long, and the order of the base field q is qbits long. Elements take qbits to represent.
    To be secure, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in finite fields of order q^2, e.g. rbits = 160, qbits = 512.
    The file param/a.param contains parameters for a type A pairing suitable for cryptographic use.
  • void pbc_param_init_i_gen(pbc_param_t par, int group_size)
    ———-Generate type I pairing parameters and store them in p, where the group order is at least 2^group_size.
    To be as secure as 64 bit symmetric encryption, group_size may be 150. To get 128 bit symmetric secure level, group_size may be 696.
    The file param/i.param contains parameters for a type I pairing suitable for cryptographic use.
  • void pbc_param_init_a1_gen(pbc_param_t param, mpz_t n)
    Generate type A1 pairing parameters and store them in p. The group order will be n. The order of the base field is a few bits longer. To be secure, generic discrete log algorithms must be infeasible in groups of order n, and finite field discrete log algorithms must be infeasible in finite fields of order roughly n2. Additionally, n should be hard to factorize.
    For example: n a product of two primes, each at least 512 bits.
    The file param/a1.param contains sample parameters for a type A1 pairing, but it is only for benchmarking: it is useless without the factorization of n, the order of the group.
  • void pbc_param_init_d_gen(pbc_param_t p, pbc_cm_t cm)
    ———-Type D curves are generated using the complex multiplication (CM) method. This function sets p to a type D pairing parameters from CM parameters cm. Other library calls search for appropriate CM parameters and the results can be passed to this function.
    To be secure, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in finite fields of order q6. For usual CM parameters, r is a few bits smaller than q.
    Using type D pairings allows elements of group G1 to be quite short, typically 170-bits. Because of a certain trick, elements of group G2 need only be 3 times longer, that is, about 510 bits rather than 6 times long. They are not quite as short as type F pairings, but much faster.
    I sometimes refer to a type D curve as a triplet of numbers: the discriminant, the number of bits in the prime q, and the number of bits in the prime r. The gen/listmnt program prints these numbers.
    Among the bundled type D curve parameters are the curves 9563-201-181, 62003-159-158 and 496659-224-224 which have shortened names param/d201.param, param/d159.param and param/d225.param respectively.
    See gen/listmnt.c and gen/gendparam.c for how to generate type D pairing parameters.
  • void pbc_param_init_e_gen(pbc_param_t p, int rbits, int qbits)
    ———-Generate type E pairing parameters and store them in p, where the group order r is rbits long, and the order of the base field q is qbits long. To be secure, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in finite fields of order q, e.g. rbits = 160, qbits = 1024.
    This pairing is just a curiosity: it can be implemented entirely in a field of prime order, that is, only arithmetic modulo a prime is needed and there is never a need to extend a field.
    If discrete log in field extensions are found to be substantially easier to solve than previously thought, or discrete log can be solved in elliptic curves as easily as they can be in finite fields, this pairing type may become useful.
  • void pbc_param_init_f_gen(pbc_param_t p, int bits)
    Generate type F pairing parameters and store them in p. Both the group order r and the order of the base field q will be roughly bits-bit numbers. To be secure, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in finite fields of order q^12, e.g. bits = 160.
    Type F should be used when the top priority is to minimize bandwidth (e.g. short signatures). The current implementation makes them slow.
    If finite field discrete log algorithms improve further, type D pairings will have to use larger fields, but type F can still remain short, up to a point.
  • void pbc_param_init_g_gen(pbc_param_t p, pbc_cm_t cm)
    Type G curves are generated using the complex multiplication (CM) method. This function sets p to a type G pairing parameters from CM parameters cm. They have embedding degree 10.
    To be secure, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in finite fields of order q6. For usual CM parameters, r is a few bits smaller than q.
    They are quite slow at the moment so for now type F is a better choice.
    The file param/g149.param contains parameters for a type G pairing with 149-bit group and field sizes.
  • 其他

    关于参数param以及一些例子的说明看manual

    你可能感兴趣的:(Cryptography)