我正在尝试执行多项式乘法,如Advanced Encryption Standard (AES)草案中所述。
这是我到目前为止所拥有的:
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
上面的代码适用于
" y = {02}。一个"
(其中" {}"表示十六进制表示法,其二进制表示可以解释为多项式中x的相应幂的前提。例如,{02}对应于00000010,对应于对于多项式" x",{06}将对应于" x 2 + x"等,根据AES文档)
我想将a
与0e
,09
,0d
和0b
相乘。
代码将如何针对每个人?即:
" y =({0e}。a)"
" y =({09}。a)"
" y =({0d}。a)"
" y =({02}。a)"
答案 0 :(得分:3)
这是一个有趣的问题。以下是您链接的AES文档中定义的乘法的一般解决方案。我使用名称xtime
进行{02}乘法,并实现"加法" (xadd)直接作为XOR操作(即!=
),因为这更容易。
帮助程序功能:
%% 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
多项式函数:
%% 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
使用示例:(与AES文档中的示例相同)
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
答案 1 :(得分:2)
在MATLAB / Octave中,conv
和deconv
分别对应于多项式的乘法和(除法/模)运算。
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
例如,将0x57
和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
是0xFE
答案 2 :(得分:1)
感谢您的关注。我正在尝试在matlab中实现AES。我在http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf的页面中找到了解决方案。以下是y= ( {09} . a )
乘法运算的函数;
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
并且也可以使用任何矩阵乘法multiply_xx (a, b, p )
函数。这是函数;
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