文件
PazeSSH/include/paze/bignum.h
T

102 行
4.5 KiB
C

/* bignum.h —— 定长大数运算(RSA/ECDSA/DH 所需)
*
* 设计:
* - 定长 uint32_t limb 数组,小端序(limb[0] 为最低位)。
* - 固定上限 PAZE_BN_MAX_LIMBS,覆盖 RSA-4096 与中间积。
* - 始终非负(RSA/ECDSA 模运算不需要负数)。
* - 乘法用 schoolbook O(n^2),模幂用 Montgomery 加速。
*
* limb 数上限说明:
* RSA-4096 模数 = 128 limb;两数相乘 = 256 limb。
* 故普通 bignum 容量 130 limb(余量),乘积用 260 limb 临时缓冲。
*/
#ifndef PAZE_BIGNUM_H
#define PAZE_BIGNUM_H
#include "paze/paze_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PAZE_BN_MAX_BITS 4160 /* 4096 + 64 余量 */
#define PAZE_BN_MAX_LIMBS (PAZE_BN_MAX_BITS / 32) /* 130 */
#define PAZE_BN_MUL_LIMBS (PAZE_BN_MAX_LIMBS * 2) /* 260, 乘积临时 */
/* 大数:定长 limb 数组 + 有效 limb 数。始终非负。n==0 表示 0。 */
typedef struct {
uint32_t d[PAZE_BN_MAX_LIMBS];
int n; /* 有效 limb 数(高位在前的计数,limb[n-1] 为最高有效) */
} paze_bn_t;
/* ---- 初始化与赋值 ---- */
void paze_bn_init(paze_bn_t *a);
void paze_bn_zero(paze_bn_t *a);
void paze_bn_copy(paze_bn_t *dst, const paze_bn_t *src);
int paze_bn_set_u32(paze_bn_t *a, uint32_t v);
int paze_bn_set_u64(paze_bn_t *a, uint64_t v);
/* 从大端字节序列导入(如 RSA 模数的字节表示) */
int paze_bn_from_bytes(paze_bn_t *a, const uint8_t *be, size_t len);
/* 导出为大端字节序列,左侧补零到 len 字节。len 不足返回 PAZE_ERR_SHORT */
int paze_bn_to_bytes(const paze_bn_t *a, uint8_t *be, size_t len);
/* 十六进制字符串导入/导出(调试与测试用) */
int paze_bn_from_hex(paze_bn_t *a, const char *hex);
size_t paze_bn_to_hex(const paze_bn_t *a, char *out, size_t outlen);
/* ---- 查询 ---- */
int paze_bn_is_zero(const paze_bn_t *a) ;
int paze_bn_is_one(const paze_bn_t *a);
int paze_bn_cmp(const paze_bn_t *a, const paze_bn_t *b); /* -1/0/1 */
int paze_bn_bit_len(const paze_bn_t *a); /* 最高位 +1, 0 返回 0 */
int paze_bn_bit(const paze_bn_t *a, int pos); /* pos 位的值 0/1 */
size_t paze_bn_byte_len(const paze_bn_t *a); /* 最少字节数 */
/* ---- 基本运算 ---- */
/* r = a + b */
int paze_bn_add(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *b);
/* r = a - b (要求 a >= b,否则返回 PAZE_ERR_INVALID) */
int paze_bn_sub(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *b);
/* r = a + b,允许进位扩展。r 与 a/b 可别名 */
int paze_bn_rshift(paze_bn_t *r, const paze_bn_t *a, int bits);
int paze_bn_lshift(paze_bn_t *r, const paze_bn_t *a, int bits);
/* r = a * b (schoolbook)。r 不能与 a/b 别名 */
int paze_bn_mul(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *b);
/* q = a / b, r = a mod b。q 或 r 可为 NULL(不计算)。b==0 返回错误 */
int paze_bn_divmod(paze_bn_t *q, paze_bn_t *r,
const paze_bn_t *a, const paze_bn_t *b);
/* ---- 模运算 ---- */
/* r = a mod m (结果 0 <= r < m) */
int paze_bn_mod(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *m);
/* r = (a + b) mod m */
int paze_bn_modadd(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *b,
const paze_bn_t *m);
/* r = (a - b) mod m (结果非负) */
int paze_bn_modsub(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *b,
const paze_bn_t *m);
/* r = (a * b) mod m */
int paze_bn_modmul(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *b,
const paze_bn_t *m);
/* r = (base ^ exp) mod m。Montgomery 加速,m 须为奇数 */
int paze_bn_modexp(paze_bn_t *r, const paze_bn_t *base, const paze_bn_t *exp,
const paze_bn_t *m);
/* r = a^(-1) mod m (扩展欧几里得)。要求 gcd(a,m)=1 */
int paze_bn_modinv(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *m);
/* r = gcd(a, b) */
int paze_bn_gcd(paze_bn_t *r, const paze_bn_t *a, const paze_bn_t *b);
/* ---- 随机与素数 ---- */
/* 生成 bits 位的随机数,最高位置 1(保证位数) */
int paze_bn_random_bits(paze_bn_t *a, int bits);
/* 生成 [0, m) 范围内均匀随机数 */
int paze_bn_random_range(paze_bn_t *a, const paze_bn_t *m);
/* Miller-Rabin 素性测试,rounds 轮。返回 1=可能素数, 0=合数 */
int paze_bn_is_prime(const paze_bn_t *a, int rounds);
/* 生成 bits 位的素数(e 用于确保 gcd(p-1, e)=1)。最多尝试 max_tries 次 */
int paze_bn_gen_prime(paze_bn_t *p, int bits, uint32_t e, int max_tries);
#ifdef __cplusplus
}
#endif
#endif /* PAZE_BIGNUM_H */