hks_mbedtls_bn.c代码详细
本篇主要分析安全模块下hks_mbedtls_bn.c文件,主要涉及到两个函数,都是为了实现大数运算中的expmod运算。
文件位置
一、相关知识
二、代码分析
运算参数的检查
该函数主要是为了检查运算中的x和n参数,来判断n是否为大奇数,该运算要求取模数n必须为大奇数,该函数基于与运算对n的最后一位进行判断奇偶。同时比较x和n的数据域宽度,如果x_data.size < n_data.size函数报错返回,即x小于n则有可能无法存放最后结果。
参数详解:
- n主要是为了存储该计算过程中的要取模的数字
- x:是为了存储最后结果的数组
//检查取模的数n和最终结果数x
//原理x = a^e mod n
static int32_t CheckBnExpModNx(const struct HksBlob *n, const struct HksBlob *x)
{
/* zero is even number, so doesn't have to be checked */
if ((n->data[n->size - 1] & 0x1) == 0x0) {
//用来检查n的数据域中最后一位数来判断n是奇数还是偶数
HKS_LOG_E("The param n(modular) must be odd!");
//如果与运算结果为0,说明n为偶数,程序报错。n必须为奇数
return HKS_ERROR_INVALID_ARGUMENT;
}
if (x->size < n->size) {
//如果存放结果的数据域宽度小于mod数n的宽的,说明x的数据与太小,不够存放结果
HKS_LOG_E("The param x's size is too samll! x size = 0x%X", x->size);
return HKS_ERROR_BUFFER_TOO_SMALL;
}
return HKS_SUCCESS;
}
运算执行过程
该过程主要目的是为了计算:x = a^e mod n。
函数传入的参数功能同上面表达式,分别是计算中的四个数据。函数原理主要是基于mbedtls_mpi中所封装的结构体和函数,先申请四个临时结构体空间,将函数传入的a,e,n分别读进临时变量,mbedtls_mpi_exp_mod函数将运算执行并且结果写进临时变量bnX,最后再将bnX数据写进函数传入参数HksBlob结构体:x
//实现ExpMod运算
//原理 x = a^e mod n
int32_t HksMbedtlsBnExpMod(const struct HksBlob *a,
const struct HksBlob *e, const struct HksBlob *n, struct HksBlob *x)
{
int32_t ret = CheckBnExpModNx(n, x);//先对结果x和大数mod进行判断
if (ret != HKS_SUCCESS) {
return ret;
}
mbedtls_mpi bnX;
mbedtls_mpi bnA;
mbedtls_mpi bnE;
mbedtls_mpi bnN;
mbedtls_mpi_init(&bnX);
mbedtls_mpi_init(&bnA);
mbedtls_mpi_init(&bnE);
mbedtls_mpi_init(&bnN);
//定义大数A,X,E,N并且初始化
do {
ret = mbedtls_mpi_read_binary(&bnA, a->data, a->size);
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls mpi read a failed! mbedtls ret = 0x%X", ret);
break;
}
ret = mbedtls_mpi_read_binary(&bnE, e->data, e->size);
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls mpi read e failed! mbedtls ret = 0x%X", ret);
break;
}
ret = mbedtls_mpi_read_binary(&bnN, n->data, n->size);
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls mpi read n failed! mbedtls ret = 0x%X", ret);
break;
}
//将函数传入参数a,e,n分别调用mbedtls_mpi_read_binary函数读进刚刚定义的bnA,bnE,bnN
ret = mbedtls_mpi_exp_mod(&bnX, &bnA, &bnE, &bnN, NULL);
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls exp mod failed! mbedtls ret = 0x%X", ret);
break;
//调用库函数执行x=a^e mod n
}
ret = mbedtls_mpi_write_binary(&bnX, x->data, x->size);
//将最后结果从bnX写进函数传入的HksBlob结构体x
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls mpi write x failed! mbedtls ret = 0x%X", ret);
}
} while (0);
mbedtls_mpi_free(&bnX);
mbedtls_mpi_free(&bnA);
mbedtls_mpi_free(&bnE);
mbedtls_mpi_free(&bnN);
//最后释放刚刚临时申请的四个大数对应的空间
return ret;
}
三、总结
以上为standard中大数幂运算相关细节,感谢阅读点赞。