第十一章 大数 / 11.3 大数函数

大数函数一般都能根据函数名字知道其实现的功能。下面简单介绍了几个函数。

1  BN_rand/BN_pseudo_rand

生成一个随机的大数。

2BN_rand_range/BN_pseudo_rand_range

生成随机数,但是给出了随机数的范围。

3BN_dup

大数复制。

4)   BN_generate_prime

生成素数。

       5  int BN_add_word(BIGNUM *a, BN_ULONG w)

给大数a加上w,如果成功,返回1

示例:

#include <openssl/bn.h>

 

int     main()

{

int                  ret;

BIGNUM        *a;

BN_ULONG   w;

 

a=BN_new();

BN_one(a);

w=2685550010;

ret=BN_add_word(a,w);

if(ret!=1)

{

        printf("a+=w err!\n");

        BN_free(a);

        return -1;

}

BN_free(a);

return 0;

}

6)    BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)

将内存中的数据转换为大数,为内存地址,len为数据长度ret为返回值。

示例:

#include <openssl/bn.h>

intmain()

{

    BIGNUM*ret1,*ret2;

 

    ret1=BN_new();

    ret1=BN_bin2bn("242424ab",8, ret1);

    ret2=BN_bin2bn("242424ab",8,NULL);

    BN_free(ret1);

    BN_free(ret2);

    return 0;

}

注意:输入参数“242424ab”是asc码,对应的大数值为16进制的0x3234323432346162

7)  int BN_bn2bin(const BIGNUM *a, unsigned char *to)

将大数转换为内存形式。输入参数为大数ato为输出缓冲区地址,缓冲区需要预先分配,返回值为缓冲区的长度。

示例:

#include <openssl/bn.h>

int    main()

{

       BIGNUM*ret1=NULL;

       charbin[50],*buf=NULL;

       int           len;

 

       ret1=BN_bin2bn("242424ab",8, NULL);

       len=BN_bn2bin(ret1,bin);

       len=BN_num_bytes(ret1);

       buf=malloc(len);

       len=BN_bn2bin(ret1,buf);

       free(buf);

       BN_free(ret1);

       return 0;

}

本例的缓冲区分配有两种方法:静态分配和动态分配。动态分配时,先调用

BN_num_bytes函数获取大数对应的缓冲区的大小。

8)  char *BN_bn2dec(const BIGNUM *a)

将大数转换成整数字符串。返回值中存放整数字符串,它由内部分配空间,用户必须在外部用OPENSSL_free函数释放该空间。

示例:

#include <openssl/bn.h>

#include <openssl/crypto.h>

intmain()

{

    BIGNUM*ret1=NULL;

    char   *p=NULL;

    int    len=0;

 

    ret1=BN_bin2bn("242424ab",8, NULL);

    p=BN_bn2dec(ret1);

    printf("%s\n",p);/* 3617571600447332706 */

    BN_free(ret1);

OPENSSL_free(p);

    getchar();

    return 0;

}

    9char *BN_bn2hex(const BIGNUM *a)

将大数转换为十六进制字符串。返回值为生成的十六进制字符串,外部需要用OPENSSL_free函数释放

示例:

#include <openssl/bn.h>

#include <openssl/crypto.h>

intmain()

{

    BIGNUM*ret1=NULL;

    char   *p=NULL;

    int    len=0;

 

    ret1=BN_bin2bn("242424ab",8, NULL);

    p=BN_bn2hex(ret1);

    printf("%s\n",p);

    BN_free(ret1);

    OPENSSL_free(p);

    getchar();

    return 0;

}

输出的结果为:323432346162

10)  BN_cmp

比较两个大数。

11BIGNUM *BN_mod_inverse(BIGNUM *in,  const BIGNUM *a,

const BIGNUM *n, BN_CTX *ctx)

计算ax=1(mod n)

用户使用openssl函数编程时,一般用不着进行大数运算。BN_bin2bnBN_hex2bnBN_dec2bnBN_bin2bnBN_bn2binBN_bn2hexBN_bn2dec比较常用。比如给定RSA密钥的内存形式,用户可以调用BN_bin2bn来构造RSA密钥的大数元素来进行RSA运算,或者已经生成了RSA密钥,用户调用BN_bn2binRSA各个元素导出到内存中再写入密钥文件。