URL
https://opencores.org/ocsvn/ecg/ecg/trunk
Subversion Repositories ecg
[/] [ecg/] [trunk/] [rtl/] [ecg.v] - Rev 19
Go to most recent revision | Compare with Previous | Blame | View Log
/* Copyright 2011, City University of Hong Kong Author is Homer (Dongsheng) Hsing. This file is part of Elliptic Curve Group Core. Elliptic Curve Group Core is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Elliptic Curve Group Core is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Elliptic Curve Group Core. If not, see http://www.gnu.org/licenses/lgpl.txt */ `include "inc.v" /* point scalar multiplication on the elliptic curve $y^2=x^3-x+1$ over a Galois field GF(3^M) * whose irreducible polynomial is $x^97 + x^12 + 2$. */ /* $P3(x3,y3) == c \cdot P1(x1,y1)$ */ module point_scalar_mult(clk, reset, x1, y1, zero1, c, done, x3, y3, zero3); input clk, reset; input [`WIDTH:0] x1, y1; input zero1; input [`SCALAR_WIDTH:0] c; output reg done; output reg [`WIDTH:0] x3, y3; output reg zero3; reg [`WIDTH:0] x2, y2; reg zero2; // accumulator reg [`WIDTH:0] x4, y4; reg zero4; // doubler wire [`WIDTH:0] x5, y5; wire zero5; // the first input of the adder wire [`WIDTH:0] x6, y6; wire zero6; // the second input of the adder wire [`WIDTH:0] x7, y7; wire zero7; // the output of the adder reg [`SCALAR_WIDTH : 0] k; // the scalar value wire fin; // asserted if job done reg op; wire p, p2, rst, done1, lastbit; assign lastbit = k[0]; assign fin = (k == 0); assign x5 = op ? x4 : x2; assign y5 = op ? y4 : y2; assign zero5 = op ? zero4 : zero2; assign {x6,y6} = {x4,y4}; assign zero6 = ((~op)&(~lastbit)) ? 1 : zero4; assign rst = reset | p2 ; point_add ins1 (clk, rst, x5, y5, zero5, x6, y6, zero6, done1, x7, y7, zero7); func6 ins2 (clk, reset, done1, p), ins3 (clk, reset, p, p2); always @ (posedge clk) if (reset) k <= c; else if (op & p) k <= k >> 1; always @ (posedge clk) if (reset) op <= 0; else if (p) op <= ~op; always @ (posedge clk) if (reset) begin x2 <= 0; y2 <= 0; zero2 <= 1; end else if ((~op) & p) begin {x2,y2,zero2} <= {x7,y7,zero7}; end always @ (posedge clk) if (reset) begin {x4,y4,zero4} <= {x1,y1,zero1}; end else if (op & p) begin {x4,y4,zero4} <= {x7,y7,zero7}; end always @ (posedge clk) if (reset) begin x3 <= 0; y3 <= 0; zero3 <= 1; done <= 0; end else if (fin) begin {x3,y3,zero3} <= {x2,y2,zero2}; done <= 1; end endmodule /* add two points on the elliptic curve $y^2=x^3-x+1$ over a Galois field GF(3^M) * whose irreducible polynomial is $x^97 + x^12 + 2$. */ /* $P3(x3,y3) == P1 + P2$ for any points $P1(x1,y1),P2(x2,y2)$ */ module point_add(clk, reset, x1, y1, zero1, x2, y2, zero2, done, x3, y3, zero3); input clk, reset; input [`WIDTH:0] x1, y1; // this guy is $P1$ input zero1; // asserted if P1 == 0 input [`WIDTH:0] x2, y2; // and this guy is $P2$ input zero2; // asserted if P2 == 0 output reg done; output reg [`WIDTH:0] x3, y3; // ha ha, this guy is $P3$ output reg zero3; // asserted if P3 == 0 wire [`WIDTH:0] x3a, x3b, x3c, y3a, y3b, y3c, ny2; wire zero3a, done10, // asserted if $ins10$ finished done11; reg use1, // asserted if $ins9$ did the work cond1, cond2, cond3, cond4, cond5; f3m_neg ins1 (y2, ny2); // ny2 == -y2 func9 ins9 (x1, y1, zero1, x2, y2, zero2, x3a, y3a, zero3a); func10 ins10 (clk, reset, x1, y1, done10, x3b, y3b); func11 ins11 (clk, reset, x1, y1, x2, y2, done11, x3c, y3c); always @ (posedge clk) if (reset) begin use1 <= 0; cond1 <= 0; cond2 <= 0; cond3 <= 0; cond4 <= 0; cond5 <= 0; end else begin use1 <= zero1 | zero2; cond1 <= (~use1) && cond2 && cond4; // asserted if $P1 == -P2$ cond2 <= (x1 == x2); cond3 <= (y1 == y2); cond4 <= (y1 == ny2); cond5 <= (~use1) && cond2 && cond3; // asserted if $P1 == P2$ end always @ (posedge clk) if (reset) zero3 <= 0; else zero3 <= (use1 & zero3a) | cond1; // if both of $P1$ and $P2$ are inf point, or $P1 == -P2$, then $P3$ is inf point always @ (posedge clk) if (reset) done <= 0; else done <= (use1 | cond1) ? 1 : (cond5 ? done10 : done11); always @ (posedge clk) if (reset) begin x3 <= 0; y3 <= 0; end else begin x3 <= use1 ? x3a : (cond5 ? x3b : x3c); y3 <= use1 ? y3a : (cond5 ? y3b : y3c); end endmodule /* $P3 == P1+P2$ */ /* $P1$ and/or $P2$ is the infinite point */ module func9(x1, y1, zero1, x2, y2, zero2, x3, y3, zero3); input [`WIDTH:0] x1, y1, x2, y2; input zero1; // asserted if P1 == 0 input zero2; // asserted if P2 == 0 output [`WIDTH:0] x3, y3; output zero3; // asserted if P3 == 0 assign zero3 = zero1 & zero2; genvar i; generate for (i=0; i<=`WIDTH; i=i+1) begin:label assign x3[i] = (x2[i] & zero1) | (x1[i] & zero2); assign y3[i] = (y2[i] & zero1) | (y1[i] & zero2); end endgenerate endmodule /* $P3 == P1+P2$ */ /* $P1$ or $P2$ is not the infinite point. $P1 == P2$ */ module func10(clk, reset, x1, y1, done, x3, y3); input clk, reset; input [`WIDTH:0] x1, y1; output reg done; output reg [`WIDTH:0] x3, y3; wire [`WIDTH:0] v1, v2, v3, v4, v5, v6; wire rst2, done1, done2; reg [2:0] K; f3m_inv ins1 (clk, reset, y1, v1, done1); // v1 == inv y1 f3m_mult ins2 (clk, rst2, v1, v1, v2, done2); // v2 == v1^2 f3m_cubic ins3 (v1, v3); // v3 == v1^3 f3m_add ins4 (x1, v2, v4), // v4 == x1+v2 == x1 + (inv y1)^2 ins5 (y1, v3, v5); // v5 == y1+v3 == y1 + (inv y1)^3 f3m_neg ins6 (v5, v6); // v6 == -[y1 + (inv y1)^3] func6 ins7 (clk, reset, done1, rst2); always @ (posedge clk) if (reset) K <= 3'b100; else if ((K[2]&rst2)|(K[1]&done2)|K[0]) K <= K >> 1; always @ (posedge clk) if (reset) begin done <= 0; x3 <= 0; y3 <= 0; end else if (K[0]) begin done <= 1; x3 <= v4; y3 <= v6; end endmodule /* $P3 == P1+P2$ */ /* $P1$ or $P2$ is not the infinite point. $P1 != P2, and P1 != -P2$ */ module func11(clk, reset, x1, y1, x2, y2, done, x3, y3); input clk, reset; input [`WIDTH:0] x1, y1, x2, y2; output reg done; output reg [`WIDTH:0] x3, y3; wire [`WIDTH:0] v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; wire rst2, rst3, done1, done2, done3; reg [3:0] K; f3m_sub ins1 (x2, x1, v1), // v1 == x2-x1 ins2 (y2, y1, v2); // v2 == y2-y1 f3m_inv ins3 (clk, reset, v1, v3, done1); // v3 == inv v1 == inv(x2-x1) f3m_mult ins4 (clk, rst2, v2, v3, v4, done2), // v4 == v2*v3 == (y2-y1)/(x2-x1) ins5 (clk, rst3, v4, v4, v5, done3); // v5 == v4^2 f3m_cubic ins6 (v4, v6); // v6 == v4^3 f3m_add ins7 (x1, x2, v7), // v7 == x1+x2 ins8 (y1, y2, v8); // v8 == y1+y2 f3m_sub ins9 (v5, v7, v9), // v9 == v5-v7 == v4^2 - (x1+x2) ins10 (v8, v6, v10); // v10 == (y1+y2) - v4^3 func6 ins11 (clk, reset, done1, rst2), ins12 (clk, reset, done2, rst3); always @ (posedge clk) if (reset) K <= 4'b1000; else if ((K[3]&rst2)|(K[2]&rst3)|(K[1]&done3)|K[0]) K <= K >> 1; always @ (posedge clk) if (reset) begin done <= 0; x3 <= 0; y3 <= 0; end else if (K[0]) begin done <= 1; x3 <= v9; y3 <= v10; end endmodule
Go to most recent revision | Compare with Previous | Blame | View Log