问题:我需要编写一个以4个字节为输入的函数,对此执行可逆线性变换,并将其返回为4个字节。
但等等,还有更多:它也必须是分布式的,因此更改输入上的一个字节应该会影响所有4个输出字节。
问题:
一个解决方案: 我可以创建一个长度为256 ^ 4的字节数组并填充它,在一对一的映射中,这可以工作,但是有问题:这意味着我必须搜索大小为256 ^ 8的图表,因为必须搜索对于每个值的自由数字(应该注意分配性应该是基于64 * 64字节数组的sudo随机)。这个解决方案还有需要8GB RAM的MINOR(lol)问题,使这个解决方案无意义。
有什么好主意吗?我不需要代码,只是一个想法。
编辑:好的,对不起我的描述;我会尽量让它更清晰一些。输入的域与输出的域相同,每个输入都有唯一的输出,换句话说:一对一映射。正如我在“一个解决方案”中所指出的那样,这是非常可能的,当一个较小的域(只有256个)存在问题时,我已经使用了该方法。事实是,随着数字越来越大,该方法变得非常低效,delta缺陷为O(n ^ 5),omega为O(n ^ 8),内存使用方面具有相似的瑕疵。我想知道是否有一种聪明的方法来做到这一点。简而言之,它是域的一对一映射(4字节或256 ^ 4)。哦,并且不能使用N + 1这样简单的东西,它必须键入64 * 64字节值数组,这些字节值是随机的,但可以进行反向转换。我希望我有道理。
答案 0 :(得分:4)
Balanced Block Mixers正是您正在寻找的。 p>
谁知道?
答案 1 :(得分:4)
编辑!如果您确实需要线性变换,那么不可能。这是一个糟糕的解决方案:
你有四个字节a_1, a_2, a_3, a_4
,我们将其视为一个带有4个组件的向量 a
,每个组件都是一个模数256。线性变换只是一个4x4矩阵M
,其元素也是数字模256.你有两个条件:
M
a
,我们可以推断 a
(这意味着M
是可逆矩阵)。a
且 a'
在单个坐标中有所不同,则M
a
< / strong>和M
a'
必须在每个坐标中有所不同。条件(2)有点棘手,但这就是它的含义。由于M
是线性变换,我们知道
M
(a
-a
)=M
a
< / strong> -M
a'
在左侧,由于 a
和 a'
在单个坐标中不同, a
- a
只有一个非零坐标。在右侧,由于M
a
和M
a'
必须在每个坐标中都有所不同,{{1} } M
- a
M
必须每个坐标非零。
因此矩阵a'
必须将具有单个非零坐标的向量带到具有所有非零坐标的向量。所以我们只需要M
的每个条目都是非零除数 mod 256,即为奇数。
回到条件(1),M
可逆是什么意思?既然我们正在考虑它是mod 256,我们只需要它determinant是可逆的mod 256;也就是说,它的决定因素必须是奇数。
所以你需要一个4x4矩阵,其奇数项为256,其行列式为奇数。但这是不可能的!为什么?通过对条目的各种产品求和来计算行列式。对于4x4矩阵,有4个! = 24个不同的加数,每个加数是奇数条目的乘积,是奇数。但是24个奇数的总和是偶数,所以这个矩阵的行列式必须是偶数!
答案 2 :(得分:2)
我不确定我理解你的问题,但我想我得到了你想要做的事。
Bitwise Exclusive或是你的朋友。
如果R = A XOR B,则R XOR A给出B,R XOR B给出A返回。所以这是一个可逆的转换,假设您知道结果和其中一个输入。
答案 3 :(得分:2)
根据我的理解,这是您的要求:
B
为字节空间。你想要一对一(以及因此)函数f: B^4 -> B^4
。这是我最简单的解决方案因此。我已经避免发布了一段时间,因为我一直试图想出一个更好的解决方案,但我没有想到任何事情。
好的,首先,我们需要一个函数g: B -> B
,它接受一个字节并返回一个字节。此函数必须具有两个属性:g(x)是可逆的,x ^ g(x)是可逆的。 [注意:^是XOR运算符。]任何这样的g都可以,但我稍后会定义一个特定的。
给定这样的ag,我们用f(a,b,c,d)=(a ^ b ^ c ^ d,g(a)^ b ^ c ^ d,a ^ g(b)^ c定义f ^ d,a ^ b ^ g(c)^ d)。让我们检查一下你的要求:
最后,我们构造了这样一个函数g。令T为两位值的空间,并且h : T -> T
函数使得h(0)= 0,h(1)= 2,h(2)= 3,并且h(3)= 1。该函数具有g的两个期望属性,即h(x)是可逆的,因此是x ^ h(x)。 (对于后者,检查0 ^ h(0)= 0,1 ^ h(1)= 3,2 ^ h(2)= 1和3 ^ h(3)= 2.)所以,最后,到计算g(x),将x分成四组,每两位,并分别取每个四分之一的h。因为h满足两个期望的属性,并且四分之一之间没有相互作用,所以g。
答案 4 :(得分:1)
假设我明白你要做什么,我认为任何block cipher都能胜任。
块密码占用一个比特块(比如128)并将它们可逆地映射到具有相同大小的不同块。
此外,如果您使用OFB mode,则可以使用分组密码生成无限的伪随机位流。使用您的位流对这些位进行异或运算将为您提供任意长度数据的转换。
答案 5 :(得分:0)
“线性”转换是什么意思? O(n),或函数f与f(c *(a + b))= c * f(a)+ c * f(b)?
一种简单的方法是旋转位移(不确定这是否满足上述数学定义)。它的可逆性和每个字节都可以改变。但是这样做并不强制每个字节都被改变。
编辑:我的解决方案是:
b0 = (a0 ^ a1 ^ a2 ^ a3)
b1 = a1 + b0 ( mod 256)
b2 = a2 + b0 ( mod 256)
b3 = a3 + b0 ( mod 256)
它是可逆的(只是从另一个中减去第一个字节,然后在第一个字节上对3个结果字节进行异或),并且一个位的变化将改变每个字节(因为b0是所有字节和影响的结果)所有其他)。
答案 6 :(得分:0)
我要抛弃一个可能有效或无效的想法。
使用一组线性函数mod 256,具有奇素数系数。
例如:
b0 = 3 * a0 + 5 * a1 + 7 * a2 + 11 * a3;
b1 = 13 * a0 + 17 * a1 + 19 * a2 + 23 * a3;
如果我正确地记住了中国剩余定理,并且我多年没有看过它,那么斧头可以从bx中恢复。甚至可能有一种快速的方法。
我认为,这是一种可逆的转变。它是线性的,因为af(x)mod 256 = f(ax)和f(x)+ f(y)mod 256 = f(x + y)。显然,更改一个输入字节将改变所有输出字节。
所以,请查看中国剩余定理,看看是否有效。
答案 7 :(得分:0)
将所有字节粘贴到32位数字,然后执行shl或shr(向左移位或向右移位)一,二或三。然后将其拆分为字节(可以使用变体记录)。这会将每个字节的位移动到相邻的字节中。
这里有很多好的建议(XOR等)我建议将它们组合起来。
答案 8 :(得分:0)
您可以重新映射这些位。让我们使用ii作为输入,使用oo作为输出:
oo[0] = (ii[0] & 0xC0) | (ii[1] & 0x30) | (ii[2] & 0x0C) | (ii[3] | 0x03)
oo[1] = (ii[0] & 0x30) | (ii[1] & 0x0C) | (ii[2] & 0x03) | (ii[3] | 0xC0)
oo[2] = (ii[0] & 0x0C) | (ii[1] & 0x03) | (ii[2] & 0xC0) | (ii[3] | 0x30)
oo[3] = (ii[0] & 0x03) | (ii[1] & 0xC0) | (ii[2] & 0x30) | (ii[3] | 0x0C)
它不是线性的,但显着改变输入中的一个字节将影响输出中的所有字节。我不认为你可以进行可逆转换,例如改变输入中的一位会影响输出的所有四个字节,但我没有证据。