Anda di halaman 1dari 3

Super-increasing knapsacks

Function definitions
supinc[n] makes a super-increasing sequence of length n
supinc[n_] := Module[{a = {}, b},
b = RandomInteger[{100, 200}];
a = {b};
While[Length[a] < n,
AppendTo[a, RandomInteger[{b + 25, 2 b}]];
b += a-1]];
Return[a]];
prikey[a] makes a private key from a super-increasing sequence a
this private key consists of a super-increasing sequence, a modulus, a multiplier, and the inverse
multiplier.
prikey[a_] := Module[{m, w, w1},
m = RandomInteger[Total[a] {1, 2} + 1000];
w = RandomInteger[{Ceiling[m / 2], m}];
While[GCD[m, w] > 1, w = RandomInteger[{Ceiling[m / 2], m}]];
w1 = PowerMod[w, -1, m];
Return[{a, m, w, w1}]];
pubkey[p] makes a public key from a private key
pubkey[p_] := Mod[p3] p1], p2]];
keypair[n] makes a key pair {private key, public key} of length n
keypair[n_] := Module[{p},
p = prikey[supinc[n]];
Return[{p, pubkey[p]}]];
encrypt[pub,plain] encrypts the plaintext plain with the public key pub
encrypt[pub_, plain_] := pub.plain;
solveknapsack[sis,s] solves the knapsack problem for the super-increasing sequence sis and the
integer s, returning the answer as a subsequence of sis
solveknapsackbits[sis,s] does the same but returns the answer as a bitstring indicating the
subsequence
solveknapsack[sis_, s_] := Module[{a = {}, k, ss = s},
For[k = Length[sis], k > 0, k--,
If[ss z sisk], PrependTo[a, sisk]]; ss -= sisk]];
];
Return[If[ss = 0, a, {}]]];
solveknapsackbits[sis_, s_] := Module[{sk},
sk = solveknapsack[sis, s];
Return[Table[If[MemberQ[sk, sisi]], 1, 0], {i, 1, Length[sis]}]]];
decrypt[pri,ciph] encrypts the ciphertext ciph with the private key pri
decrypt[pri_, ciph_] := solveknapsackbits[pri1], Mod[pri4] ciph, pri2]]];
Example
len = 12;
kp = keypair[len]
157, 260, 543, 1880, 4842, 15101, 30843, 57693, 155510, 522841, 938256, 2355838,
6482449, 5505138, 2027220, 2140949, 5197100, 880945, 3670836,
47908, 2162962, 184677, 337879, 5865644, 781874, 431230, 4467059
pt = RandomInteger[{0, 1}, len]
ct = encrypt[kp2], pt]
0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0
13031596
decrypt[kp1], ct]
0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0
Cryptanalysis
build the lattice from the public key and the ciphertext
lat = IdentityMatrix[len + 1];
latRange[len], -1] = -kp2];
lat-1, -1] = ct;
lat // MatrixForm
1 0 0 0 0 0 0 0 0 0 0 0 2140949
0 1 0 0 0 0 0 0 0 0 0 0 5197100
0 0 1 0 0 0 0 0 0 0 0 0 880945
0 0 0 1 0 0 0 0 0 0 0 0 3670836
0 0 0 0 1 0 0 0 0 0 0 0 47908
0 0 0 0 0 1 0 0 0 0 0 0 2162962
0 0 0 0 0 0 1 0 0 0 0 0 184677
0 0 0 0 0 0 0 1 0 0 0 0 337879
0 0 0 0 0 0 0 0 1 0 0 0 5865644
0 0 0 0 0 0 0 0 0 1 0 0 781874
0 0 0 0 0 0 0 0 0 0 1 0 431230
0 0 0 0 0 0 0 0 0 0 0 1 4467059
0 0 0 0 0 0 0 0 0 0 0 0 13031596
reduce the lattice using LLL
2 knapsack.nb
latr = LatticeReduce[lat];
latr // MatrixForm
0 1 1 1 0 1 0 1 0 1 0 0 0
1 0 3 1 0 2 1 1 0 0 0 0 0
2 0 3 2 2 1 0 1 1 1 0 0 0
2 0 1 1 2 1 1 1 1 0 2 0 1
2 1 1 1 1 2 1 2 0 2 1 0 0
2 1 0 3 0 2 1 1 2 0 1 0 0
1 3 1 0 0 1 1 0 1 1 1 1 2
1 2 1 0 1 0 2 1 1 1 1 0 1
1 1 0 1 0 0 1 2 1 1 2 1 1
0 2 1 2 2 1 1 0 1 1 1 1 1
1 1 1 1 2 1 1 2 1 1 1 2 1
1 1 1 1 3 1 1 0 0 1 0 3 0
1 1 1 2 3 1 1 1 1 1 1 2 2
find the positions where only 0 and 1 occur
and check whether they are solutions indeed
p = Flatten[Position[Table[(Min / latr)i] z 0
(Max / latr)i] s 1 latri, -1] = 0, {i, 1, len + 1}], True]];
If[Length[p] > 0, Print["position: ", p]; Print[latrp]All, Range[len]].kp2],
" should be equal to ", ct];
Print["decipered text: ", latrp]All, Range[len]]], Print["no solution"]];
Print["plaintext was: ", pt];
position: 1
13031596 should be equal to 13031596
decipered text: 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0
plaintext was: 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0
knapsack.nb 3

Anda mungkin juga menyukai