PBC Library Manual(PBC库手册)翻译(四)

目录

4.元素函数

4.1 元素初始化

4.2.元素赋值

4.3.元素转换

4.4.元素的算数运算

4.5.元素的幂运算

4.6.元素比较

4.7.元素I/O

4.8.随机元素

4.9.元素导入与导出


4.元素函数

群、环、域的元素都存储在element_t数据结构中。这种类型的变量在使用之前必须进行初始化,并且不再需要时要进行释放(clear)。

使用element_函数必须谨慎。就像0作被除数对于整数没有意义一样,某些操作可能对特定元素没有意义。例如,在环上,元素一般不能求逆。

另一个警告是,许多函数假设他们的参数来自于相同的环、群或者域。不执行隐式的类型转换。

对于调试构建,通过在包含pbc.h之前定义PBC_DEBUG来进行run-time检查

#define PBC_DEBUG
#include <pbc.h>

当PBC_DEBUG被定义时,以下的宏命令可用。通常他们会被空语句替换。

PBC_ASSERT(expr, msg), Macro: 如果expr赋值为0,打印msg并退出。

PBC_ASSERT_MATCH2(a, b), Macro: 如果元素a和b来自不同的域则退出。

PBC_ASSERT_MATCH3(a, b, c), Macro: 如果元素a、b和c来自不同的域则退出。

4.1 元素初始化

当初始化一个元素时,它与代数结构相关联,例如一个特定的有限域或者椭圆曲线。

我们用G1和G2表示pairing的输入群,用GT表示输出群。他们都是r阶的,Zr表示以r为摸的整数环。G1是较小的群(基本域点上的群)。对于对称pairing,G1=G2。

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)

 初始化e为pairing上的群G1、G2或GT上的元素。

void element_init_Zr(element_t e, pairing_t pairing)

 初始化e为pairing上的环Z_r上的元素。r是pairing中涉及的群G1、G2和GT的阶。

void element_init_same_as(element_t e, element_t e2)

 初始化e为e2元素所在的代数结构的一个元素。

 void element_clear(element_t e)

 释放元素e所占用的空间。当变量e不再需要时调用这个函数。

4.2.元素赋值

这些函数用于给元素赋值。当整数被赋值时,如果有意义,将被映射到代数结构(例如环和域)。

void element_set0(element_t e) // 将e设置为0

void element_set1(element_t e) // 将e设置为1

void element_set_si(element_t e, signed long int i) // 将e设置为i

void element_set_mpz(element_t e, mpz_t z) // 将e设置为z

void element_set(element_t e. element_t a) // 将e设置为a

4.3.元素转换

// 如果这样操作有意义,将e转换为GMP整数z
void element_to_mpz(mpz_t z, element_t e)

从长度为len个字节的缓冲区data中确定性的生成元素e
void element_from_hash(element_t e, void *data, int len)

4.4.元素的算数运算

除非另外有说明,所有的element_t函数参数都必须已经被初始化为相同的代数结构。当其中一个函数期望其参数来自特定的代数结构时,会在函数名中体现。

加法和乘法函数在环和域中执行加法和乘法运算。而对于椭圆曲线上的群(例如与pairing相关的G1和G2群),加法和乘法代表群操作(类似地,0和1代表单位元)。

相比之下,GT群目前是作为有限域上的子群来实现的,因此GT只需要使用乘法运算。

// 设置n = a+b
void element_add(element_t n, element_t a, element_t b)

// 设置n = a-b 
void element_sub(element_t n, element_t a, element_t b)

// 设置n = ab
void element_mul(element_t n, element_t a, element_t b)

// 设置n = az,即a+a+...+a, 其中z个a。
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)
void element_mul_zn(element_t c,element_t a, element_t z)

z必须整数模环的一个元素(即Zn for some n)。设置c= az,即a+a+...+a,其中z个a。

// 设置n = a/b
void element_div(element_t n, element_a, element_b)

// 设置n = a+a
void element_double(element_t n, element_t a)

// 设置n = a/2
void element_halve(element_t n, element_t a)

// 设置n = a^2(a的平方)
void element_square(element_t n, element_t a)

// 设置n = -a
void element_neg(element_t n, element_t a)

// 设置n为a的逆
void element_invert(element_t n, element_t a)

4.5.元素的幂运算

幂函数和多幂函数。如果预先知道某个特定元素在将来会被多次求幂,那么从长远来看,可以通过先调用预处理函数来节省时间:

element_pp_t g_pp;
element_pp_init(g_pp, 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)

 设置x = a^n,即a * a * ... * a,其中有n个a。

void element_pow_zn(element_t x,element_t a, element_t n)

设置x = a^n,其中n是某个N的环Zn的元素(通常阶是x所在的代数结构的阶) 。

//  设置x = (a1^n1)(a2^n2),并且通常比分别求幂要快
void element_pow2_mpz(element_t x,element_t a1, mpz_t n1, element_t a2, mpz_t n2)

// 同上,只是n的类型不同
void element_pow2_zn(element_t x, element_t a1, element_t n1, element_t a2, element_t n2)

// 设置x = (a1^n1)(a2^n2)(a3^n3),且速度比分别求幂要快
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)

// 同上
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)
// 准备对一个元素求幂,并将预处理信息存在p中
void element_pp_init(element_pp_t p, element_t in)

// 当p不再需要后释放p
void element_pp_clear(element_pp_t p)

// 将in求power幂并将结果存储在power中,其中in是预先处理过的元素,即第二个参数预先调用过element_pp_init。
void element_pp_pow(element_t out, mpz_t power, element_pp_t p)

// 同上,power类型不同
void element_pp_pow_zn(element_t out, element_t power, element_pp_t p)

// 通过暴力计算x使,g^x = h,其中x属于element_set_mpz()有意义的域
void element_dlog_brute_force(element_t x, element_t g, element_t h)

// 通过Pollard rho方法计算x,使g^ = h,其中x属于element_set_mpz()有意义的域
void element_dlog_pollard_rho(element_t x, element_t g, element_t h)

4.6.元素比较

这类函数比较来自相同代数结构的元素。

// 如果n=1返回true
int element_is1(element_t n)

// n=0返回true
int element_is0(element_t n)

// 如果a和b相同则返回0,否则返回非零
int element_cmp(element_t a, element_t b)

// 如果a是完全平方数(二次剩余)则返回非零,否则返回0
int element_is_sqr(element_t a)
int element_sgn(element_ a)
int element_sign(element_t a)

 如果a是0那么返回0。a不是0,其操作取决于代数结构,但是有属性:element_sgn(a) = -element_sgn(-a),element_sgn(a) = 0意味着有压倒性的概率使a=0。

4.7.元素I/O

这类函数主要为了使元素生成人类可读的输出。之后将讨论元素与字节之间的转换。

size_t element_out_str(FILE* stream, int base, element_t e)

 以基数(进制)base将e输出到流stream上,base必须在2-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)

除了有用于element_t类型专门的转换说明符B,和用于mpz_t的转换说明符Y、Z之外,与printf族函数相同。例如,如果e是element_t类型,那么element_printf("%B\n", e);会打印e的值为人类可读的形式到标准输出。

int element_snprint(char *s, size_t n, element_t e)

将元素转换为人类友好的字符串。表现为snprintf,但是每次只能对一个元素。

int element_set_str(element_t e, const char *s, int base)

 以字符串s设置元素e,其中s是以null结尾(这里应该只以'\0'结尾)的C风格字符串且是base进制。空格将被忽略。点的形式为“ [x,y]”或“ O”,而多项式的形式为“ [a0,...,an]”。返回读取的字符数(不像GMP的 mpz_set_str)。

4.8.随机元素

只适用于有限代数结构。对于多项式环和特征零的域等的影响未定义

PBC如何获得随机bit见6.1节。

void element_random(element_t e)

 如果e属于一个有限代数结构,那么均匀地给e赋值随机元素。

4.9.元素导入与导出

用于序列化和反序列化元素的函数。

// 返回元素e将要占用的字节长度
int element_length_in_bytes(element_t e)
int element_to_bytes(unsigned char *data, element_t e)

 将e转换为字节,将结果写入缓冲区data中。占用的字节数可以通过调用element_length_in_bytes()来确定。

// 从缓冲区data中读取元素e,并且返回读取的字节数
int element_from_bytes(element_t e, unsigned char *data)
// 假设e是椭圆曲线上的一个点。将e的x坐标写入到缓冲区data中
int element_to_bytes_x_only(unsigned char *data, element_t e)
int element_from_bytes_x_only(element_t e, unsigned char *data)

 假设e是椭圆曲线上的一个点。将e设置为一个点,其x坐标用缓冲区data表示。这并不是唯一的。对于每个x坐标,都存在两个不同的点,至少对于PBC中的椭圆曲线。(它们互逆。)

// 假设e是椭圆曲线上的点,返回e的x坐标需要占用的字节长度
int element_length_in_bytes_x_only(element_t e)
// 如果可能,输出元素e的一个压缩形式到字节缓冲区data中。目前仅适用于椭圆曲线上的点。
int element_to_bytes_compressed(unsigned char *data, element_t e)
// 以字节数据缓冲区中元素的压缩形式为元素e赋值,目前仅实现了椭圆曲线上的点。
int element_from_bytes_compressed(element_t e, unsigned char *data)
// 返回以压缩形式保存元素e需要占用的字节数。目前仅适用于椭圆曲线上的点
int element_length_in_bytes_compressed(element_t e)
// 对于点,返回坐标的数目。对于多项式,返回系数的数目。其它情况返回0
element_item_count(element_t e)
// 对于点,返回第n个坐标,对于多项式,返回x^n的系数(n次项的系数),其它情况返回NULL.返回值指向的函数值可能被改变
element_t element_item(element_t e, int i)
// 等价于 element_item(a, 0)
element_t element_x(element_t a)

// 等价于 element_item(a, 1)
element_t element_y(element_t a)

注:删除线部分是翻译不通顺或者可能有错误的地方。 

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值