Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change input to be multiple messages But with same key #6

Open
subzzero opened this issue Dec 13, 2023 · 6 comments
Open

Change input to be multiple messages But with same key #6

subzzero opened this issue Dec 13, 2023 · 6 comments

Comments

@subzzero
Copy link

subzzero commented Dec 13, 2023

Hello my friend.
I am working on breaking Enigma M3 messages and doing some work.
I have about 20 messages that are all in depth messages and all of these 20 messages are encrypted with the same key .
I was working on these messages to decode theme , and actually looking for some cribs but I saw your good project and I want to use it.
Actually I have about 700 characters in these 20 messages ,that are encrypted with the same key but not one message.
I wrote a HillClime function in python that is similar to yours and I change the score function to sum all the scores from 20 messages instead of doing a score function on one message, I do score function on all 20 messages and it works fine in CPU mode but it is slow.
I was wondering if i can change your app to score all 20 messages instead of one message and sum all scores and do the other tasks.?
My knowledge about C++ is little and I really want help!!
I follow the cipher_text variable but I want some advice to do that .
So if possible please help me .
Tanx a lot for your good programs. It works very efficiently and fast.

@VE3NEA
Copy link
Owner

VE3NEA commented Dec 13, 2023

I am not sure if this approach will work. In addition to the selection and order of the rotors, ring settings and plugboard connections, encryption of the Enigma messages was controlled by a so called message key, a random group of characters that was unique for each message. It was not allowed to use the same message key for multiple messages. The encryption procedure is described in detail here.

Also, please note that the code in this project is not just C++ code, many parts of it are written in a special way to run computations on a GPU. Modification of such code is pretty difficult.

@subzzero
Copy link
Author

subzzero commented Dec 14, 2023

Thanks for your reply.
Ok . I know everything about enigma encryption procedures, etc.
I work on an Enigma challenge and my problem is real .
When an operator was lazy , He did not choose random Grundestelung for each message and he sent messages with the same header .In Bletchley park they call this 'Messages in depth'.

For example these are my messages: ( THESE ARE DUMMY MESSAGES)

FFV A QS 1410 1TLE 1TL 45 = BXF LAP
QQMCF COIMZ YQJTL KDPUE KABMP WDMXC BUUQP WUGFV KGGDE

DC3 A AW5 1415 1TLE 2TL 45 = BXF LAP
MBKVO CMOQA CQETW ELMKJ NGYQJ QGEDV LGGBC TIWFQ ZPPZA

DC3 A AW5 1421 2TLE 2TL 45 = BXF LAP
JHMOQ QMKOZ TBETD EWASX QMKLO CNILH WSNTO ANTEB RGJXQ

DC3 A SS2 1436 1TLE 1TL 50 = BXF LAP
QQMCF GVBED NLSYS HFNGA WSMKI AOIGV UAEWM OYMCB IKVOY

FC3 A SS2 1440 1TLE 1TL 45 = BXF LAP
HNQMK SGQNK ZCNRJ OXRCP AQMAE QGEDV GXYAF RNLYB OASXX

FC3 A FH4 1444 1TLE 1TL 45 = BXF LAP
QXCRD QLOPC NMSUU SMKOL URBMV DUUUG IPNYF RVTFJ UFASX

NH9 A EE4 1720 1TLE 1TL 45 = BXF LAP
QQMCF QAXRF HGEDV KTFDC DDCRF BGBPI IQNUN TJDWF WJMNG


As you see every message send with this key :

Ring = ??
Grund = encrypted of "LAP" with "BXF" as grundstellung , that we do not know
wheel order = ??
plug board = ??

and we know in German Army they had a key sheet for W.O and Ring and plugboard , and all of these messages are sent in one day and they have the same Plugs , Ring setting and wheel order and due to lazy operator they have the same Grundstellung.
So , now I have about 500 characters that are all encrypted with the same key (ring,grund,W.O and plugs), but they are not in one message.:)
I wrote the HC function in python and it works well with my approach.
I only change the score function to sum all scores from all messages instead of one message and this way I can find the solution but for every Wheel order ,Grund and Ring (532:AA:AAA in your key format)  it takes about 4.3 seconds.(very slow).
I read your code and exactly my problem is dealing with some cuda staff . -;)

I know your program prepares to do the tasks in some matrix format due to GPU conditions, but my knowledge in GPU programming is little.

In CPU program it is pretty easy to change the score function , for example this is my score function:

def score_fun(plain_text):
     ........
     do some staff and calculate the score
     return score of plain_text

Now in my main function when i want to calculate the score i have a list with 20 messages and i do score function on all of them:

def main():
    ...
    message_list =[list of all 20 messages]
    for item in message_list:
         scores_value = score_fun(item)
         total_score = total_score + score_value 
    ...

and in my benchmark it works pretty good and finds the solution but it is slow.
In comparison with your program, Yours runs one million(10^6) times faster...wow!
I have a Geforce 1070 and it runs the whole key space in one wheel order in 22 seconds.
So this is an explanation of the problem and hope for help.
Any suggestion appreciated .

@VE3NEA
Copy link
Owner

VE3NEA commented Dec 15, 2023

Even if you know GPU programming very well, it may take you weeks to modify the code the way you have described. It would be much easier to modify the CPU-only program that does basically the same thing, then you would not have to worry about parallelization.

@k3it
Copy link

k3it commented Dec 15, 2023

I agree it's hard to just "wing it" with the GPUs. They are sensitive to even a minor inefficiency which can ruin the experience. A while ago I took a course on Parallel programming https://learn.udacity.com/courses/cs344 (this one is probably out of date by now, but there are others). It makes you fairly proficient with CUDA but you forget quickly if you don't use regularly..

@subzzero
Copy link
Author

Hello my friend.
I am reading the code line by line and now i understand how program works but i have a question about work flow of the hill climb process.
As i understood h_task.count is equal to characters count that is in input message.
Before calling hill climb kernel , this function "GenerateScrambler(iterator.key);" runs .
what does this function do?
I do not understand how your enigma machine works , if explain me some tips i can read about it .
I have some idea to solve my problem, after reading the code i understood that it can not read multiple message at the same time and all the algorithm is based on one message so i decided to do not touch this thing instead i choose 8 message that all of them are exactly 35 letter , and if i put all of them in one message one after another , Now i have one single message with about 250 character, Now in Hill climb process i want to change Enigma machine to do every 35 character with the same grung.
Means for example if the start position is "AAA" after 35 letter it return again to "AAA" and enigma machine do this way and every score function do scoring on all message but with custom enigma that repeat every 35 character .
I do not find where to implant this.
In my function in CPU mode i run enigma as a function on a string and in my function every character cipher one by one and easily i can change grund to AAA in 35 position and repeat this, but here i can not find where you cipher message with grund .
so would you please help me understand more .
thanks

@subzzero
Copy link
Author

subzzero commented Jan 2, 2024

Good news is I figured out how to do this , and It works Great!! and solved my problem like a charm in 19 min in one single pass.It was very easy to change the program but understanding CUDA was a little difficult,but I found it.As I said , I cut my messages to be 32 characters long and I took 8 of them and put them all in the input file as a single message .Then in code in "cuda_code.cu" file in " ComputeScramblerIndex" function i add one single line :

char_pos = char_pos % 32;

and it workssss!! with this one line of code :)the code is :

__host__ __device__
int ComputeScramblerIndex(int char_pos, 
  const ScramblerStructure & stru,
  const RotorSettings & sett, const Wiring & wiring)
{
  char_pos = char_pos % 32;
  //retrieve notch info
  const int8_t * r_notch = wiring.notch_positions[stru.r_slot];

No common message with 250 characters can resist this function.!
The code was very clean and reading them was interesting .
tanx again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants