Implementing Montogomery Modular Reduction/Multiplication (MMM) - rsa

I have been trying to implement Montogomery Modular Reduction in Verilog and encountered an error while doing so. Attaching the code below-
module MMM ( a , b , c , y ) ;
// Parameters
//
parameter N = 32 ; // Default value of N
// Inputs
//
input [N-1:0] a ; // N-bit input a
input [N-1:0] b ; // N-bit input b
input [N-1:0] c ; // N-bit input c
// Outputs
//
output [N-1:0] y ; // N-bit output y
// Internal nets
//
wire [N-1:0] q ; // N-bit q array
//wire [N+1:0] t [0:N-1] ; // (N+2)-bit temporary iteration variable t, bus array of N
wire [N+1:0] s ; //
// Initial value of S
//
assign s[0] = 0 ;
// Iteration
//
genvar i ;
generate
for ( i = 0 ; i <= N-1 ; i = i + 1 )
begin : iterate
assign q[i] = (s[i] + a[i] * b) % 2;
assign s[i+1] = (s[i] + q[i] * c + a[i] * b) / 2;
if (s[N] >= c)
assign y = s[N] - c ;
else
assign y = s[N] ;
end // iterate
endgenerate
//assign MMM[a, b, c] = y;
endmodule
The error- The generate if condition must be a constant expression.
Any help would be great.
Thanks

The problem is that if inside a generate must be decidable at compilation time, you are using a signal as a condition of the if block. I understand that what you mean is to create a mux with that expression in the selector, but the compiler don't.
you could wrap the iterate logic in a procedural always block and then you would be able to use the if statement.
Also, the assignment to y should be outside the iterate block, otherwise it will have multiple drivers.
Fixing these two problems you have
module MMM ( a , b , c , y ) ;
// Parameters
//
parameter N = 32 ; // Default value of N
// Inputs
//
input [N-1:0] a ; // N-bit input a
input [N-1:0] b ; // N-bit input b
input [N-1:0] c ; // N-bit input c
// Outputs
//
output [N-1:0] y ; // N-bit output y
// Internal nets
//
wire [N-1:0] q ; // N-bit q array
//wire [N+1:0] t [0:N-1] ; // (N+2)-bit temporary iteration variable t, bus array of N
wire [N+1:0] s ; //
// Initial value of S
//
assign s[0] = 0 ;
// Iteration
//
genvar i ;
generate
for ( i = 0 ; i <= N-1 ; i = i + 1 )
begin : iterate
assign q[i] = (s[i] + a[i] * b) % 2;
assign s[i+1] = (s[i] + q[i] * c + a[i] * b) / 2;
end // iterate
endgenerate
assign y = s[N] >= c ? s[N] - c : s[N];
//assign MMM[a, b, c] = y;
endmodule
Disclaimer: Maybe there are more errors, I did not notice.

Related

Merge sort in scilab

I implemented merge sort in scilab with the following code:
function x = mergesortre (x)
n = length (x);
if ( n > 1 ) then
m = floor (n/2);
p = n-m;
x1 = mergesortre ( x(1:m) );
x2 = mergesortre ( x(m+1:n) );
x = merge ( x1 , x2 );
end
endfunction
function [x] = merge ( x1 , x2 )
n1 = length (x1);
n2 = length (x2);
n = n1 + n2;
x = [];
i = 1
j = 1
k = 1
while(j<=n1 && k<=n2)
if x1(j)>=x2(k)
x(i)=x2(k);
k=k+1;
i=i+1;
elseif x1(j)<x2(k)
x(i)=x1(j);
j=j+1;
i=i+1;
end
end
if (j > n1) then
x(i+1:n) = x2(k:n2);
else
x(i+1:n) = x1(j:n1);
end
endfunction
a=[5,4,3,2,1];
x=mergesortre(a);
disp x;
However in when i try to see the sorted array using the terminal window its showing only the first element,for example if my array is [5,4,3,2,1] its only giving output as 1. I need help understanding what i did wrong.
Your error is in the merge function. As i is already incremented at the end of the loop you have to concatenate starting at i:
if (j > n1) then
x(i:n) = x2(k:n2);
else
x(i:n) = x1(j:n1);
end
A recursive algorithm needs a termination condition. There is no such condition in your function mergesortre. It's likely because the declaration of your function does not used the input argument x. Try to change it like this:
function [a] = mergesortre ( a )
I guess you wanted to use a as an input and output argument.

Error in code, a method to compute sqrt (a)

One of the methods to compute sqrt(a), a>0 is
X(n+1) = (a + (X(n)*X(n-1))/(X(n)+X(n-1)), n = 1, 2, …,
with X0=1 and X1=a (That is, it is known that lim n-> infin of Xn = sqrt(a)
Write a function [sqa, nitr] = mySqrt(a) which implements this calculation. The function should use a while-loop, terminate when the difference between Xn+1 and Xn becomes smaller than eps(10*a), and output Xn+1 in sqa and the value of n at which the while-loop was terminated in nitr. Test your function for a = 103041.
I have written this but it does not work
function [sqa, nitr] = mySqrt (a)
%[sqa, nitr] = mySqrt (a)
% computes square root of a
% sqa = a;
sqaprev = a;
nitr = 0;
X(n+1) = (a + (X(n)*X(n-1))/(X(n)+X(n-1))); %find the second term
sqa= X(n+1)
while abs (sqaprev-sqa) >= eps (10*a)
sqaprev = sqa;
sqa = (1/2) *(sqaprev+ (a/sqaprev));
nitr = nitr + 1;
end %while
end
i get the error:
Unrecognized function or variable 'X'.
Error in mySqrt (line 7)
X(n+1) = (a + (X(n)*X(n-1))/(X(n)+X(n-1))); %find the second term
Could someone help me ?
You should start with declaring your variables and assigning them values
X(1)=1;
X(2)=a;
n=2;
Then in the loop you apply the given recursion formula, not the Heron/Babylonian formula that got from somewhere else.
According to the algorithm you presented for the square root, you can try the code below
function [sqa, n] = mySqrt(a)
n = 2; % start from 2
X = [1,a]; % initial value for sequence X
while true % repeat procedure until termination condition is reached
X(n+1) = (a + (X(n)*X(n-1)))/(X(n)+X(n-1)); % update sequence X by assigning new values
if abs(X(n+1)-X(n)) <= eps(10*a) % termination condition
break;
end
n = n + 1;
end
sqa = X(end); % return the last element of X as the square root
end
such that
>> [sqa,n] = mySqrt(a)
sqa = 321.00
n = 20

Trapezodial Rule Matlab

I am completing an assignment for a class. We were to follow a flow chart to find the values for the trap rule code. I believe the problem is with my main code.
I am not sure if there is a problem with my function code or my main code, any help would be appreciated.
when I run the section, it display the function as the answer
The following is my mainscript code:
f = #(x) (4*sin (x)) / (exp(2*x)) ;
trap_haskell(f , 0 , 3 , 7)
The rest is my trapezoidal rule code
function [f] = trap_haskell(f, a, b, n)
x = a ;
h = (b - a) / n ;
s = f (a) ;
for k=1:1:n-1
x = x + h ;
s = s + 2 * f(x) ;
end
s = s + f(b) ;
I = (b - a) * s / (2 * n) ;
end
You're returning f as the output argument of trap_haskell which is the input function into trap_haskell itself. The variable I in your code actually stores the integral so it's simply a matter of changing the output variable of the function definition to return the integral instead:
%// ------ Change here
%// |
%// V
function [I] = trap_haskell(f, a, b, n)

Have to convert Integer to binary

I'm writing a user-defined function to convert integers to binary. The largest number that could be converted with the function should be a binary number with
16 1 s. If a larger number is entered as d, the function should display an error
message. With my code, I'm trying to add the numbers 0 or 1 to my vector x based on the remainder, then I want to reverse my final vector to display a number in binary. Here's what I have:
function [b] = bina(d)
% Bina is a function that converts integers to binary
x = [];
y = 2;
in = d/2;
if d >=(2^16 -1)
fprintf('This number is too big')
else
while in > 1
if in >= 1
r = rem(in,y);
x = [x r]
end
end
end
end
As you insist on a loop:
x = [];
y = 2;
in = d;
if d >=(2^16 -1)
fprintf('This number is too big')
else
ii = 1;
while in > 0
r = logical(rem(in,y^ii));
x = [r x];
in = in - r*2^(ii-1);
ii = ii+1;
end
end
b = x;
You had the right ideas, but you need to update the variables in your while-loop with every iteration. This is mainly in, where you need to subtract the remainder. And just store the binary remainders in your variable x.
You can check your result with
x = double( dec2bin(d, 16) ) - 48
You could also use a for loop, by pre-calculating the number of iterations with
find( d < 2.^(1:16),1)
and then
if d >=(2^16 -1)
fprintf('This number is too big')
else
for ii = 1:find( d < 2.^(1:16),1)
r = logical(rem(in,y^ii));
x = [r x];
in = in - r*2^(ii-1)
end
end

lapack - addressing for fully packed rectangular format

I would like to use the LAPACK routines for factorisation and inversion of matrices using the fully packed rectangular format, as this requires only n(n+1)/2 elements to be stored for a symmetric nxn matrix. So far, I am setting up the matrix in 'packed' format and transform it calling routine DTPTTF. However, this requires a second array. I would like to build my matrix directly in fully packed rectangular format (to save on space) - is there an 'addressing' function which will give me the position of the i,j-th element? or could somebody point me to the relevant formula?
to partly answer my own question: inspecting the source code of DTPTTF and the example given therein, I've worked out the adress for one of the four possible constellations (the only one I need), namely uplo ='L' and trans ='N'. below is my fortran function:
! ==================================== ! returns address for RFP format
integer function ijfprf( ii, jj, n ) ! for row jj and column ii
! ==================================== ! for UPLO = 'L' and TRANSR = 'N' only!
implicit none
integer, intent(in) :: ii, jj, n
integer :: i, j, k, n1, k1
if( ii <= jj ) then
i = ii; j = jj
else
i = jj; j = ii
end if
k = n/2
if( mod(n,2) == 0 ) then ! n even
n1 = n + 1
if( i <= k ) then
ijfprf = 1 + (i - 1) * n1 + j
else
ijfprf = ( j - k - 1 ) * n1 + i - k
end if
else ! n odd
k1 = k + 1
if( i > k1 ) then
ijfprf = ( j - k1 ) * n + i - k1
else
ijfprf = ( i - 1 ) * n + j
end if
end if
return
end function ijfprf