第二十三个知识点:写一个实现蒙哥马利算法的C程序

这次博客我将通过对蒙哥马利算法的一个实际的实现,来补充我们上周蒙哥马利算法的理论方面。这个用C语言实现的蒙哥马利算法,是为一个位数为64的计算机编写的。模数\(m\)因此能和\(2^{64}-1\)一样大,\(a\)和\(b\)能和\(m-1\)一样大。我们采用\(r = 2^{64}\)。在之前的博客里,给出的大部分信息都来自于[1],因此请参考这里的信息。

在读过上次博客后,你知道我们需要四个步骤。为了我们的目的,我们将这些分为三个阶段。

1.The GCD Operation

这个函数用了二进制扩展欧几里得算法,找出一个\(r^{-1}\)和\(m^{'}\)使得\(rr^{-1} = 1 + mm^{'}\)。这些整数在后面的算法中需要使用到。算法用\(r^{-1}\)和\(m^{'}\)计算出\(m,m^{'}\),这个博客的目的不是介绍这个二进制扩展欧几里得算法。你想知道的更多可以看链接[1]和[2]。

2.Transform the Multipliers

第二阶段是计算两个值\(abar = ar \mod m\)和\(bbar = br \mod m\).因为\(r = 2^{64}\),这里只需要右移64位。就是输出128位,前64位是\(a,b\)的值,后64位都是0。然后计算\(m\)的模数。这个函数接受64位的\(x\),同时接受低64位的\(y\)和一个\(m\)的值。之后返回一个64位的值。

uint64 modul64(uint64 x, uint64 y, uint64 z);

uint64是这样定义的:

typedef unsigned long long uint64;

3.Montgomery Multiplication

这个函数定义成接受64位的abar,bbar,m和mprime。然后返回64位的值。

首先计算\(t = abar*bbar\)。这个得到一个128位的整数。

然后计算\(u = (t + ( tm^{'} \mod r)*m)/r\)。\(t\)是一个128位的整数。这里就可以计算了。定义如下:

tm = tlo*mprime;
mulul64(tm,m,&tmmhi,%tmmlo);

然后计算:

ulo = tlo + tmmlo;
uhi = thi + tmmhi;
if (ulo < tlo) uhi = uhi +1; // test for overflow from ulo and add if necessary to uhi
ov = (uhi < thi) | ((uhi == thi) & (ulo < tlo)); // check for carry

最后一步约减到\(m\)。

ulo = uhi;
uhi = 0;
if(ov > 0 || ulo >= m) // test if there was overflow or ulo is higher that
ulo = ulo – m;
return ulo;

4.The Inverse Transformation

最后计算\(a*b \mod m = ur^{-1} \mod m\)

调用之前的函数。

mulul64(p, rinv, &phi, &plo); // performs multiplication and returns two 64 bit values phi and plo
p = modul64(phi, plo, m); // returns value of 128bit input mod m

这里\(p\)就是蒙哥马利算法的结果了。

[1] http://www.hackersdelight.org/MontgomeryMultiplication.pdf

[2] http://www.ucl.ac.uk/~ucahcjm/combopt/ext_gcd_python_programs.pdf

第二十三个知识点:写一个实现蒙哥马利算法的C程序的更多相关文章

  1. 五:用JAVA写一个阿里云VPC Open API调用程序

    用JAVA写一个阿里云VPC Open API调用程序 摘要:用JAVA拼出来Open API的URL 引言 VPC提供了丰富的API接口,让网络工程是可以通过API调用的方式管理网络资源.用程序和软 ...

  2. #写一个随机产生138开头手机号的程序 1.输入一个数量,产生xx条手机号 2.产生的这些手机号不能重复

    import randomcount=int(input('请输入你所想要手机号数量:'))prefix='138'for i in range(count): num=random.sample(r ...

  3. python 写一个生成大乐透号码的程序

    """ 写一个生成大乐透号码的程序 生成随机号码:大乐透分前区号码和后区号码, 前区号码是从01-35中无重复地取5个号码, 后区号码是从01-12中无重复地取2个号码, ...

  4. 一道面试题:用shell写一个从1加到100的程序

    [试题描述] 请用shell写一个简短的程序,实现1+2+...+100的功能. [程序] 方法一: #!/bin/bash ..} do let sum+=$i done echo $sum 方法二 ...

  5. 这是第二道题内容要求写一个银行的ATM系统 这个浪费了好长时间 ,遇到了许多问题,不过都解决了,上程序

    下面的4个用户是我宿舍的,当然我是钱最多的,呵呵! #include<iostream>#include<string>using namespace std; class c ...

  6. 第二十八篇 -- 写一个简陋的WIFI服务器界面

    效果图: Dlg.cpp // WIFIWMITestDlg.cpp : implementation file // #include "stdafx.h" #include & ...

  7. 【C#】写一个支持多人聊天的TCP程序

    碎碎念 先谈谈我们要实现的效果:客户端可以选择要聊天的对象,或者直接广播消息(类似QQ的私聊和群消息) 那么,该如何实现呢? 首先明确的是,要分客户端和服务器端两个部分(废话) 客户端:选择要发送的对 ...

  8. 用socket写一个简单的客户端和服务端程序

    用来练手写写socket代码 客户端代码 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h ...

  9. 初学javascript,写一个简单的阶乘算法当作练习

    代码如下: <script> var a = prompt("请输入值"); function mul(a){ if(a==1){ return 1; } return ...

随机推荐

  1. day15 内置函数和模块

    day15 内置函数和模块 1.三元表达式 代码如下: x = 1 y = 2 res = 'ok' if x > y else 'no' print(res) 输出结果:no 2.内置函数:重 ...

  2. Docker快速上手入门

    Docker 什么是Docker? Docker就是一种虚拟化的技术 可以通过Docker快速的下载使用第三方技术,方便搭建环境 目的:Securely build,share and run any ...

  3. nodejs-Child Process模块

    JavaScript 标准参考教程(alpha) 草稿二:Node.js Child Process模块 GitHub TOP Child Process模块 来自<JavaScript 标准参 ...

  4. 源码分析-Consumer

    消息消费概述 消息消费以组的模式开展,一个消费组内可以包含多个消费者,每一个消费者组可订阅多个主题,消费组之间有集群模式和广播模式两种消费模式. 集群模式,主题下的同一条消息只允许被其中一个消费者消费 ...

  5. JavaIO——System对IO的支持、序列化

    1.系统类对IO的支持 在我们学习PriteWriter.PrintStream里面的方法print.println的时候是否观察到其与我们之前一直使用的系统输出很相似呢?其实我们使用的系统输出就是采 ...

  6. java设计模式—Decorator装饰者模式

    一.装饰者模式 1.定义及作用 该模式以对客户端透明的方式扩展对象的功能. 2.涉及角色      抽象构件角色:定义一个抽象接口,来规范准备附加功能的类. 具体构件角色:将要被附加功能的类,实现抽象 ...

  7. ubuntu基础

    下载地址: http://cdimage.ubuntu.com/releases/ #:配置多网卡静态IP地址和路由 root@ubuntu:~# vim /etc/netplan/01-netcfg ...

  8. Oracle带输入输出参数的存储过程

    (一)使用输入参数 需求:在emp_copy中添加一条记录,empno为已有empno的最大值+1,ename不能为空且长度必须大于0,deptno为60. 创建存储过程: create or rep ...

  9. Google Guava 常用集合方法

    /** * Author: momo * Date: 2018/6/7 * Description: */ public class ListTest { public static void mai ...

  10. 使用缓冲流和byte数组,拷贝文件

    package com.itcast.demo05.Buffered;import java.io.*;/** * @author newcityman * @date 2019/7/28 - 17: ...