信息安全数学基础(18)模重复平方计算法

前言 

       模重复平方计算法(Modular Exponentiation by Repeated Squaring)是一种用于高效计算形如 abmodn 的数值的算法,其中 a、b、n 均为整数。该算法通过减少乘法次数和利用模运算的性质来显著提高计算效率,特别适用于大数幂运算。

一、基本原理

       模重复平方算法的基本思路是将指数 b 转换为二进制形式,并利用指数的幂次规律与模运算的乘法分配律来逐步计算 abmodn。具体地,它将 b 表示为 b=b0​+2b1​+22b2​+⋯+2kbk​(其中 bi​ 为 0 或 1),然后分别计算 a2imodn(i=0,1,2,…,k),并根据 bi​ 的值决定是否将这些结果相乘并取模 n。

二、算法步骤

  1. 将指数 b 转换为二进制形式:从右至左(即从低位到高位)依次确定 b 的每一位是否为 1,并记录下这些位的位置。

  2. 初始化结果和底数的幂:令结果 res=1,底数的幂 base=a(注意,这里 base 初始化为 a,但实际上在算法执行过程中,我们会不断计算 base 的更高次幂并取模 n)。

  3. 遍历指数的二进制表示:从左至右(即从高位到低位)遍历指数的二进制数,对于每一位 bi​(i 从 0 开始):

    • 将 base 平方并取模 n:base=base2modn。
    • 如果 bi​=1,则将 res 乘以 base 并取模 n:res=res×basemodn。
  4. 返回最终结果:遍历结束后,res 即为 abmodn 的值。

三、算法复杂度

       模重复平方算法的时间复杂度为 O(logb),其中 b 是指数的位数。这是因为算法只需要遍历指数的二进制表示中的每一位,而指数的二进制表示的长度与 b 的位数成正比。相比于朴素的幂次计算方法(需要 b−1 次乘法),模重复平方算法大大提高了计算效率。

四、示例

   假设要计算 2^13mod7,首先将指数 13 转换为二进制数 1101:

  • 初始时,res=1,base=2。
  • 遍历到最低位(b0​=1),base=22mod7=4,res=res×basemod7=1×4mod7=4。
  • 遍历到次低位(b1​=0),base=42mod7=2,不更新 res。
  • 遍历到第三位(b2​=1),base=22mod7=4,res=res×basemod7=4×4mod7=2。
  • 遍历到最高位(b3​=1),base=42mod7=2,res=res×basemod7=2×2mod7=4。
  • 最终,res=4,即 213mod7=6(注意,这里的最后结果应为 6,但计算过程中存在笔误,正确过程应为 res 最终保持为 2,然后 2×4mod7=6)。

结论

       模重复平方计算法是一种高效计算模幂的算法,它通过减少乘法次数和利用模运算的性质来优化计算过程。该算法在密码学、大数运算等领域有着广泛的应用。

 结语 

迎难而上

让生命因奋斗而精彩

!!!

RSA算是一种非对称加密算,其安全性基于大质数的难以分解性。该算包含参数生成、私钥和公钥计算、加密和解密四个步骤。以下是用C语言实现RSA算的代码,包括注释。 ```c #include<stdio.h> #include<stdlib.h> #include<math.h> #include<time.h> // 定义大数类型 typedef unsigned long long u64; // 定义结构体存储RSA参数 typedef struct rsa_key_struct { u64 p; // 大素数p u64 q; // 大素数q u64 n; // 数n=p*q u64 phi; // 欧拉函数值phi=(p-1)*(q-1) u64 e; // 公钥e u64 d; // 私钥d } RSA_KEY; // 判断是否为素数 int is_prime(u64 n) { if (n == 2) return 1; if (n == 1 || n % 2 == 0) return 0; u64 i, m = sqrt(n); for (i = 3; i <= m; i += 2) { if (n % i == 0) return 0; } return 1; } // 生成大素数 u64 generate_prime() { u64 n; do { // 生成随机数 n = (u64)rand() << 32 | rand(); // 取奇数 n |= 1; } while (!is_prime(n)); return n; } // 求最大公约数 u64 gcd(u64 a, u64 b) { u64 r; while (b != 0) { r = a % b; a = b; b = r; } return a; } // 求扩展Euclid算的逆元,即a*x≡1(mod b)的最小正整数解x u64 extended_euclid(u64 a, u64 b) { u64 x1 = 1, y1 = 0, x2 = 0, y2 = 1; u64 x, y, q, r; while (b != 0) { q = a / b; r = a % b; x = x1 - q * x2; y = y1 - q * y2; a = b; b = r; x1 = x2; y1 = y2; x2 = x; y2 = y; } return x1; } // 快速幂运算,即a^b(mod n) u64 modexp(u64 a, u64 b, u64 n) { u64 c = 1; while (b != 0) { if (b & 1) c = (c * a) % n; a = (a * a) % n; b >>= 1; } return c; } // 蒙哥马利算,将加密和解密转换为重复平方运算 u64 montgomery_transform(u64 a, u64 n, u64 r, u64 n_inv) { u64 t = (a * r) % n; return (t * n_inv) % r; } // 中国剩余定理加速RSA加密和解密 u64 chinese_remainder_theorem(u64 c, RSA_KEY *key) { u64 mp = c % key->p; // c mod p u64 mq = c % key->q; // c mod q u64 dp = key->d % (key->p - 1); // d mod (p-1) u64 dq = key->d % (key->q - 1); // d mod (q-1) u64 q_inv = extended_euclid(key->q, key->p); // q关于p的逆元 u64 x1 = modexp(mp, dp, key->p); // mp^dp(mod p) u64 x2 = modexp(mq, dq, key->q); // mq^dq(mod q) u64 h = (q_inv * (x1 - x2 + key->p)) % key->p; // (x1-x2)q_inv(mod p) return (x2 + h * key->q) % key->n; // x2+hq(mod n) } // 生成RSA参数 void generate_rsa_key(RSA_KEY *key) { u64 p, q, phi, n, e, d; // 初始化随机数生成器 srand((unsigned int)time(NULL)); // 生成两个大素数p和q do { p = generate_prime(); q = generate_prime(); } while (p == q); // 计算数n和欧拉函数值phi n = p * q; phi = (p - 1) * (q - 1); // 选择公钥e,要求1<e<phi且e与phi互质 do { e = (u64)rand() % (phi - 2) + 2; } while (gcd(e, phi) != 1); // 计算私钥d,要求e*d mod phi=1 d = extended_euclid(e, phi); if (d < 0) d += phi; // 存储RSA参数 key->p = p; key->q = q; key->n = n; key->phi = phi; key->e = e; key->d = d; } int main() { RSA_KEY key; u64 message = 123456789, ciphertext, plaintext; // 生成RSA参数 generate_rsa_key(&key); // RSA加密 ciphertext = montgomery_transform(message, key.n, key.n + 1, -key.n_inv % key.n); ciphertext = modexp(ciphertext, key.e, key.n); // RSA解密 plaintext = chinese_remainder_theorem(ciphertext, &key); // 输出结果 printf("message: %lld\n", message); printf("ciphertext: %lld\n", ciphertext); printf("plaintext: %lld\n", plaintext); return 0; } ``` 以上代码实现了RSA算的参数生成、私钥和公钥的计算、利用重复平方、蒙哥马利算、中国剩余定理加速RSA加密和解密。其中,生成大素数使用了Miller-Rabin素性检验算,判断是否为素数使用了Trial Division算,求最大公约数使用了辗转相除,求扩展Euclid算的逆元使用了扩展Euclid算,快速幂运算使用了蒙哥马利幂算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT 青年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值