ECDSA—模逆模块
在有限域Fp上的非零元素a的逆记为a-1mod p 。即在有限域Fp上存在唯一的一个元素x,使得ax恒等于1(mod p),则元素x为a的逆a-1 。本次设计采用扩展的整数Euclidean算法来求逆元。
扩展的整数Euclidean算法可参考该网站:https://www.cnblogs.com/GjqDream/p/11537934.html
本博文主要介绍verilog实现该算法。
根据模块化的设计思想,设计该模块接口定义如下:

|
信号名 |
方向 |
位宽 |
端口定义 |
|
clk |
Input |
1 |
时钟 |
|
reset |
Input |
1 |
复位 |
|
Inv_en |
Input |
1 |
模逆使能信号 |
|
Inv_in |
Input |
512 |
待求逆信号 |
|
Inv_out |
output |
256 |
模逆结果 |
|
Inv_done |
output |
1 |
模逆完成标识 |
二进制扩展Euclidean算法
输入:模逆使能信号inv_en,整数0<a<p
输出:a-1mod p
- u=a,v=p,A=1,C=0;
- 若 ,重复执行步骤2,否则直接返回C=0
2.1. 若u为偶数,重复执行2.1节
2.1.1. u=u/2。
2.1.2. 若A为偶数,则A=A/2,否则A=(A+P)/2。
2.2. 若v为偶数,重复执行2.2节
2.2.1. v=v/2。
2.2.2. 若C为偶数,则C=C/2;否则C=(C+P)/2。
2.3. 若 ,则u=u-v,A=A-C;否则v=v-u,C=C-A。
3.返回(C mod p)。
为验证模逆算法正确性,我们选取一个简单的椭圆曲线进行验证,选取的曲线为见以往算法模块,其中a = 4; p = 29
选用输入inv_in = 15,仿真结果为2,15*2=30 mod 29 = 1(mod29),结果正确。

代码如下:
module mod_inv (
input clk,
input reset,
input mod_inv_en,
input mod_inv_end,
input [511:0] in,
input [255:0] params_p,
output [255:0] out,
output mod_inv_done
); /*Since Z = 2 for the case of binary polynomials, all divisions can be preformed via a right shift, and all
**divisibility checks can be preformed by checking the least signifigant bit.
**Since the only elliptic curve operations we have to worry about are point doubling and point adding, we're
**not concerned with numbers greater than 2P, which will be limited to 257 bits
**
**UPDATE 11/22: Ditched that assumption, now allows inputs up to 512 bits instead of 257
*/ //parameter params_p = 256'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F; //Control Signals
reg u_load, v_load, g1_load, g2_load, count_load;
reg [511:0] u_in, v_in, g1_in, g2_in;
reg [10:0] count_in;
reg mod_inv_done_r;
reg [255:0] out_r;
wire [511:0] u_out,v_out,g1_out,g2_out;
wire [10:0] count_out; //state machine states
reg [2:0] state, next_state;
parameter Init = 3'd0;
parameter Start = 3'd1;
parameter Check_u = 3'd2;
parameter Check_v = 3'd3;
parameter Check_deg = 3'd4;
parameter Wait = 3'd5;
parameter Finish = 3'd6; //Register Instatntations
reg_256 #(512) u(.clk(clk), .load(u_load), .data(u_in), .out(u_out));
reg_256 #(512) v(.clk(clk), .load(v_load), .data(v_in), .out(v_out));
reg_256 #(512) g1(.clk(clk), .load(g1_load), .data(g1_in), .out(g1_out));
reg_256 #(512) g2(.clk(clk), .load(g2_load), .data(g2_in), .out(g2_out)); reg_256 #(11) counter(.clk(clk), .load(count_load), .data(count_in), .out(count_out)); //state machine behavior
always@(posedge clk) begin
if(reset)
state <= Init;
else
state <= next_state;
end //Next state Logic
always@(*) begin
next_state = state;
case(state)
Init: if(mod_inv_en && in != 0 )
next_state = Start;
else if(mod_inv_en && in == 0 )
next_state = Finish;
else
next_state = Init;
Start: begin
if(u_out == 512'b01 || v_out == 512'b01)
next_state = Wait;
else if(u_out[0] == 0)
next_state = Check_u;
else if(v_out[0] == 0)
next_state = Check_v;
else
next_state = Check_deg;
end
Check_u: begin
if(u_out[0] == 0)
next_state = Check_u;
else if(v_out[0] == 0)
next_state = Check_v;
else
next_state = Check_deg;
end
Check_v: begin
if(v_out[0] == 0)
next_state = Check_v;
else
next_state = Check_deg;
end
Check_deg:
next_state = Start;
Wait:
if(count_out == 11'd470) next_state = Finish;
Finish:
next_state = mod_inv_end ? Init : Finish;
default:
next_state = Init;
endcase
end always@(*) begin
//Default values
u_in = u_out;
v_in = v_out;
g1_in = g1_out;
g2_in = g2_out;
u_load = 1'b0;
v_load = 1'b0;
g1_load = 1'b0;
g2_load = 1'b0;
out_r = 256'b0;
mod_inv_done_r = 1'b0;
count_load = 1'b1;
count_in = count_out + 1;
//Preform algorithm steps
case(state)
Init: begin
u_in = in;
v_in = params_p;
mod_inv_done_r = 1'b0;
g1_in = 512'b01;
g2_in = 512'b0;
u_load = 1'b1;
v_load = 1'b1;
g1_load = 1'b1;
g2_load = 1'b1;
count_in = 0;
end
Start:begin end
Check_u: begin
u_in = u_out>>1; //Divide by z (z=2)
if(g1_out[0] == 0)
g1_in = g1_out>>1;
else
g1_in = (g1_out + params_p)>>1;
if(u_out != 512'b01 && u_out[0] == 0) begin
u_load = 1'b1;
g1_load = 1'b1;
end
end
Check_v: begin
v_in = v_out>>1;
if(g2_out[0] == 0)
g2_in = g2_out>>1;
else
g2_in = (g2_out + params_p)>>1;
if(v_out != 512'b01 && v_out[0] == 0) begin
v_load = 1'b1;
g2_load = 1'b1;
end
end
Check_deg: begin //Checks if deg(u) > deg(v)
if(u_out > v_out && u_out >= ((v_out<<1) - v_out)) begin
u_in = u_out + v_out;
g1_in = g1_out + g2_out;
u_load = 1'b1;
g1_load = 1'b1;
end
else begin
v_in = v_out + u_out;
g2_in = g2_out + g1_out;
v_load = 1'b1;
g2_load = 1'b1;
end
end
Wait:
if(count_out != 11'd470)
count_in = count_out + 1;
Finish: begin
mod_inv_done_r = 1'b1;
if(in == 0)
out_r = 0;
else if(u_out == 512'b01 && in != 0)
out_r = g1_out[255:0];
else if(u_out != 512'b01 && in != 0)
out_r = g2_out[255:0];
else
out_r = g2_out[255:0];
end
default: begin end
endcase
end
assign out = (state==Finish)? out_r : 0;
assign mod_inv_done = (state==Finish)? mod_inv_done_r : 0;
endmodule
ECDSA—模逆模块的更多相关文章
- ECDSA—模乘模块
如果a,b属于GF(P),则有乘法运算a*b=r (mod p), 其中r满足0<r<p-1,即a*b除以p的余数.该操作成为模p乘法.本模块输入两个数,完成两个数的模乘运算. 信号名 方 ...
- 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进行签名,并将消息 ...
- v0lt CTF安全工具包
0×00 v0lt v0lt是一个我尝试重组每一个我使用过的/现在在使用的/将来要用的用python开发的安全领域CTF工具.实践任务可能会采用bash脚本来解决,但我认为Python更具有灵活性,这 ...
- C/C++大数库简介
在网络安全技术领域中各种加密解密算法的软件实现上始终有一个共同的问题就是如何在普通的PC机上实现大数的运算.我们日常生活中所应用的PC机内部字长多是32位或64位,但是在各种加密解密的算法中为了达到一 ...
- TensorFlow API 汉化
TensorFlow API 汉化 模块:tf 定义于tensorflow/__init__.py. 将所有公共TensorFlow接口引入此模块. 模块 app module:通用入口点脚本. ...
- 利用system generator 生成vivado ip—以低通滤波器举例
前段时间自学了matlab和vivado联合推出的system generator工具,用来做数字信号处理,十分好用且使开发更便捷,下面举个例子来供大家一起学习下. 首先打开matlab命令行,输入s ...
- 常见C内存管理程序
本文主要关注的是C内存管理程序,比较著名的几个C内存管理程序,其中包括: l Doug Lea Malloc:Doug Lea Malloc实际上是完整的一组分配程序,其中包括Doug Lea的原 ...
- 2014 Hangjs 见闻流水账第一天
前言 6月21日~6月22日, 第一次跑远门去参加一个大会(广州 -> 杭州),本来打算,在火车的回来的路上,把这两天的东西记录一下,不过,火车上的环境实在恶劣,同时也高估了自己的专注力,所以, ...
随机推荐
- Java代码操作zookeeper
.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...
- rancher清理主机脚本
#!/bin/bash #From:rancher #date:2019-10-18 #admin:jarno # 停止服务 systemctl disable kubelet.service sys ...
- Ivy入门笔记
安装过程 命令行安装 下载和安装JDK5.Eclipse3.5.Ant 1.8.Ivy 2.2: 安装JDK:成功标志:在命令行下运行java命令,得到java命令行帮助: 安装Ant:解压Ant,在 ...
- WPF listbox 实现动态滚轮下拉定位
private ObservableCollection<keymodel> _listlua; public ObservableCollection<keymodel> l ...
- PHPMailer 远程命令执行漏洞 Writeup
漏洞概述 1.漏洞简介 PHPMailer 小于5.2.18的版本存在远程代码执行漏洞.成功利用该漏洞后,攻击者可以远程任意代码执行.许多知名的 CMS 例如 Wordpress 等都是使用这个组件来 ...
- Nebula 2.5.0安装过程及遇到的坑
2021年8月23日,Nebula 发布了最新版本:2.5.0,正好赶上新环境部署,记录一下安装过程及遇到的坑: 一.准备工作 以下安装使用nebula用户,搭建集群模式,一共三台机器:192.168 ...
- 《手把手教你》系列技巧篇(二十)-java+ selenium自动化测试-元素定位大法之终卷(详细教程)
1.简介 这篇文章主要是对前边的文章中的一些总结和拓展.本来是不打算写着一篇的,但是由于前后文章定位元素的时间有点长,怕大家忘记了,就在这里简单做一个总结和拓展. 2.Selenium八种定位方式 S ...
- .Net Core WebApi(三)--使用 IdentityServer4 4.1.1 踩坑记录
目的:创建IdentityServer 并通过PostMan验证获取token 第一次配置如下 public class Config { public static IEnumerable<A ...
- jsoup的Node类
一.简介 Node类直接继承Object,实现了Cloneable接口,它是一个抽象类,类声明:public abstract class Node extends Object implements ...
- 【小技巧】排名前 16 的 Java 工具类!
转自java技术栈: https://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247485460&idx=1&sn=cef ...