基于STM32与Mbed框架的RSA-CRT项目:大整数串口打印故障排查
解决STM32F103 + Mbed框架下mini-gmp大整数串口打印问题
我之前做嵌入式密码学项目时也碰到过一模一样的问题——mini-gmp的默认输出函数和Mbed的串口系统不兼容,直接调用mpz_out_str根本出不来内容。结合你的RSA-CRT项目场景,给你两个实用的解决方案:
先把你的测试代码补全,方便对照问题:
#include <mbed.h> #include <mini-gmp.h> Serial pc(USBTX, USBRX); int main() { pc.baud(115200); pc.printf("Starting RSA-CRT Test...\r\n"); mpz_t big_num; mpz_init_set_str(big_num, "123456789012345678901234567890", 10); // 这里直接用mpz_out_str(stdout, 10, big_num)会无效 pc.printf("Big Number: [无法正确输出]\r\n"); mpz_clear(big_num); while(1); }
方案一:转成C字符串再打印(最简单直接)
mini-gmp提供了mpz_get_str函数,可以把大整数转换成普通C字符串,再用Mbed自带的printf打印就行,代码如下:
#include <mbed.h> #include <mini-gmp.h> #include <cstring> Serial pc(USBTX, USBRX); int main() { pc.baud(115200); pc.printf("Starting RSA-CRT Test...\r\n"); mpz_t big_num; mpz_init_set_str(big_num, "123456789012345678901234567890", 10); // 转换大整数为十进制字符串,NULL表示让函数自动分配内存 char* num_str = mpz_get_str(NULL, 10, big_num); if (num_str != nullptr) { pc.printf("Big Number: %s\r\n", num_str); free(num_str); // 必须手动释放内存,避免堆溢出 } else { pc.printf("Error: Failed to convert big integer to string\r\n"); } mpz_clear(big_num); // 别忘了清理mini-gmp的变量 while(1); }
这个方法不需要修改标准IO流,直接适配Mbed的串口系统,适合嵌入式小内存场景。重点提醒:一定要释放mpz_get_str分配的内存,否则运行久了会出现内存泄漏。
方案二:重定向标准输出到串口(适配mini-gmp原生函数)
如果你习惯用mini-gmp的mpz_out_str等原生输出函数,可以把Mbed的串口绑定到标准输出流(stdout),只需要重写fputc函数就行:
#include <mbed.h> #include <mini-gmp.h> #include <cstdio> Serial pc(USBTX, USBRX); // 重写fputc,让stdout和stderr的输出都转到串口 int fputc(int ch, FILE* stream) { if (stream == stdout || stream == stderr) { pc.putc(static_cast<char>(ch)); return ch; } return EOF; } int main() { pc.baud(115200); pc.printf("Starting RSA-CRT Test...\r\n"); mpz_t big_num; mpz_init_set_str(big_num, "123456789012345678901234567890", 10); // 现在可以直接用mini-gmp的输出函数了 pc.printf("Big Number: "); mpz_out_str(stdout, 10, big_num); // 输出到stdout就是输出到串口 pc.printf("\r\n"); mpz_clear(big_num); while(1); }
这样之后,所有依赖标准输出的函数(包括printf、mpz_out_str)都会把内容打到串口控制台,适合需要频繁使用mini-gmp输出函数的场景。
额外注意事项
- 如果你处理的是2048位以上的RSA大模数,转换后的字符串会很长,要确保STM32的堆空间足够(可以在Mbed Studio的项目配置里调整堆大小,一般设成2KB以上就够)
- 每次使用完
mpz_t变量后,一定要调用mpz_clear释放内存,mini-gmp不会自动回收这些资源 - 测试时先从小的整数开始验证打印是否正确,再逐步替换成RSA-CRT中的实际密钥和模数
内容的提问来源于stack exchange,提问作者namron
相关产品推荐
相关产品推荐

