0

I've read a lot about this subject, about Euclidean algorithm, and I have all references needed for this subject right here:

(Best source for my question) -> Math Explanation

Another great example -> Math Explanation 2

Wiki -> Extended Euclidean

Great answer for adding values -> Add Operation

This is where I completely lost it -> AFFINE CIPHERS

However, out of all these sources, I'm still failing to understand how to implement it by code (or pseudo code), or at least find the way to write it.

So I'll write the basics, let's assume I have this formula:

(x * key) % mod = result
0 <= X <= mod
0 <= key <= mod
0 <= result<= mod

key and mod are constants.
* means multiplication operation
% means remainder operation (edited to clarify)
x and result are dynamic.

I want to create a formula that will give me x through code in Java.

The function that calculates result for me is:

private int MultModulus(int num, int key, int mod)
{
    return (num * key) % mod;
}

how can I find X? what should I write in order to calculate it? this is the point where I didn't understand, let's assume that my function signature would be:

private int InverseMultModulus(int result, int key, int mod)
{
    x = ...
    return x;
}
Community
  • 1
  • 1
Ori Frish
  • 409
  • 7
  • 21
  • 1
    a small information. The `%` is the remainder operator and not a mathematical representation of the modulo calculation. That´s what, for example `Math#floorMod`, is there for. – SomeJavaGuy Sep 29 '15 at 14:00
  • oh, in that case, ill clarify that I meant the remainder operator. – Ori Frish Sep 29 '15 at 14:01
  • 3
    The problem is not well-specified. There are, in general, multiple possible `x` values. Which do you want? – John Bollinger Sep 29 '15 at 14:05
  • 2
    There isn't a unique answer. E.g. if `result == 1`, `mod == 2` and `key == 3`, `x` could be any positive odd number. – Paul Boddington Sep 29 '15 at 14:06
  • for the Add operation, there is only one solution, how's that for multiply there are multiple answers? the sources I brought shows that there's suppose to be only 1 correct answer. if I understood them correctly. – Ori Frish Sep 29 '15 at 14:10
  • It's also possible that there is *no* answer. – John Bollinger Sep 29 '15 at 14:11
  • I'll edit the question again, 0 <= X <= mod, 0 <= KEY <= mod – Ori Frish Sep 29 '15 at 14:13
  • (X*5)%3=1 means X could be 2, 5, 8, etc. (for positive numbers). How did you want your answer to be provided to you? – ergonaut Sep 29 '15 at 14:13
  • There is no answer at all if `key` divides `mod` and `result` is not a multiple of `key`. More generally, if `key` and `mod` are not relatively prime then there will be at least one value for `result` to which no `x` corresponds. Otherwise, there may be more than one. – John Bollinger Sep 29 '15 at 14:16
  • I assume it's all supposed to be done modulo `mod`. In which case you need to look at the `BigInteger` class. Assuming `result` and `key` don't have any prime factors in common with `mod` the answer (modulo `mod`) is `key.modInverse(mod).multiply(result)`. – Paul Boddington Sep 29 '15 at 14:20
  • @OriFrish, the math.stackexchange.com answer you presented gives a pretty clean explanation for how to perform the computation efficiently when there is in fact any answer at all. The Wikipedia article describes how to compute the needed quantities. What is preventing you from implementing the needed algorithm based on the information provided by those resources? – John Bollinger Sep 29 '15 at 14:58
  • Well, to be honest with you, I'm sitting with my pen and paper, and just failing to understand how to convert it to code, I didn't fully understand the method they used in order to create the conversion. – Ori Frish Sep 29 '15 at 15:45
  • @OriFrish, if the question boils down to "please implement the extended Euclidean algorithm for me" (or similar) then it is out of scope for SO. If you have *specific* questions about how to implement the algorithm then we can address them (please post separate questions). If you don't understand the algorithm in the first place, then you may find us receptive to *specific* questions about it, but most such questions would technically be out of scope, too. – John Bollinger Sep 29 '15 at 16:03

2 Answers2

1

Run through the MultModulus, but iterate with X in [0, mod] to return the answer and store them in an array.

for (int i=0;i<mod;i++){
    if (MultModulus(i, key, mod) == result){
       // store answer in array
    }
}

return array;
ergonaut
  • 6,929
  • 1
  • 17
  • 47
  • Your solution works, however, it works partly, since from some reason some ascii letters like " and ' are simply not being written back, it also works in the same way for the add-operation solution that I brought, do you have any idea why's that? – Ori Frish Sep 29 '15 at 14:45
  • @OriFrish, you posed a numeric problem. What do ASCII characters have to do with it? – John Bollinger Sep 29 '15 at 14:54
  • You're right, basically, I write a small conversion algorithm for "encrypting" files, since it's not using any real encrypting algorithms out there. now, the algo, replaces any ascii letter in file with a key, that could be added to the char, or multiplyed with it. and I've done it with writing a 4-bytes (for every char) encrypted file, but I wanna try to do it with 1 byte, and the modulus function, to save space. – Ori Frish Sep 29 '15 at 15:12
  • Not sure about the ascii, but you can use this technique anywhere you don't want to use/derive the inverse calculation by using the forward calculation, and you have a small finite set of inputs it could be. eg. If a^b (mod c) was your formula, and you didn't want to deal with roots/logarithms, and you knew lower – ergonaut Sep 29 '15 at 15:16
1

If, as described in comments on @ergonaut's answer, you need to be able to solve this problem only for a relatively small number of original values x, and a relatively small value of mod, then one reasonable approach would be to build a decoding table in advance: perform the forward computation on every possible x, and record the starting x in an array, indexed on the result. Then you can perform a simple array lookup to get an x for each result. That will certainly outperform computing x separately for each value in a long enough sequence of values (i.e. the characters in a long enough enciphered message). Of course, if you're doing this in the spirit of a Vignere cipher, i.e. with a multibyte key, then that will multiply the input length required for pre-computing a decoding table to be a win.

Do be aware, however, that using the function you describe to define a viable cipher depends on every valid input value yielding a distinct result. As we already discussed, however, some combinations of key and mod afford duplicate results. Moreover, if the space of possible result values is the same size as the space of possible input values, then you must choose a combination of key and mod that results in all possible result values being used, else you cannot avoid duplicates.

If you want to encipher bytes as bytes, and if you want to be able to handle general files, then the only possible mod is 256. If you choose a smaller one, then there has to be at least one pair of input bytes that map to the same cipherbyte. On the other hand, if you choose a larger mod then the range of result values cannot be mapped 1:1 into the range of type byte. You must furthermore be certain to choose keys that are relatively prime with 256, but that's easy: since 256 is a power of 2, any odd key will do. As long as you choose such a key, no two input values in any range of 256 consecutive integers will map to the same result.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Thanks for your answer, can you suggest any other approach which I can create this cipher? maybe something that not including any modulu operation. I did solve it by encrypting every char to a 4-bytes size data. so when I read back, I'm sure my encrypted file is based of 4bytes data that I can read, and just decrypt back. however, it makes every file 4 times bigger, which is not a good conversion. – Ori Frish Sep 29 '15 at 16:16
  • @OriFrish, It is possible to implement a variants of Vignere cipher for "alphabets" of any size. In particular you can implement it for a 256-character alphabet. That ordinarily does involve computing remainders, but it's `(x + key) % size` rather than `(x * key) % size`. It is much easier to decipher, given a known key. Perhaps that will suit your purpose. – John Bollinger Sep 29 '15 at 16:34