密码学基础算法(二)中国剩余定理
随便谷歌了一个图片做首图
原图地址: http://www.siwapu.com/etagid41968b0/
密码学基础系列:
- (一) 基于整数的欧几里得算法和扩展欧几里得算法
- (二) 中国剩余定理
- (三) 扩展域 GF(2n)GF(2^n)GF(2n) 上的多项式运算
- (四) 扩展域 GF(2n)GF(2^n)GF(2n) 上的欧几里得算法和扩展欧几里得算法
文章目录
- 1. 问题
- 2. 求解
- 3. 代码
- 4. 测试代码和示例
- 5. 中国剩余定理的应用
- 6. 完整代码
- 7. 其它
看书自学的一个比较大的问题就是,一旦对书中的问题有疑问,尤其是一些小的细节,很难找到人答疑。
学习中国剩余定理时(CRT: Chinese Reminder Theorem),一直有点迷糊,没有完全明白中国剩余定理到底如何用。
陆续看了一些资料,
- 《深入浅出密码学》中没有对中国剩余定理的证明,只在 7.5.2 节中提到使用中国剩余定理快速加密
- 《密码编码学与网络安全》各版本(包括六/七/八版)中,对中国剩余定理的描述相当复杂(也可能是我太蠢了)
- 《数论概论》第三版第 11 章中,只说了中国剩余定理的表述,没有提供完整计算方式
- 《密码学原理与实践》第三版中,第 5.2.2 节对中国剩余定理有详细的证明和描述,是我见过最易懂的说明。
这里摘录一下《密码学原理与实践》中关于中国剩余定理的描述(第5.2.2节):
(中国剩余定理) 假定m1,m2,...,mrm_1, m_2, ..., m_rm1,m2,...,mr为两两互素的正整数,又假定a1,a2,...,ara_1, a_2, ..., a_ra1,a2,...,ar为整数。那么同余方程组:
x≡ai(modmi)(1≤i≤r)x\equiv a_i(mod\ m_i)(1\le i \le r)x≡ai(mod mi)(1≤i≤r) 有模 M=m1×m2×...×mrM=m_1 \times m_2 \times ... \times m_rM=m1×m2×...×mr的唯一解,此解由下式给出:
x=∑i=1raiMiyimodMx = \sum_{i=1}^{r}{a_iM_iy_i}\ mod\ M x=i=1∑raiMiyi mod M
其中, Mi=M/miM_i = M\ /\ m_iMi=M / mi,且yi=Mi−1modmi,1≤i≤ry_i=M_i^{-1}\ mod\ m_i, 1 \le i \le ryi=Mi−1 mod mi,1≤i≤r
从定理出发,明确了定义之后,就容易计算了。
这里以《孙子算经》中的原文为例:
今有物不知其数,三三数之余二,五五数之余三,七七数之余二,问物几何?
1. 问题
这个问题翻译过来就是:
已知 3 个同余方程组:
- 2≡xmod3,3≡xmod5,2≡xmod72\equiv x\ mod\ 3,\quad 3\equiv x\ mod\ 5,\quad 2\equiv x\ mod\ 72≡x mod 3,3≡x mod 5,2≡x mod 7,
求xxx。
从条件得知:
- (m1,m2,m3)⇒(3,5,7)(m_1, m_2, m_3)\Rightarrow(3, 5, 7)(m1,m2,m3)⇒(3,5,7),即m1=3,m2=5,m3=7m_1=3,\ m_2=5,\ m_3=7m1=3, m2=5, m3=7
- (a1,a2,a3)⇒(2,3,2)(a_1, a_2, a_3)\Rightarrow(2, 3, 2)(a1,a2,a3)⇒(2,3,2),即a1=2,a2=3,a3=2a_1=2,\ a_2=3,\ a_3=2a1=2, a2=3, a3=2
2. 求解
第一步,计算同余方程组的模M=m1×m2×...×mrM=m1 \times m2 \times ... \times m_rM=m1×m2×...×mr
- M=m1×m2×m3=3×5×7=105M=m_1 \times m_2 \times m_3 = 3 \times 5 \times 7 = 105M=m1×m2×m3=3×5×7=105
第二步,求MiM_iMi及其基于mim_imi的逆元Mi−1M_i^{-1}Mi−1和yiy_iyi
这里的逆元Mi−1M_i^{-1}Mi−1使用《密码学基础算法(一)基于整数的欧几里得算法和扩展欧几里得算法》一文中求逆的函数int int_inv(int a, int b)
来求取。
- M1=M/m1=105/3=35M_1=M\ /\ m_1 = 105 / 3 = 35M1=M / m1=105/3=35, M1−1=int_inv(M1,m1)=int_inv(35,3)=2M_1^{-1}=int\_inv(M_1,m_1)=int\_inv(35,3)=2M1−1=int_inv(M1,m1)=int_inv(35,3)=2, y1=M1−1modm1=2mod3=2y_1=M_1^{-1}\ mod\ m_1=2\ mod\ 3=2y1=M1−1 mod m1=2 mod 3=2
- M2=M/m2=105/5=21M_2=M\ /\ m_2 = 105 / 5 = 21M2=M / m2=105/5=21, M2−1=int_inv(M2,m2)=int_inv(21,5)=1M_2^{-1}=int\_inv(M_2,m_2)=int\_inv(21,5)=1M2−1=int_inv(M2,m2)=int_inv(21,5)=1, y2=M2−1modm2=1mod5=1y_2=M_2^{-1}\ mod\ m_2=1\ mod\ 5=1y2=M2−1 mod m2=1 mod 5=1
- M3=M/m3=105/7=15M_3=M\ /\ m_3 = 105 / 7 = 15M3=M / m3=105/7=15, M3−1=int_inv(M3,m3)=int_inv(15,7)=1M_3^{-1}=int\_inv(M_3,m_3)=int\_inv(15,7)=1M3−1=int_inv(M3,m3)=int_inv(15,7)=1, y3=M3−1modm3=1mod7=1y_3=M_3^{-1}\ mod\ m_3=1\ mod\ 7=1y3=M3−1 mod m3=1 mod 7=1
第三步,根据第二步计算的M/Mi/yiM/M_i/y_iM/Mi/yi,使用中国剩余定理的公式求xxx
x=∑i=1raiMiyimodM=(a1M1y1+a2M2y2+a3M3y3)mod105=(2×35×2+3×21×1+2×15×1)mod105=(140+63+30)mod105=233mod105=23x = \sum_{i=1}^{r}{a_iM_iy_i}\ mod\ M = (a_1M_1y_1 + a_2M_2y_2 + a_3M_3y_3)\ mod\ 105\\= (2 \times 35 \times 2 + 3 \times 21 \times 1 + 2 \times 15 \times 1)\ mod\ 105 \\= (140 + 63 + 30)\ mod\ 105\\=233\ mod\ 105 \\= 23 x=i=1∑raiMiyi mod M=(a1M1y1+a2M2y2+a3M3y3) mod 105=(2×35×2+3×21×1+2×15×1) mod 105=(140+63+30) mod 105=233 mod 105=23
所以最后得到要求的数为 23。
3. 代码
我们可以根据前面的计算过程将其翻译成代码
/*** @description: 中国剩余定理(CRT: Chinese Reminder Theorem)求同余方程解* @param {int} 指针 m, 指向整型数组, 包含每一组除数* @param {int} 指针 r, 指向整型数组, 包含每一组余数* @param {int} 整数 n, 指定传入指针 m 和 r 指向数组的大小* @return {*} 中国剩余定理的同余方程解*/
int crt(int *m, int *r, int n)
{int i;int M, Mi, yi;int sum;// 计算同于方程组的模 MM = 1;for (i=0; i<n; i++){M *= m[i];}sum = 0;for (i=0; i<n; i++){// 计算每一个 MiMi = M / m[i];// 计算每一个 yiyi = int_inv(Mi, m[i]) % m[i];// 累积求和sum += r[i] * Mi * yi;}return sum % M;
}
其中调用的函数int_inv
来自《密码学基础算法(一)基于整数的欧几里得算法和扩展欧几里得算法》,专门用于求整数的乘法逆元,如下:
/*** @description: 基于扩展欧几里得算法计算整数 a 关于 整数 b 的乘法逆元(展开 int_gcd_ex 后的优化版本)* @param {int} a 整数 a* @param {int} b 整数 b* @return {*} 返回整数 a 关于整数 b 的最小正整数乘法逆元, 乘法逆元不存在(gcd(a, b) != 1)则返回 0;*/
int int_inv(int a, int b)
{int x, x0, x1;int q, r, t;/* 消除警告: "warning: ‘x’ may be used uninitialized in this function" */x = 0;/* 初始化最初两项系数 */x0 = 1;x1 = 0;/* 临时保存 b */t = b;q = a / b;r = a % b;while (r != 0){/* 计算当前项 x */x = x0 - q * x1;/* 依次保存前两项到 x0, x1 */x0 = x1; x1 = x;a = b;b = r; /* 前一次的余数 */q = a / b;r = a % b;}/* gcd(a, b) != 1, 没有乘法逆元 */if (b != 1){return 0;}/* 调整小于 0 的情况 */if (x < 0){x += t;}return x;
}
4. 测试代码和示例
- 测试代码
int main(int argc, char *argv[])
{int m1[3] = { 3, 5, 7}, r1[3] = { 2, 3, 2}; // 示例1: 孙子算经int m2[3] = { 7, 11, 13}, r2[3] = { 5, 3, 10}; // 示例2: 《密码学原理与实践》第三版, p133, 例 5.3int m3[3] = {25, 26, 27}, r3[3] = {12, 9, 23}; // 示例3: 《密码学原理与实践》第三版, p178, 题 5.6int m4[2] = {37, 49}, r4[2] = {11, 42}; // 示例4: 《密码编码学与网络安全》第七版, p37, 示例int res;res = crt(m1, r1, 3);printf("同余方程组: 除数{ 7, 11, 13}, 余数{ 5, 3, 10}的解为 %d\n", res);res = crt(m2, r2, 3);printf("同余方程组: 除数{ 3, 5, 7}, 余数{ 2, 3, 2}的解为 %d\n", res);res = crt(m3, r3, 3);printf("同余方程组: 除数{25, 26, 27}, 余数{12, 9, 23}的解为 %d\n", res);res = crt(m4, r4, 2);printf("同余方程组: 除数{37, 49}, 余数{11, 42} 的解为 %d\n", res);return 0;
}
- 编译和运行
$ gcc crt.c -o crt
$ ./crt
同余方程组: 除数{ 7, 11, 13}, 余数{ 5, 3, 10}的解为 23
同余方程组: 除数{ 3, 5, 7}, 余数{ 2, 3, 2}的解为 894
同余方程组: 除数{25, 26, 27}, 余数{12, 9, 23}的解为 14387
同余方程组: 除数{37, 49}, 余数{11, 42} 的解为 973
5. 中国剩余定理的应用
根据《密码编码学与网络安全》中的说明,运用中国剩余定理,使得模 M 的大数运算可以转化为相对较小的数的运算。当 M 为 150 位或 150 位以上时,这种方法特别有效。
例如:
973 对 37 和 49 取模分别为: 973mod37=11,973mod49=42973\ mod\ 37\ =\ 11,\ 973\ mod\ 49\ =\ 42973 mod 37 = 11, 973 mod 49 = 42,因此把 973 表示为(11, 42)的形式。
假如要计算 678 + 973 = 1651, 用处理 973 的办法同样处理 678: 678mod37=12,678mod49=41678\ mod\ 37=\ 12,\ 678\ mod\ 49=\ 41678 mod 37= 12, 678 mod 49= 41,因此把 678 表示为(12, 41)
然后将上面得到的两个二元组的元素相加并化简:
1651=973+678=((11+12)mod37,(42+41)mod49)=(23,34)1651=973+678=((11+12)\ mod\ 37, (42+41)\ mod\ 49)=(23, 34)1651=973+678=((11+12) mod 37,(42+41) mod 49)=(23,34)
从上面的例子可以看到,大数 1651 (其实很小) 对 37 和 49 取模转换成了小数 973 和 678 对 37 和 49 取模。
虽然看起来计算量差不多,但是对很大的数,前面提到的 150 位或更多这种,转换成两个数乘积的形式,新的数短一半,再进行操作是很有优势的。
6. 完整代码
#include <stdio.h>/*** @description: 基于扩展欧几里得算法计算整数 a 关于 整数 b 的乘法逆元(展开 int_gcd_ex 后的优化版本)* @param {int} a 整数 a* @param {int} b 整数 b* @return {*} 返回整数 a 关于整数 b 的最小正整数乘法逆元, 乘法逆元不存在(gcd(a, b) != 1)则返回 0;*/
int int_inv(int a, int b)
{int x, x0, x1;int q, r, t;/* 消除警告: "warning: ‘x’ may be used uninitialized in this function" */x = 0;/* 初始化最初两项系数 */x0 = 1;x1 = 0;/* 临时保存 b */t = b;q = a / b;r = a % b;while (r != 0){/* 计算当前项 x */x = x0 - q * x1;/* 依次保存前两项到 x0, x1 */x0 = x1; x1 = x;a = b;b = r; /* 前一次的余数 */q = a / b;r = a % b;}/* gcd(a, b) != 1, 没有乘法逆元 */if (b != 1){return 0;}/* 调整小于 0 的情况 */if (x < 0){x += t;}return x;
}/*** @description: 中国剩余定理(CRT: Chinese Reminder Theorem)求同余方程解* @param {int} 指针 m, 指向整型数组, 包含每一组除数* @param {int} 指针 r, 指向整型数组, 包含每一组余数* @param {int} 整数 n, 指定传入指针 m 和 r 指向数组的大小* @return {*} 中国剩余定理的同余方程解*/
int crt(int *m, int *r, int n)
{int i;int M, Mi, yi;int sum;// 计算同于方程组的模 MM = 1;for (i=0; i<n; i++){M *= m[i];}sum = 0;for (i=0; i<n; i++){// 计算每一个 MiMi = M / m[i];// 计算每一个 yiyi = int_inv(Mi, m[i]) % m[i];// 累积求和sum += r[i] * Mi * yi;}return sum % M;
}int main(int argc, char *argv[])
{int m1[3] = { 3, 5, 7}, r1[3] = { 2, 3, 2}; // 示例1: 孙子算经int m2[3] = { 7, 11, 13}, r2[3] = { 5, 3, 10}; // 示例2: 《密码学原理与实践》第三版, p133, 例 5.3int m3[3] = {25, 26, 27}, r3[3] = {12, 9, 23}; // 示例3: 《密码学原理与实践》第三版, p178, 题 5.6int m4[2] = {37, 49}, r4[2] = {11, 42}; // 示例4: 《密码编码学与网络安全》第七版, p37, 示例int res;res = crt(m1, r1, 3);printf("同余方程组: 除数{ 7, 11, 13}, 余数{ 5, 3, 10}的解为 %d\n", res);res = crt(m2, r2, 3);printf("同余方程组: 除数{ 3, 5, 7}, 余数{ 2, 3, 2}的解为 %d\n", res);res = crt(m3, r3, 3);printf("同余方程组: 除数{25, 26, 27}, 余数{12, 9, 23}的解为 %d\n", res);res = crt(m4, r4, 2);printf("同余方程组: 除数{37, 49}, 余数{11, 42} 的解为 %d\n", res);return 0;
}
7. 其它
洛奇工作中常常会遇到自己不熟悉的问题,这些问题可能并不难,但因为不了解,找不到人帮忙而瞎折腾,往往导致浪费几天甚至更久的时间。
所以我组建了几个微信讨论群(记得微信我说加哪个群,如何加微信见后面),欢迎一起讨论:
- 一个密码编码学讨论组,主要讨论各种加解密,签名校验等算法,请说明加密码学讨论群。
- 一个Android OTA的讨论组,请说明加Android OTA群。
- 一个git和repo的讨论组,请说明加git和repo群。
在工作之余,洛奇尽量写一些对大家有用的东西,如果洛奇的这篇文章让您有所收获,解决了您一直以来未能解决的问题,不妨赞赏一下洛奇,这也是对洛奇付出的最大鼓励。扫下面的二维码赞赏洛奇,金额随意:
洛奇自己维护了一个公众号“洛奇看世界”,一个很佛系的公众号,不定期瞎逼逼。公号也提供个人联系方式,一些资源,说不定会有意外的收获,详细内容见公号提示。扫下方二维码关注公众号:
密码学基础算法(二)中国剩余定理相关推荐
- 信息安全基础综合实验-中国剩余定理
最近没有什么事情,打算把之前的作业整理一下发出来,有需要的学弟学妹们可以参考一下. 相关:某电的密码学实验,信安专业必选实验 实验题目:中国剩余定理 实验目的 (包括实验环境.实现目标等等) 实验环境 ...
- 密码学基础——辗转相除法,费马小定理,欧拉定理,裴蜀定理,中国剩余定理
文章主要根据百度百科和维基百科相关相关知识点整理而成! 辗转相除法 辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法.它的具体做法是:用较小数除较大数 ...
- 从孙子算经到中国剩余定理
中国剩余定理中间涉及一个重要观念:互质: 首先来看<孙子算经>卷下第二十六问:今有物,不知其数.三.三数之,剩二:五.五数之,剩三:七.七数之,剩二.问物几何? 转换为数学语言即是(理解其 ...
- 扩展欧几里得算法、乘法逆元与中国剩余定理
文章目录 前言 定义.定理和部分证明 整除 定义 定理 定理的证明 同余 定义 同余的性质 同余的运算律 运算律的证明 扩展欧几里得算法 代码模板 算法详解 乘法逆元 求解逆元 乘法逆元的作用 中国剩 ...
- 中国剩余定理Chinese remainder theorem(CRT)
中国剩余定理 孙子定理, Chinese remainder theorem(CRT) 参考 : 百度百科-中国剩余定理 有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二.问物几何? x=2mo ...
- 中国剩余定理matlab程序,中国剩余定理即孙子定理的五种解法
中国剩余定理即孙子定理的五种解法 -- 学习初等数论心得笔记 2013-10-04 博文2015-12修改 "中国剩余定理"是公元5-6世纪.我国南北朝时期的一部著名算术著作< ...
- 基于Miracl库的中国剩余定理C语言实现
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/tch3430493902/articl ...
- 数论一之定理证明——裴蜀/威尔逊/费马/扩展欧几里得/[扩展]欧拉/[扩展]中国剩余定理,欧拉函数,逆元,剩余系,筛法
打死没想到会在H老师处学懂数论 同余,整除 模运算 埃式筛法 欧拉筛法 最大公约数和最小公倍数 辗转相除法 更相减损术 裴蜀定理 威尔逊定理 费马定理 同余等价类.剩余系.缩系 欧拉函数 欧拉定理 扩 ...
- 信奥中的数学:孙子定理 中国剩余定理
孙子定理 中国剩余定理 孙子定理 中国剩余定理_Dreamer Thinker Doer-CSDN博客 中国剩余问题(简介+详解) 中国剩余问题(简介+详解)_dreamzuora的博客-CSDN博客 ...
最新文章
- 支持向量机原理(五)线性支持回归
- JavaScript判断是否是手机mobile登录
- 油田智能化远程监控系统_十种远程无线视频监控系统拓扑图
- Pivotal发布Spring Cloud Data Flow 1.5版本
- 实践编译LINUX0.11源码,感觉真爽。
- springmvc 拦截器_Spring MVC拦截器学习
- 2019 d serv 激活_化疗过程中肌肉减少症的发生机制及维生素D、ω-3脂肪酸的作用...
- 一个JSP大马的源码
- ES6-ES11新特性_ECMAScript相关名词介绍_---JavaScript_ECMAScript工作笔记002
- 手机浏览器被强制跳转_Azure front door 强制http redirect to https
- CSS规则重要性以及继承、层叠
- 老板下死命令:必须将20M文件从30秒压缩到1秒,我是如何做到的?
- 洛谷P3233 [HNOI2014]世界树
- Hibernate配置文件,映射文件
- java怎么设置_java环境配置怎么设置?Java基础教程
- mysql怎么导出insert语句_mysql导出insert语句
- 阿帕奇服务器配置站点,Apache的基本服务器配置
- s3c6410裸机调试方式总结
- 个税计算公式excel_我月薪1万,为啥个税只交150块捏?
- 考考你的基础知识:C++ 文件操作ofstream、ifstream使用
热门文章
- 从1万到100万的理财法则
- 叉乘点乘混合运算公式_用抽象指标记号推导nabla算符相关公式
- Vivado HLS常用优化命令介绍
- 自然语言处理中CNN模型几种常见的Max Pooling操作
- 毕得医药递交科创板注册:年营收6亿 拟募资4.34亿
- SpringCloud调用接口流程
- 运维体系建设(第二章)
- mysql主备集群(高可用)
- 从0开始编写一个应用(android端+小程序端+服务器端)第二步 项目经理完成逻辑图。(下:产品细节思考后的实现逻辑图)
- 神一般的科学“超人”尼古拉-特斯拉!