Advanced Encryption Standard (AES) polynomial multiplication in octave / matlab - matlab

I am trying to perform polynomial multiplication as explained in the Advanced Encryption Standard (AES) draft.
Here's what I have so far:
function y = multiply_x2( a )
% a is a 1 x 8 binary vector
% y is a 1 x 8 binary vector
% t is a 1 x 8 binary vector corresponding to the "AES irreducible polynomial"
y = [ a(2:8) 0 ]; % Multiply byte 'a' by 2 using "left shift"
t = [ 0 0 0 a(1) a(1) 0 a(1) a(1) ]; % 't' only becomes the "AES irreducible
% polynomial" if a(1) == 1, otherwise
% it becomes the "zero" byte array
y = mod( y + t , 2 ) ; % XOR operation on y and t, as described in AES.
end
The code above is for
"y = {02} . a"
(where "{}" denotes hexadecimal notation, whose binary representation can be interpreted as the presense of the respective power of x in a polynomial. For example, {02} corresponds to 00000010, which corresponds to the polynomial "x", {06} would correspond to "x2+x", etc, as per the AES docs)
I want to multiply a with 0e , 09 , 0d, and 0b.
How will the code be for each of them? i.e. for:
"y= ( {0e} . a )"
"y= ( {09} . a )"
"y= ( {0d} . a )"
"y= ( {02} . a )"

This was an interesting problem. Here is a general solution for multiplication as defined in the AES doc you linked. I use the name xtime for the {02} multiplication, and I implement "addition" (xadd) as an XOR operation (i.e. !=) directly, since this is easier.
Helper functions:
%% in file isByte.m
function Out = isByte (a)
a = a(:).'; % ensure horizontal vector representation
if all (a == 0 | a == 1) && length (a) == 8; Out = true; return; end
Out = false;
end
%% in file byte2hex.m
function Out = byte2hex (a)
a = a(:).'; % ensure horizontal vector
assert (isByte (a), 'Input needs to be a valid "byte" array');
Out = sum (a .* ([2,2,2,2,2,2,2,2] .^ [7:-1:0])); Out = dec2hex (Out);
end
%% in file hex2byte.m
function Out = hex2byte (h)
assert (isxdigit (h) && hex2dec (h) < 256, 'Input needs to be a valid hex number below FF');
Out = dec2bin (hex2dec (h)); Out = sprintf ('%8s', Out);
Out = Out - 48 ; Out(Out == -16) = 0; % convert spaces to zeros
end
Polynomial functions:
%% in file xadd.m
function Out = xadd (a, b)
a = a(:).'; b = b(:).'; % ensure horizontal vector representations
assert (isByte (a) && isByte (b), 'Inputs need to be valid "byte" arrays');
Out = a != b;
end
%% in file xtime.m
function Out = xtime (a)
a = a(:).'; % ensure horizontal vector
assert (isByte (a), 'Input needs to be a valid "byte" array');
Out = [a(2 : 8), 0]; % left shift
if a(1) == 1
Out = xadd (Out, [0, 0, 0, 1, 1, 0, 1, 1]); % subtract (= add) the AES m(x) polynomial
end
end
% in file xmultiply.m
function Out = xmultiply (a, b)
a = a(:)'; b = b(:)'; % ensure horizontal vector representations
assert (isByte(a) && isByte(b), 'Inputs need to be valid "byte" arrays');
Out = [0,0,0,0,0,0,0,0];
if a == [0, 0, 0, 0, 0, 0, 0, 0] || b == [ 0, 0, 0, 0, 0, 0, 0, 0]; return; end
if b(8) == 1; Out = xadd (Out, a); end % yes this could be done recursively but, why bother.
if b(7) == 1; Out = xadd (Out, xtime (a)); end
if b(6) == 1; Out = xadd (Out, xtime (xtime (a))); end
if b(5) == 1; Out = xadd (Out, xtime (xtime (xtime (a)))); end
if b(4) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (a))))); end
if b(3) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (xtime (a)))))); end
if b(2) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (xtime (xtime (a))))))); end
if b(1) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (xtime (xtime (xtime (a)))))))); end
end
Example use: (same example as in the AES doc)
octave:1> a = hex2byte("57")
a =
0 1 0 1 0 1 1 1
octave:2> b = hex2byte("13")
b =
0 0 0 1 0 0 1 1
octave:3> c = xmultiply(a, b)
c =
1 1 1 1 1 1 1 0
octave:4> byte2hex(c)
ans = FE

In MATLAB/Octave, conv and deconv are respectively correspond to multiplication and (division/modulo) operations for polynomials.
function out = multiply(A, x)
mult = mod(conv(A,x), 2); % poynomial multiplication
[~, modulo] = deconv(mult, [1 0 0 0 1 1 0 1 1]); %modulo operation
out = mod(modulo(end-7:end) , 2); %extract last 8 bits
end
For example to multiply 0x57 and 0x13
a = [1 0 1 0 1 1 1]; %0x57
b = [1 0 0 1 1]; %0x13
result = multiply(a,b)
result =
1 1 1 1 1 1 1 0
that is binary representation of 0xFE

Thank you for your interest. I am trying to implement AES in matlab. And I found the solution in the pages of http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf . Here is the function for the y= ( {09} . a ) multiply operation ;
function y = multiply_x9( a )
% Multiply byte A by 9 over finite field of AES
y2 = multiply_x2( a ) ;
y4 = multiply_x2( y2 ) ;
y8 = multiply_x2( y4 ) ;
y = mod( y8 + a , 2 ) ;
end
And also for the any matrix multiplication multiply_xx (a, b, p ) function can be used. Here is the function;
function y = multiply_xx (a, b, p )
% Determine input lengths and check if they are equal
n = length( a ) ;
if ( n ~= length(b) ) ,
error( 'Operand input lengths not equal to each other!' ) ;
elseif ( n ~= length(p) ) ,
error( 'Operand input lengths not equal to modulus length!' ) ;
end
% Initialize result to zeros and start iteration row by row
y = zeros( 1 , n ) ;
for i = 1 : n ,
m = a(i) * b ;
y = mod( y(1) * p + [ y(2:n) 0 ] + m , 2 ) ;
end
end

Related

Image Transformation Without Loop

I am writing image transformation function in matlab instead of using predefined functions like 'imwarp or imtransform'. I am done with writing the code roughly but it is taking too long due to the use of loop.
Please suggest me a solution which can achieve the same result without loops
function I2 = f_transform(A, I1)
%A is an affine transformation matrix
%I1 is original image to be transformed
s=size(A);
if(s(1)~=3 || s(2)~=3)
disp("Invalid Transforming Matrix");
I2=0;
return;
end
if(det(A)==0)
disp("The given Transforming Matrix is Singular");
I2=0;
return;
end
[r, c]=size(I1);
extremeValues = [1 1 r r ; 1 c 1 c; 1 1 1 1];
newExtremeValues = A * extremeValues;
minRow = floor( min( newExtremeValues(1,:) ) );
maxRow = ceil( max( newExtremeValues(1,:) ) );
minCol = floor( min( newExtremeValues(2,:) ) );
maxCol = ceil( max( newExtremeValues(2,:) ) );
I2 = zeros(maxRow - minRow + 1, maxCol - minCol + 1);
for i = minRow:maxRow
for j=minCol:maxCol
b = A \ [i j 1]';
p = b(1) / b(3);
q = b(2) / b(3);
if(p >= 1 && p <= r && q >= 1 && q <= c)
I2(i - minRow + 1, j - minCol + 1) = I1(round(p),round(q));
end
end
end
I2 = uint8(I2);
return;
end

How can I do vectorization for this matlab "for loop"?

I have some matlab code as follow, constructing KNN similarity weight matrix.
[D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
D = D < threshold;
W = zeros(n, n);
for i=1:size(I,2)
W(I(:,i), i) = D(:,i);
W(i, I(:,i)) = D(:,i)';
end
I want to vectorize the for loop. I have tried
W(I) = D;
but failed to get the correct value.
I add test case here:
n = 5;
D = [
1 1 1 1 1
0 1 1 1 1
0 0 0 0 0
];
I = [
1 2 3 4 5
5 4 5 2 3
3 1 1 1 1
];
There are some undefined variables that makes it hard to check what it is doing, but this should do the same as your for loop:
D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
D = D < threshold;
W = zeros(n);
% set the diagonal values
W(sub2ind(size(X), I(1, :), I(1, :))) = D(1,:);
% set the other values
W(sub2ind(size(W), I(2, :), 1:size(I, 2))) = D(2, :);
W(sub2ind(size(W), 1:size(I, 2), I(2, :))) = D(2, :).';
I splited the directions, it works now with your test case.
A possible solution:
idx1 = reshape(1:n*n,n,n).';
idx2 = bsxfun(#plus,I,0:n:n*size(I,2)-1);
W=zeros(n,n);
W(idx2) = D;
W(idx1(idx2)) = D;
Here assumed that you repeatedly want to compute D and I so compute idx only one time and use it repeatedly.
n = 5;
idx1 = reshape(1:n*n,n,n).';
%for k = 1 : 1000
%[D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
%D = D < threshold;
idx2 = bsxfun(#plus,I,0:n:n*size(I,2)-1);
W=zeros(n,n);
W(idx2) = D;
W(idx1(idx2)) = D;
%end
But if n isn't constant and it varies in each iteration it is better to change the way idx1 is computed:
n = 5;
%for k = 1 : 1000
%n = randi([2 10]);%n isn't constant
%[D,I] = pdist2(X, X, 'squaredeuclidean', 'Smallest', k+1);
%D = D < threshold;
idx1 = bsxfun(#plus,(0:n:n^2-1).',1:size(I,2));
idx2 = bsxfun(#plus,I,0:n:n*size(I,2)-1);
W=zeros(n,n);
W(idx2) = D;
W(idx1(idx2)) = D;
%end
You can cut some corners with linear indices but if your matrices are big then you should only take the nonzero components of D. Following copies all values of D
W = zeros(n);
W(reshape(sub2ind([n,n],I,[1;1;1]*[1:n]),1,[])) = reshape(D,1,[]);

Vectorization in Matlab to speed up expensive loop

How can I speed up the following MATLAB code, using vectorization? Right now the single line in the loop is taking hours to run for the case upper = 1e7.
Here is the commented code with sample output:
p = 8;
lower = 1;
upper = 1e1;
n = setdiff(lower:upper,primes(upper)); % contains composite numbers between lower + upper
x = ones(length(n),p); % Preallocated 2-D array of ones
% This loop stores the unique prime factors of each composite
% number from 1 to n, in each row of x. Since the rows will have
% varying lengths, the rows are padded with ones at the end.
for i = 1:length(n)
x(i,:) = [unique(factor(n(i))) ones(1,p-length(unique(factor(n(i)))))];
end
output:
x =
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
2 3 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
2 5 1 1 1 1 1 1
For example, the last row contains the prime factors of 10, if we ignore the ones. I have made the matrix 8 columns wide to account for the many prime factors of numbers up to 10 million.
Thanks for any help!
This is not vectorization, but this version of the loop will save about half of the time:
for k = 1:numel(n)
tmp = unique(factor(n(k)));
x(k,1:numel(tmp)) = tmp;
end
Here is a quick benchmark for this:
function t = getPrimeTime
lower = 1;
upper = 2.^(1:8);
t = zeros(numel(upper),2);
for k = 1:numel(upper)
n = setdiff(lower:upper(k),primes(upper(k))); % contains composite numbers between lower to upper
t(k,1) = timeit(#() getPrime1(n));
t(k,2) = timeit(#() getPrime2(n));
disp(k)
end
p = plot(log2(upper),log10(t));
p(1).Marker = 'o';
p(2).Marker = '*';
xlabel('log_2(range of numbers)')
ylabel('log(time (sec))')
legend({'getPrime1','getPrime2'})
end
function x = getPrime1(n) % the originel function
p = 8;
x = ones(length(n),p); % Preallocated 2-D array of ones
for k = 1:length(n)
x(k,:) = [unique(factor(n(k))) ones(1,p-length(unique(factor(n(k)))))];
end
end
function x = getPrime2(n)
p = 8;
x = ones(numel(n),p); % Preallocated 2-D array of ones
for k = 1:numel(n)
tmp = unique(factor(n(k)));
x(k,1:numel(tmp)) = tmp;
end
end
Here's another approach:
p = 8;
lower = 1;
upper = 1e1;
p = 8;
q = primes(upper);
n = setdiff(lower:upper, q);
x = bsxfun(#times, q, ~bsxfun(#mod, n(:), q));
x(~x) = inf;
x = sort(x,2);
x(isinf(x)) = 1;
x = [x ones(size(x,1), p-size(x,2))];
This seems to be faster than the other two options (but is uses more memory). Borrowing EBH's benchmarking code:
function t = getPrimeTime
lower = 1;
upper = 2.^(1:12);
t = zeros(numel(upper),3);
for k = 1:numel(upper)
n = setdiff(lower:upper(k),primes(upper(k)));
t(k,1) = timeit(#() getPrime1(n));
t(k,2) = timeit(#() getPrime2(n));
t(k,3) = timeit(#() getPrime3(n));
disp(k)
end
p = plot(log2(upper),log10(t));
p(1).Marker = 'o';
p(2).Marker = '*';
p(3).Marker = '^';
xlabel('log_2(range of numbers)')
ylabel('log(time (sec))')
legend({'getPrime1','getPrime2','getPrime3'})
grid on
end
function x = getPrime1(n) % the originel function
p = 8;
x = ones(length(n),p); % Preallocated 2-D array of ones
for k = 1:length(n)
x(k,:) = [unique(factor(n(k))) ones(1,p-length(unique(factor(n(k)))))];
end
end
function x = getPrime2(n)
p = 8;
x = ones(numel(n),p); % Preallocated 2-D array of ones
for k = 1:numel(n)
tmp = unique(factor(n(k)));
x(k,1:numel(tmp)) = tmp;
end
end
function x = getPrime3(n) % Approach in this answer
p = 8;
q = primes(max(n));
x = bsxfun(#times, q, ~bsxfun(#mod, n(:), q));
x(~x) = inf;
x = sort(x,2);
x(isinf(x)) = 1;
x = [x ones(size(x,1), p-size(x,2))];
end

Matlab if loop function, How to improve this function?

I am new to matlab and I am trying to figure how to write the following function in a smart/efficient way.
First I create a matrix y with entries HL, and every line is a permutation of a predefined length n.
For example, for n=3 I get the first line of the matrix y : H H H. Then I want for each line, to create a matrix of size n x n where for example the entry (1,2) corresponds to a variable which links entry y(1,1) with y(1,2) , and entry y(3,2) corresponds to a variable which links entry y(1,3) with y(1,2). Is this possible?
function A1=mystupidfunction(s , n)
%n is the number of agents and s is the number of state, this function
%returns the matrix of influence. Stupid code must be improved to work for
%n agents
x = 'HL'; %// Set of possible types
K = n; %// Length of each permutation
%// Create all possible permutations (with repetition) of letters stored in x
C = cell(K, 1); %// Preallocate a cell array
[C{:}] = ndgrid(x);
y = cellfun(#(x){x(:)}, C);
y = [y{:}];
A1 = sym('A1',[n n], 'positive' );
syms H L A_HH A_HL A_LH A_LL
for k=s
for i=1:n
for j=1:n
if ( y(k,1)==H) && ( y(k,2)==H) && (y(k,3)==H)
A1(i,j)=A_HH
elseif ( y(k,1)==L) && ( y(k,2)==L) && (y(k,3)==L)
A1(i,j)=A_LL
elseif ( y(k,1)==H) && ( y(k,2)==L) && (y(k,3)==L)
A1(1,1)=A_HH
A1(1,2)=A_HL
A1(1,3)=A_HL
A1(2,1)=A_LH
A1(3,1)=A_LH
A1(2,2)=A_LL
A1(2,3)=A_LL
A1(3,3)=A_LL
A1(3,2)=A_LL
elseif ( y(k,1)==H) && ( y(k,2)==H) && (y(k,3)==L)
A1(1,1)=A_HH
A1(1,2)=A_HH
A1(1,3)=A_HL
A1(2,1)=A_HH
A1(3,1)=A_LH
A1(2,2)=A_HH
A1(2,3)=A_HL
A1(3,3)=A_LL
A1(3,2)=A_LH
elseif ( y(k,1)==L) && ( y(k,2)==L) && (y(k,3)==H)
A1(1,1)=A_LL
A1(1,2)=A_LL
A1(1,3)=A_LH
A1(2,1)=A_LL
A1(3,1)=A_LH
A1(2,2)=A_LL
A1(2,3)=A_LH
A1(3,3)=A_HH
A1(3,2)=A_HL
elseif ( y(k,1)==L) && ( y(k,2)==H) && (y(k,3)==H)
A1(1,1)=A_LL
A1(1,2)=A_LH
A1(1,3)=A_LH
A1(2,1)=A_HL
A1(3,1)=A_HL
A1(2,2)=A_HH
A1(2,3)=A_HH
A1(3,3)=A_HH
A1(3,2)=A_HH
elseif ( y(k,1)==L) && ( y(k,2)==H) && (y(k,3)==L)
A1(1,1)=A_LL
A1(1,2)=A_LH
A1(1,3)=A_LL
A1(2,1)=A_HL
A1(3,1)=A_LL
A1(2,2)=A_HH
A1(2,3)=A_HL
A1(3,3)=A_LL
A1(3,2)=A_LH
elseif ( y(k,1)==H) && ( y(k,2)==L) && (y(k,3)==H)
A1(1,1)=A_HH
A1(1,2)=A_HL
A1(1,3)=A_HH
A1(2,1)=A_LH
A1(3,1)=A_HH
A1(2,2)=A_LL
A1(2,3)=A_HL
A1(3,3)=A_HH
A1(3,2)=A_HL
else A(i,j)=0
end
end
end
end
For example when n=3 and s=1, then the function returns:
A =
[ A_HH, A_HH, A_HH]
[ A_HH, A_HH, A_HH]
[ A_HH, A_HH, A_HH]
notes:
C = cell(K, 1); %// Preallocate a cell array
[C{:}] = ndgrid(x); %// Create K grids of values
y = cellfun(#(x){x(:)}, C); %// Convert grids to column vectors
y = [y{:}];
the output is for n=3 :
y =
HHH
LHH
HLH
LLH
HHL
LHL
HLL
LLL
s is just a scalar that indicates the number of line in the matrix y (which corresponds to a "state")
if you only have 2 states H and L, as you said in comment you could just as well use 0 and 1, so a binary logic.
To get your y combinations, just count in binary until you have the right number of digit and convert each bit to the state you decide:
So for order n=3 you would have:
n = 3 ;
a = de2bi( (0:2^n-1).' )
which gives you all 3 digits binary combinations:
a =
0 0 0
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1
If you want them in ascii format, you can then convert them:
b = char( ones(size(a))* 'L') ;
b(~a) = 'H' ;
To obtain:
b =
HHH
LHH
HLH
LLH
HHL
LHL
HLL
LLL
So if you want to keep a "ascii" character logic (and output), this could do the job:
function out = combiadjacent( k , n )
yb = de2bi( (0:2^n-1).' ) ; %'// get the combinations
y = char( ones(size(yb))* 'L') ;
y(~yb) = 'H' ;
A = char( zeros(n,2*n) ) ;
for col=1:n
Acol = [col col+1] + (col-1) ;
A(:,Acol) = [y(k,col)*ones(n,1) y(k,:).'] ;
end
out = reshape( cellstr( reshape(A.',2,[]).' ) , n , n ).' ;
Will give you a cell array as output like:
>> A = combiadjacent( 4 , 3 )
A =
'LL' 'LL' 'HL'
'LL' 'LL' 'HL'
'LH' 'LH' 'HH'
However, if you are not picky about the exact output format, the solution below will probably run significantly faster:
function out = combiadjacent( k , n )
y = de2bi( (0:2^n-1).' ) ; %'// get the combinations
b = ones(n,1)*y(k,:) ;
%// use that to get a cell array of characters
out = cellfun( #(a,b) char(cat(2,a+65,b+65)) , num2cell(b) ,num2cell(b.'),'uni',0) ;
%'// or use that to get a cell array of double in output (even faster)
%// out = cellfun( #(a,b) cat(2,a,b) , num2cell(b) ,num2cell(b.'),'uni',0)
%// or that to get a cell array of boolean
%// out = cellfun( #(a,b) logical(cat(2,a,b)) , num2cell(b) ,num2cell(b.'),'uni',0) ;
Which will give you
>> A = combiadjacent( 4 , 3 )
A =
'BB' 'BB' 'AB'
'BB' 'BB' 'AB'
'BA' 'BA' 'AA'
note: Whatever solution you choose, it would be prudent to add a checking condition for k to make sure the user will not request a line which doesn't exist.

B-Spline Basic function Matlab recursive

I'm trying to make a B-Spline Function
first i set the variables and made the Knot vector
# cmpp.m
% Set variables
k = 3; % (8 mod 2 + 2 + 1)
p = k - 1; % Order = 2
n = 2*k - 1; % Control points = 5
l = n + p + 1; % Vector size n + p + 1 = 8
% Create the Knot vector
% Kv = [0 0 0 1 2 3 3 3] size = 8
knoten = 0; % set all knots to 0
Kv = [];
for j=1:1:l
Kv = [ Kv 0 ];
end
for i=1:1:l
if (i > n)
if (i <= n)
Kv(i) = knoten + 1;
knoten = knoten + 1;
else
Kv(i) = knoten;
end
else
Kv(i) = knoten;
end
end
then i worte a function to create the basic function
# f.m
function N = f(N,t,i,k,u,x,s)
if (u < x)
N(i,k) = ((((u-t(i)).*f(t,i,k-1,u+s,x,s)) / (t(i+k-1) - t(i))) + (((t(i+k)-u).*f(t,i+1,k-1,u+s,x,s)) / (t(i+k) - t(i+1))));
if ((u >= t(i)) && (u < t(i+1)))
N(i,1) = 1;
else
N(i,1) = 0;
end
end
end
and called it in cmpp.m
# cmpp.m
...
...
...
N = zeros(l,k);
x = (n+1) - (k-1);
s = 1;
N = [N f(N,Kv,1,k,0,x,s)];
but i get always this error in Matlab
>> cmpp
Subscripted assignment dimension mismatch.
Error in f (line 3)
N(i,k) = ((((u-t(i)).*f(t,i,k-1,u+s,x,s)) / (t(i+k-1) - t(i))) +
(((t(i+k)-u).*f(t,i+1,k-1,u+s,x,s)) / (t(i+k) - t(i+1))));
Error in cmpp (line 32)
N = [N f(N,Kv,1,k,0,x,s)]