ECDSA—模乘模块
如果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
- 初始化product,product=0;
- 对于i从0到t-1,重复执行
2.1. 若bi=1,则product=product + a<<1;
- Product = product mod p;
- 返回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—模乘模块的更多相关文章
- ECDSA—模逆模块
在有限域Fp上的非零元素a的逆记为a-1mod p .即在有限域Fp上存在唯一的一个元素x,使得ax恒等于1(mod p),则元素x为a的逆a-1 .本次设计采用扩展的整数Euclidean算法来求逆 ...
- ECDSA—模加减模块
如果a,b GF(P),则加法运算a+b=r (mod p),其中r满足0<r<p-1,即a+b除以p的余数,该操作成为模p加法.对于模减运算可以视为另类的模加运算,即a+(-b)=k ( ...
- ECDSA高性能硬件实现——算法详解与模块划分
ECDSA全称椭圆曲线数字签名算法,它是基于素数域的椭圆曲线对信息进行加签与验签.其核心在于对信息的加签,及对加签的信息进行验签,那么下面介绍该算法流程. 假设Alice希望对消息m进行签名,并将消息 ...
- 常见C内存管理程序
本文主要关注的是C内存管理程序,比较著名的几个C内存管理程序,其中包括: l Doug Lea Malloc:Doug Lea Malloc实际上是完整的一组分配程序,其中包括Doug Lea的原 ...
- 2014 Hangjs 见闻流水账第一天
前言 6月21日~6月22日, 第一次跑远门去参加一个大会(广州 -> 杭州),本来打算,在火车的回来的路上,把这两天的东西记录一下,不过,火车上的环境实在恶劣,同时也高估了自己的专注力,所以, ...
- 看到了必须要Mark啊,最全的编程中英文词汇对照汇总(里面有好几个版本的,每个版本从a到d的顺序排列)
java: 第一章: JDK(Java Development Kit) java开发工具包 JVM(Java Virtual Machine) java虚拟机 Javac 编译命令 java ...
- OpenStack配置解析库oslo.config的使用方法
OpenStack的oslo项目旨在独立出系统中可重用的基础功能,oslo.config就是其中一个被广泛使用的库,该项工作的主要目的就是解析OpenStack中命令行(CLI)或配置文件(.conf ...
- TensorFlow API 汉化
TensorFlow API 汉化 模块:tf 定义于tensorflow/__init__.py. 将所有公共TensorFlow接口引入此模块. 模块 app module:通用入口点脚本. ...
- Java生鲜电商平台-电商促销业务分析设计与系统架构
Java生鲜电商平台-电商促销业务分析设计与系统架构 说明:Java开源生鲜电商平台-电商促销业务分析设计与系统架构,列举的是常见的促销场景与源代码下载 左侧为享受促销的资格,常见为这三种: 首单 大 ...
随机推荐
- docker进入容器所在虚拟机的指令
sudo docker inspect -f {{.State.Pid}} 44fc0f0582d9 在拿到该进程PID之后我们就可以使用nsenter命令访问该容器了. $ sudo nsenter ...
- gitlab用户,组,项目权限管控
前言:gitlab上的权限管控是非常重要的,尤其是很多研发人员开发一个项目.这个是我总结的权限管控. 1.这个是创建项目时开放权限设置 2.这个创建用户设置的权限 3.用户权限,5种类型用户是 ...
- 「AGC010F」 Tree Game
「AGC010F」 Tree Game 传送门 切了一个 AGC 的题,很有精神. 于是决定纪念一下. 首先如果任意一个人在点 \(u\),他肯定不会向点权大于等于 \(a_u\) 的点走的,因为此时 ...
- PYTHON 使用re.findall如果没有引用
python使用re.findall时必须提前import re否则不提示错误,只是找不到结果 import re ab=re.findall('cmp=com.(.*?)/',aa)
- c语言函数的嵌套使用和矩阵运算
这段时间,听刚刚学习c的同学说函数嵌套运用不太熟练,想做一个简单的程序进行练习,我也就当练练手了,哈哈.虽然说是比较简单,但是其中的思维也是值得思考的. 一.函数的嵌套使用 简单说明题目:对于等式 y ...
- [刘阳Java]_为什么要前后端分离
前后端分离已成为互联网项目开发的业界标准使用方式,通过nginx+tomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服务架构.多 ...
- 软件开发(js+java开发)的启发
发现了个很重要的意义 1,一个对象,既包含被监听的参数,也包括监听处理本身 2,基于1的开发模式 3,在函数中定义监听器 4,1)高内聚: 统一面向对象,一个功能一个对象 不同对象不互相调用,不互相引 ...
- Leetcode春季活动打卡第三天:面试题 10.01. 合并排序的数组
Leetcode春季活动打卡第三天:面试题 10.01. 合并排序的数组 Leetcode春季活动打卡第三天:面试题 10.01. 合并排序的数组 思路 这道题,两个数组原本就有序.于是我们采用双指针 ...
- P4774-屠龙勇士-扩展中国剩余定理
屠龙勇士 很久很久以前,巨龙突然出现,带来了灾难带走公主又消失不见.王国十分危险,世间谁最勇敢,一位英雄出现-- 学习于该大佬博客 那么你就是这位英雄,不过不同的是,你面对的是一群巨龙,虽然巨龙都不会 ...
- Python自动化测试面试题-经验篇
目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...