安装 openssl 参考:(https://www.jianshu.com/p/12b748bdedd2)
-
加法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<openssl/bn.h>
#include<openssl/bio.h>
#include<string.h>
#include<openssl/applink.c>
using namespace std;
typedef unsigned char byte;
int main()
{
BIGNUM* a, * b, * sum;
BIO* out=NULL;
a = BN_new(); // 创建一个BIGNUM的结构,返回新BIGNUM结构的指针
char strNum1[] = "9987";
BN_hex2bn(&a, strNum1); // 将 strNum1 装入 a 中
b = BN_new();
char strNum2[] = "01999";
BN_hex2bn(&b, strNum2);
sum = BN_new();
if (!BN_add(sum, a, b)) // 成功 返回 1,失败 返回 0
{
cout << "加法计算失败";
return false;
}
out = BIO_new(BIO_s_file()); // 定义的一个文件输出
BIO_set_fp(out, stdout, BIO_NOCLOSE);
BIO_puts(out, "大数计算:");
BN_print(out, sum); // 输出为 16 进制
BIO_puts(out, "\t结束\n");
BN_free(a);
BN_free(b);
BN_free(sum);
BIO_free(out);
return 1;
}
相当于计算:0x9987+0x01999=0xb320
结果:大数计算:B320 结束
-
减法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<openssl/bn.h>
#include<openssl/bio.h>
#include<string.h>
#include<openssl/applink.c>
using namespace std;
typedef unsigned char byte;
int main()
{
BIGNUM* a, * b, * result;
BIO* out=NULL;
a = BN_new(); // 创建一个BIGNUM的结构,返回新BIGNUM结构的指针
char strNum1[] = "9987";
BN_hex2bn(&a, strNum1); // 将 strNum1 装入 a 中
b = BN_new();
char strNum2[] = "01999";
BN_hex2bn(&b, strNum2);
result = BN_new();
if (!BN_sub(result, b, a)) // 成功 返回 1,失败 返回 0
{
cout << "减法计算失败";
return false;
}
out = BIO_new(BIO_s_file()); // 定义的一个文件输出
BIO_set_fp(out, stdout, BIO_NOCLOSE);
BIO_puts(out, "大数计算:");
BN_print(out, result); // 输出为 16 进制
BIO_puts(out, "\t结束\n");
BN_free(a);
BN_free(b);
BN_free(result);
BIO_free(out);
return 1;
}
相当于:0x01999 - 0x9987= -0x7fee
结果:大数计算:-7FEE 结束
-
乘法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<openssl/bn.h>
#include<openssl/bio.h>
#include<string.h>
#include<openssl/applink.c>
using namespace std;
typedef unsigned char byte;
int main()
{
BIGNUM* a, * b, * result;
BN_CTX* ctx;
BIO* out=NULL;
a = BN_new(); // 创建一个BIGNUM的结构,返回新BIGNUM结构的指针
char strNum1[] = "9987";
BN_hex2bn(&a, strNum1); // 将 strNum1 装入 a 中
b = BN_new();
char strNum2[] = "01999";
BN_hex2bn(&b, strNum2);
ctx = BN_CTX_new();
result = BN_new();
if (!BN_mul(result,a,b,ctx)) // 成功 返回 1,失败 返回 0
{
cout << "乘法计算失败";
return false;
}
out = BIO_new(BIO_s_file()); // 定义的一个文件输出
BIO_set_fp(out, stdout, BIO_NOCLOSE);
BIO_puts(out, "大数计算:");
BN_print(out, result); // 输出为 16 进制
BIO_puts(out, "\t结束\n");
BN_free(a);
BN_free(b);
BN_free(result);
BIO_free(out);
BN_CTX_free(ctx);
return 1;
}
相当于:0x9987*0x01999= 0xf59f0af
结果:大数计算:F59F0AF 结束
-
除法及取余
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<openssl/bn.h>
#include<openssl/bio.h>
#include<string.h>
#include<openssl/applink.c>
using namespace std;
typedef unsigned char byte;
int main()
{
BIGNUM* a, * b, * div, * rem;
BN_CTX* ctx;
BIO* out=NULL;
a = BN_new(); // 创建一个BIGNUM的结构,返回新BIGNUM结构的指针
char strNum1[] = "9987";
BN_hex2bn(&a, strNum1); // 将 strNum1 装入 a 中
b = BN_new();
char strNum2[] = "01999";
BN_hex2bn(&b, strNum2);
ctx = BN_CTX_new();
div = BN_new();
rem = BN_new();
if (!BN_div(div,rem,a,b,ctx)) // 成功 返回 1,失败 返回 0
{
cout << "除法计算失败";
return false;
}
out = BIO_new(BIO_s_file()); // 定义的一个文件输出
BIO_set_fp(out, stdout, BIO_NOCLOSE);
BIO_puts(out, "大数计算:商为:");
BN_print(out, div); // 输出为 16 进制
BIO_puts(out, "\t余数为:");
BN_print(out, rem);
BIO_puts(out, "\t结束");
BN_free(a);
BN_free(b);
BN_free(div);
BN_free(rem);
BIO_free(out);
BN_CTX_free(ctx);
return 1;
}
相当于:0x9987 ➗ 0x01999= 0x5....................0x198a
结果:大数计算:商为:5 余数为:198A 结束
-
平方取余
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<openssl/bn.h>
#include<openssl/bio.h>
#include<string.h>
#include<openssl/applink.c>
using namespace std;
typedef unsigned char byte;
int main()
{
BIGNUM* a, * m, * result;
BN_CTX* ctx;
BIO* out=NULL;
a = BN_new(); // 创建一个BIGNUM的结构,返回新BIGNUM结构的指针
char strNum1[] = "9987";
BN_hex2bn(&a, strNum1); // 将 strNum1 装入 a 中
m = BN_new();
char strNum2[] = "10000";
BN_hex2bn(&m, strNum2);
ctx = BN_CTX_new();
result = BN_new();
if (!BN_mod_sqr(result,a,m,ctx)) // 成功 返回 1,失败 返回 0
{
cout << "平方取模计算失败";
return false;
}
out = BIO_new(BIO_s_file()); // 定义的一个文件输出
BIO_set_fp(out, stdout, BIO_NOCLOSE);
BIO_puts(out, "大数计算:平方取模后为:");
BN_print(out, result); // 输出为 16 进制
BIO_puts(out, "\t结束");
BN_free(a);
BN_free(m);
BN_free(result);
BIO_free(out);
BN_CTX_free(ctx);
return 1;
}
相当于:0x9987**2 mod 0x10000 == 0xa531
结果:大数计算:平方取模后为:A531 结束
注意:连续计算多个乘除法时,定义一次 BN_CTX 指针就可以了。
- 参考链接:
《openssl 编程》之大数
SM2算法第二十七篇: openssl库中的BIGNUM(超赞)
OpenSSL 大数(BIGNUM)运算函数
Openssl中的BIGNUM运算函数(整理)
- 使用环境:VS2019
网友评论