Matlab:支持非素数模的线性同余解算器?

时间:2013-12-01 20:43:56

标签: matlab cryptography linear-algebra symbolic-math mupad

我正在研究一些Matlab代码,在给定的密码系统上执行一个名为Index Calculus攻击的东西(这涉及计算离散的日志值),除了一件小事之外,我已经完成了所有这些。我不能弄清楚(在Matlab中)如何解决同余mod p的线性系统,其中p是而不是 prime。此外,这个系统有多个变量,因此,除非我遗漏了某些东西,否则中文余数定理不会起作用。

我在数学stackexchange上问了一个更详细/格式化的mathjax here的问题。我在那个链接上解决了我的问题中的问题,现在我试图找到一个实用程序,它将允许我解决以非素数为模的同余系统。我确实找到了一个包含支持模运算的求解器的套件,但模数必须是素数(here)。我也尝试逐步修改它以使用非素数,但无论使用何种方法都不起作用,因为它要求系统的所有元素都以模p进行反转。

我已经研究过使用Matlab中的函数调用MuPAD函数,但是从我的测试来看,MuPAD函数linsolve(似乎是最佳候选者)不支持非素数模数值。 。另外,我已经用Maple验证了这个系统是可解的模数我感兴趣的整数(8),所以它可以完成。

更具体地说,这是我试图在MuPAD中运行的确切命令:

linsolve([0*x + 5*y + 4*z + q = 2946321, x + 7*y + 2*q = 5851213, 8*x + y + 2*q = 2563617, 10*x + 5*y + z = 10670279],[x,y,z,q], Domain = Dom::IntegerMod(8))

Error: expecting 'Domain=R', where R is a domain of category 'Cat::Field' [linsolve]

如果我将域更改为IntegerMod(23)和IntegerMod(59407),则相同的命令将返回正确的值,因此我认为8不适合,因为它不是素数。当我尝试使用上面的命令时,输出是每个23和59407作为我的域:

[x = 1 mod 23, y = 1 mod 23, z = 12 mod 23, q = 14 mod 23]

[x = 14087 mod 59407, y = 1 mod 59407, z = 14365 mod 59407, q = 37320 mod 59407]

这些答案是正确的 - xyzq对应L1L2,{{1}位于上面Math.StackExchange链接的同余系统中的{}和L3

1 个答案:

答案 0 :(得分:3)

我想知道您之前是否曾尝试使用sym/linsolvesym/solve,但可能已传入数字而非符号值。例如,这会根据您要查找的内容返回废话:

A = [0 5 4 1;1 7 0 2;8 1 0 2;10 5 1 0];
b = [2946321;5851213;2563617;10670279];
s = mod(linsolve(A,b),8)

但是,如果将数值转换为符号整数,sym/linsolve将按照有理分数保留所有内容。然后

s = mod(linsolve(sym(A),sym(b)),8)

返回预期答案

s =

 6
 1
 6
 4

这只是使用符号数学解决系统线性系统,就像它是一个普通矩阵一样。对于大型系统而言,这可能很昂贵,但我想的不过是使用MuPAD的numeric::linsolvelinalg::matlinsolvesym/mod应该返回每个解决方案组件的分子的模数。如果模数和分母不至少为coprime,我相信你会收到错误。

sym/solve也可用于以类似方式解决此问题:

L = sym('L',[4,1]);
[L1,L2,L3,L4] = solve(A*L==b);
s = mod([L1;L2;L3;L4],8)

使用sym/solvesym/linsolve的一个可能问题是,如果线性同余问题存在多个解决方案(与线性系统相对),则此方法可能无法返回所有这些解决方案。

最后,使用MuPAD函数numlib::ichrem(整数的中文余数定理),这里有一些试图获得完整解的代码:

A = [0 5 4 1;1 7 0 2;8 1 0 2;10 5 1 0];
b = [2946321;5851213;2563617;10670279];
m = 10930888;

mf = str2num(strrep(char(factor(sym(m))),'*',' '));
A = sym(A);
b = sym(b);
s = sym(zeros(length(b),length(mf)));
for i = 1:length(mf)
    s(:,i) = mod(linsolve(A,b),mf(i));
end

mstr = ['[' sprintf('%d,',mf)];
mstr(end) = ']';
r = sym(zeros(length(b),1));
for i = 1:length(b)
    sstr = char(s(i,:));
    r(i) = feval(symengine,'numlib::ichrem',sstr(9:end-2),mstr);
end
check = isequal(mod(A*r,m),b)

我不确定这些是否是您正在寻找的,但希望它可能会有所帮助。我认为将enhancement/service request与MathWorks放在一起可能是一个好主意,这样MuPAD和其他求解器将来可以更好地处理系统。