我正在研究一些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]
这些答案是正确的 - x
,y
,z
和q
对应L1
,L2
,{{1}位于上面Math.StackExchange链接的同余系统中的{}和L3
。
答案 0 :(得分:3)
我想知道您之前是否曾尝试使用sym/linsolve
和sym/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::linsolve
或linalg::matlinsolve
。 sym/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/solve
或sym/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和其他求解器将来可以更好地处理系统。