如果a,b属于GF(P),则有乘法运算a*b=r (mod p),

其中r满足0<r<p-1,即a*b除以p的余数。该操作成为模p乘法。本模块输入两个数,完成两个数的模乘运算。

信号名

方向

位宽

端口定义

clk

Input

1

时钟

reset

Input

1

复位

multip_en

Input

1

模乘使能信号

a

Input

256

整数乘数a

b

Input

256

整数乘数b

product

output

256

模乘运算结果

done

output

1

模乘完成标识

算法:模乘运算算法

输入:a,b∈ [0,n-1], multip_en

输出:product, done

  1. 初始化product,product=0;
  2. 对于i从0到t-1,重复执行

    2.1.  若bi=1,则product=product + a<<1;

  1. Product = product mod p;
  2. 返回product。

代码如下:

module mod_multiplier(
input clk, reset,
input [255:0] a,
input [255:0] b,
output reg [255:0] product,
output reg done
);
/* multiplication using bit shifting and adding */
parameter params_p=29;
//parameter params_p = 256'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F; reg [510:0] a_in, count_in;
reg [510:0] b_in,c_in;
reg a_load, b_load, c_load, count_load;
wire [510:0] a_out, count_out;
wire [510:0] b_out, c_out; reg_256 #(511) a_reg(.clk(clk), .load(a_load), .data(a_in), .out(a_out));
reg_256 #(511) b_reg(.clk(clk), .load(b_load), .data(b_in), .out(b_out));
reg_256 #(511) c_reg(.clk(clk), .load(c_load), .data(c_in), .out(c_out));
reg_256 #(511) count(.clk(clk), .load(count_load), .data(count_in), .out(count_out)); reg [2:0] state, next_state;
parameter init = 3'd0;
parameter start = 3'd1;
parameter shift_AB = 3'd2;
parameter reduce_B = 3'd3;
parameter reduce_C = 3'd4;
parameter finish = 3'd5; always@(posedge clk) begin
if(reset)
state <= init;
else
state <= next_state;
end always@(*) begin
next_state = state;
case(state)
init:
next_state = start;
start:
next_state = shift_AB;
shift_AB: begin
if((b_out << 1) >= {255'b0,params_p})
next_state = reduce_B;
else
next_state = reduce_C;
end
reduce_B: begin
if(b_out >= {255'b0,params_p})
next_state = reduce_B;
else
next_state = reduce_C;
end
reduce_C: begin
if(count_out == 8'd254)
next_state = finish;
else
next_state = shift_AB;
end
finish:
next_state = finish;
default: ;
endcase
end always@(*) begin
count_in = count_out;
b_in = b_out;
c_in = c_out;
a_in = a_out; count_load = 1'b0;
a_load = 1'b0;
b_load = 1'b0;
c_load = 1'b0;
product = 256'b0;
done = 1'b0; case(state)
init: begin
done = 1'b0;
count_in = 8'b0;
a_in = a;
b_in = {2'b0, b};
c_in = 510'b0; count_load = 1'b1;
a_load = 1'b1;
b_load = 1'b1;
c_load = 1'b1;
end
start: begin
if(a[0] == 1)
c_in = b_out;
else
c_in = 510'b0;
c_load = 1'b1;
end
shift_AB: begin
a_in = a_out >> 1;
a_load = 1'b1;
b_load = 1'b1;
b_in = b_out << 1;
end
reduce_B: begin
b_load = 1'b1;
if(b_out >= {255'b0, params_p})
b_in = b_out - {255'b0,params_p};
else
b_in = b_out;
end
reduce_C: begin
c_load = 1'b1;
if(a_out[0] == 1'b1) begin
if((c_out + b_out) >= {255'b0, params_p})
c_in = (c_out + b_out) - {255'b0, params_p};
else
c_in = c_out + b_out;
end
else begin
if(c_out >= {255'b0, params_p})
c_in = c_out - params_p;
else
c_in = c_out;
end
count_in = count_out + 8'b01;
count_load = 1'b1;
end
finish: begin
if(c_out < params_p) begin
done = 1'b1;
product = c_out[255:0];
end
else begin
c_in = c_out - {255'b0,params_p};
c_load = 1'b1;
done = 1'b0;
end
end
default: ;
endcase
end endmodule

其中reg256.v模块为暂存模块,主要是暂时存储一下temp reg。

代码如下:

module reg_256 #(parameter size = 256)
(
input clk, load,
input [size-1:0] data,
output reg [size-1:0] out
); always @ (posedge clk)
begin
if (load)
out <= data;
else
out <= out;
end endmodule

仿真采用一条简单的曲线先验证结果的正确性,再选用spec256k1曲线来测试模乘速率,

其参数如下所示,后面的模块都会采用这两条曲线做仿真验证。此次只需将parameter中的p进行修改即可切换曲线。

sepc256k1曲线参数
p = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F a = 0 b =7 G_x = 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 G_y = 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8 n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 h = 01

testbeach如下所示:

`timescale 1ns/1ns

module mod_multiplier_tb();

    reg clk, reset;
reg [255:0] a, b;
wire [255:0] product;
wire done; mod_multiplier mult0(
.clk(clk),
.reset(reset),
.a(a),
.b(b),
.product(product),
.done(done)
); always #5 clk = ~clk; initial begin
clk = 0; reset = 1'b1;
#6
reset = 1'b0;
a = 12;
b = 25; /*
a = 256'h09;
b = 256'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFE2F;
*/
/*#5200
$display("ad/p=%d",product);
#20
$stop();*/
end endmodule

P=29时:选用的测试数据点为(12,25),12*25=300 mod 29 = 10(mod 29),结果正确。

P=256‘hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F时,

选用测试点为:a = 256'h09;  b = 256'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFE2F;

从时间上来看,运算速率看来跟数的大小无关,而是跟相对于p的大小有关。

ECDSA—模乘模块的更多相关文章

  1. ECDSA—模逆模块

    在有限域Fp上的非零元素a的逆记为a-1mod p .即在有限域Fp上存在唯一的一个元素x,使得ax恒等于1(mod p),则元素x为a的逆a-1 .本次设计采用扩展的整数Euclidean算法来求逆 ...

  2. ECDSA—模加减模块

    如果a,b GF(P),则加法运算a+b=r (mod p),其中r满足0<r<p-1,即a+b除以p的余数,该操作成为模p加法.对于模减运算可以视为另类的模加运算,即a+(-b)=k ( ...

  3. ECDSA高性能硬件实现——算法详解与模块划分

    ECDSA全称椭圆曲线数字签名算法,它是基于素数域的椭圆曲线对信息进行加签与验签.其核心在于对信息的加签,及对加签的信息进行验签,那么下面介绍该算法流程. 假设Alice希望对消息m进行签名,并将消息 ...

  4. 常见C内存管理程序

    本文主要关注的是C内存管理程序,比较著名的几个C内存管理程序,其中包括: l   Doug Lea Malloc:Doug Lea Malloc实际上是完整的一组分配程序,其中包括Doug Lea的原 ...

  5. 2014 Hangjs 见闻流水账第一天

    前言 6月21日~6月22日, 第一次跑远门去参加一个大会(广州 -> 杭州),本来打算,在火车的回来的路上,把这两天的东西记录一下,不过,火车上的环境实在恶劣,同时也高估了自己的专注力,所以, ...

  6. 看到了必须要Mark啊,最全的编程中英文词汇对照汇总(里面有好几个版本的,每个版本从a到d的顺序排列)

    java:  第一章: JDK(Java Development Kit) java开发工具包 JVM(Java Virtual Machine) java虚拟机 Javac  编译命令 java   ...

  7. OpenStack配置解析库oslo.config的使用方法

    OpenStack的oslo项目旨在独立出系统中可重用的基础功能,oslo.config就是其中一个被广泛使用的库,该项工作的主要目的就是解析OpenStack中命令行(CLI)或配置文件(.conf ...

  8. TensorFlow API 汉化

    TensorFlow API 汉化 模块:tf   定义于tensorflow/__init__.py. 将所有公共TensorFlow接口引入此模块. 模块 app module:通用入口点脚本. ...

  9. Java生鲜电商平台-电商促销业务分析设计与系统架构

    Java生鲜电商平台-电商促销业务分析设计与系统架构 说明:Java开源生鲜电商平台-电商促销业务分析设计与系统架构,列举的是常见的促销场景与源代码下载 左侧为享受促销的资格,常见为这三种: 首单 大 ...

随机推荐

  1. Could not connect to 'xxx.xx.xx.xxx' (port 22): Connection failed.

    刚刚使用xshell好好的,突然注销账号,准备重新连接突然连不上了. 这就很尴尬了,对我这种linux菜鸟只能去百度了,终于解决了,赶紧记录下这个坑 1.先登陆虚拟机,输入这段命令 查看ssh服务是否 ...

  2. luogu P2710 数列

    (这是个双倍经验呀! 题目描述 维护一个可以支持插入.删除.翻转.区间赋值.求和.求值和求最大子段和操作的序列.(真·简洁) solution 基本不用什么神奇操作,平衡树硬上就行.(我用的 Spla ...

  3. 「AGC023D」 Go Home

    「AGC023D」 Go Home 传送门 神题. 首先我们可以倒着考虑. 当车到达最后一栋楼的时候,车上一定只有到这栋楼的员工. 当车到达倒数第二栋楼的时候,车上一定只有到达剩下两栋楼的员工. 设这 ...

  4. 教你 PXE高效批量网络装机

    PXE高效批量网络装机一.PXE概述① PXE (Preboot eXcution Environment)② PXE批量部署的优点③ 服务端④ 客户端二.部署PXE远程安装服务搭建PXE远程安装服务 ...

  5. scrapy设置自己的headers referer字段

    1.在middlewares中添加自己的新类: class Mylei(object): def process_request(self,request,spider): referer=reque ...

  6. C语言:体现\r的结果

    #include <stdio.h> #include <windows.h> //体现\r的结果 //转义字符\r,回车,将光标移动到当前行最开始 main() { char ...

  7. PYTHON 解决ModuleNotFoundError: No module named 'win32com'

    d:\python37\scripts\>pip install pypiwin32

  8. Pytest单元测试框架之简单操作示例

    前言: Pytest是第三方单元格测试框架,更加简单,灵活,而且提供了更多丰富的扩展: Pytest与UnitTest框架的区别 UnitTest测试用例执行顺序是依照ascii码执行,而Pytest ...

  9. Requests方法 -- 关联用例执行

    1.参照此篇流程 :Requsts方法 -- Blog流程类进行关联 2.用例接口目录如下: 3.用例代码如下: import requestsimport unittestfrom Request. ...

  10. visibility:hidden和display:none的区别

    一.相同点 disable:none和visibility:hidden都能把网页上的某元素隐藏起来 二.不同点 display:none--不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失. ...