模重复平方计算法

一、问题描述

在模算数计算中,我们常常要对大整数模m和大整数n,计算bn(mod m).如果递归计算bn = (bn-1(mod m))·b(mod m),这种计算较为费事,须作n - 1次乘法。而使用模平方计算法可以显著降低算法复杂度。

二、算法描述

欲求bn(mod m),设a = 1

1. 先将n转换为二进制,即n = n0 + n12 + n222 + ··· + nk-12k-1

2.从低位到高位对n的二进制表示进行遍历

3.如果nk = 1,则a = a·b (mod m),b = b2(mod m);如果nk = 0,则a值保持不变,b = b2(mod m)

4.遍历完成后得到的a值即为所求结果

三、JAVA代码

 1 import java.util.Scanner;
 2 import java.util.ArrayList;
 3 
 4 public class mod2 {
 5 
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8         int n, m, b, a = 1;
 9         String binary;
10         Scanner scan = new Scanner(System.in);
11         System.out.println("Please input args n, m, b:");
12         n = scan.nextInt();
13         m = scan.nextInt();
14         b = scan.nextInt();
15         scan.close();
16         binary = Integer.toBinaryString(n);
17         for (int i = binary.length() - 1 ; i >= 0 ; i--){
18             if (binary.charAt(i) == '1'){
19                 a = (a*b)%m;
20                 b = (b*b)%m;
21             }
22             else{
23                 b = (b*b)%m;
24             }
25         }
26         System.out.println(a);
27     }
28 
29 }

转载于:https://www.cnblogs.com/nipo/p/7723528.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值