Борьба с алгоритмом TEA в сборке 8086 TASM

Я пытаюсь реализовать алгоритм TEA на языке ассемблера (8086 TASM). Однако я сталкиваюсь с трудностями в двух областях.

  1. Строковый ввод: мне нужна помощь в реализации механизма ввода строк от пользователя в моей ассемблерной программе.

  2. Шестнадцатеричное преобразование: после получения пользовательского ввода я стремлюсь преобразовать каждую букву входной строки в соответствующее шестнадцатеричное представление, чтобы подготовить ее к шифрованию TEA. Я ищу рекомендации о том, как эффективно выполнить это преобразование.

  3. Расшифровка зашифрованного сообщения. После шифрования с использованием алгоритма TEA я столкнулся с трудностями при преобразовании полученного зашифрованного сообщения обратно в читаемые строковые буквы. Мне нужна помощь в расшифровке и преобразовании зашифрованного сообщения в исходную форму.

Я успешно реализовал функции шифрования и дешифрования для алгоритма TEA. Эти функции, похоже, правильно выполняют операции шифрования и дешифрования. Однако мне приходится обрабатывать ввод строк и преобразовывать их в формат, подходящий для шифрования. Кроме того, после шифрования выходные данные содержат неизвестные символы, и мне нужна помощь в преобразовании их в читаемые зашифрованные строки.

Вот мои функции шифрования/дешифрования:

proc encrypt
    pusha

    mov cx, 32
    encryptLoop:
        ; sum += delta
        mov ax, [delta]
        add [sum], ax

        xor eax,eax
        ; ((p2 << 4) + k0)
        mov dx, [p2]
        shl dx, 4
        add dx, [k0]

        ; (p2 + sum)
        mov bx, [p2]
        add bx, [sum]

        ; ((p2 << 4) + k0) ^ (p2 + sum)
        xor dx, bx

        xor bx, bx

        ; ((p2 >> 5) + k1)
        mov bx, [p2]
        shr bx, 5
        add bx, [k1]
        ; ((p2 << 4) + k0) ^ (p2 + sum) ^ ((p2 >> 5) + k1)
        xor dx, bx
        add [pe1], dx

        ; ((p1 << 4) + k2)
        mov dx, [p1]
        shl dx, 4
        add dx, [k2]

        ; (p1 + sum)
        mov bx, [p1]
        add bx, [sum]

        ; ((p0 << 4) + k2) ^ (p0 + sum)
        xor dx, bx

        xor bx, bx

        ; ((p1 >> 5 ) + k3)
        mov bx,[p1]
        shr bx, 5
        add bx, [k3] 
        ; ((p0 << 4) + k2) ^ (p0 + sum) ^ ((p1 >> 5 ) + k3)
        xor dx, bx

        add [pe2], dx
    loop encryptLoop

    popa
    ret
endp encrypt

proc decrypt
   pusha

    mov cx, 32
    decryptLoop:
        ; ((p1 << 4) + k2)
        mov dx, [p1]
        shl dx, 4
        add dx, [k2]

        ; (p1 + sum)
        mov bx, [p1]
        add bx, [sum]

        ; ((p0 << 4) + k2) ^ (p0 + sum)
        xor dx, bx

        xor bx, bx

        ; ((p1 >> 5 ) + k3)
        mov bx,[p1]
        shr bx, 5
        add bx, [k3] 
        ; ((p0 << 4) + k2) ^ (p0 + sum) ^ ((p1 >> 5 ) + k3)
        xor dx, bx

        sub [pe2], dx

        xor ax,ax
        ; ((p2 << 4) + k0)
        mov dx, [p2]
        shl dx, 4
        add dx, [k0]

        ; (p2 + sum)
        mov bx, [p2]
        add bx, [sum]
        
        ; ((p1 << 4) + k0) ^ (p1 + sum)
        xor dx, bx

        xor bx, bx

        ; ((p2 >> 5) + k1)
        mov bx, [p2]
        shr bx, 5
        add bx, [k1]
        ; ((p2 << 4) + k0) ^ (p2 + sum) ^ ((p2 >> 5) + k1)
        xor dx, bx
        sub [pe1], dx

        ; sum -= delta
        mov ax, [delta]
        sub [sum], ax
    loop decryptLoop

    popa

    ret
endp decrypt

Раздел ДС:

delta dw 79b9h ; 79b9h for 16 bits, 9e3779b9h for 32 bits

sum dw 0
p1 dw 0
p2 dw 0

k0  dw 0                  
k1  dw 0                   
k2  dw 0                   
k3  dw 0         

; Two part of the plaintext after encryption
pe1 dw 0
pe2 dw 0        

Размер данных должен быть 32-битным, беззнаковым целым числом.

Nassau 17.05.2024 19:14

Пункт 2. Вы хотите, чтобы каждый символ обычного текста был заменен двумя шестнадцатеричными символами, а затем использовалось шифрование шестнадцатеричной строки? Например ABCD будет 41424344h?

Nassau 17.05.2024 22:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
152
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обновлено: Надеюсь, я правильно понял этот алгоритм. ;)


Первый ответ:

Память выглядит так перед вызовом encryption:

Delta: 9e3779b9h
p1   : 20656349h = 'Ice '
p2   : 21414554h = 'TEA!'

k1   : 00000016h = 22
k2   : 0000000bh = 11
k3   : 00000021h = 33
k4   : 00000003h =  3

-d ds:0
0EED:0000  B9 79 37 9E 00 00 00 00-49 63 65 20 54 45 41 21 .y7.....Ice TEA!
0EED:0010  16 00 00 00 0B 00 00 00-21 00 00 00 03 00 00 00 ........!.......

После encryption:

Delta: 9e3779b9h
p1   : c6ef3720h (encrypted)
p2   : c96bcfebh (encrypted)

k1   : 00000016h = 22
k2   : 0000000bh = 11
k3   : 00000021h = 33
k4   : 00000003h =  3

-d ds:0
0EED:0000  B9 79 37 9E 20 37 EF C6-7A D0 EA DC 1E FC 4C 9A .y7. 7..z.....L.
0EED:0010  16 00 00 00 0B 00 00 00-21 00 00 00 03 00 00 00 ........!.......

Теперь decryption, вернемся к нормальному состоянию:

Delta: 9e3779b9h
p1   : 20656349h = 'Ice '
p2   : 21414554h = 'TEA!'

k1   : 00000016h = 22
k2   : 0000000bh = 11
k3   : 00000021h = 33
k4   : 00000003h =  3

-d ds:0
0EED:0000  B9 79 37 9E 00 00 00 00-49 63 65 20 54 45 41 21 .y7.....Ice TEA!
0EED:0010  16 00 00 00 0B 00 00 00-21 00 00 00 03 00 00 00 ........!.......

Я использовал жестко закодированные значения для p1,p2,k0,k1,k2,k3.


Обновление 1:

Я добавил:

print_text proc — показывает строку в консоли, смещение строки должно быть si

user_input proc - берет данные от пользователя

check_chars proc — нам нужны только правильные символы

plain_txt_bufferразмер 32 bytes + 1 byte for 0dh.

Если пользователь вводит 32 символа, 0dh будет автоматически добавлен в конец буфера.


Обновление 2:

input_flag внутри user_input proc и check_chars контролирует, какой набор данных используется:

 1 - data set for plain_text , 20h - 7fh, enter, backspace

 2 - data set for keys, only digits 30h - 39h, enter, backspace

keys_bufferразмер 10 bytes + 1 byte for 0dh.

Если пользователь вводит 10 символов, 0dh будет автоматически добавлен в конец буфера.


Обновление 3:

  • Преобразование k0,k1,k2,k3 строки ascii в 32-битное значение.
  • Ясно keys_buffer, потому что программа использует одну и ту же память для расчета всех ключей.
  • Показать 128-битный полный ключ в шестнадцатеричном формате.

Обновление 4:

  • Подготовьте простой текст для шифрования, входная строка будет разбита на фрагменты по 4 байта.
  • Зашифровать и сохранить
  • Расшифровать
  • Показать все в таблице

Вот обновленный код:

.386
ideal
model small
stack 256
segment datasg

    plain_txt_buffer db 33 dup(0)                   ; store user's text     
    pt_buffer_size   db $ - plain_txt_buffer - 1    ; size of the buffer without 0dh
    
    keys_buffer      db 11 dup(0)                   ; store user's keys 
    k_buffer_size    db $ - keys_buffer - 1         ; size of the buffer without 0dh

    enc_buffer       db 32 dup(0)                   ; encrypted txt buffer
    ;enc_buffer_size  db $ - enc_buffer             ; not used in the code

    dec_buffer       db 32 dup(0)                   ; decrypted txt buffer
    ;dec_buffer_size  db $ - dec_buffer             ; not used in the code

    chars_in_buffer  db 0                           ; how many chars user entered, used in key32bit proc

    input_flag       dw 1                           ; 1 - plain text data set, [20h ... 7fh], enter, backspace
                                                    ; 2 - keys data set, only digits, enter, backspace

    delta dd 9e3779b9h                              ; 9e3779b9h for 32 bits

    sum dd 0        
    p1 dd 20656349h
    p2 dd 21414554h
    
    k0  dd 65536                                    ; [0 ... 4,294,967,295], 32-bit keys
    k1  dd 255                   
    k2  dd 0ff000000h                  
    k3  dd 10000000h
                                                    
    plain_txt_msg    db "Plain text: ",0            ; some screen messages
    keys_msg         db 0dh,0ah,"Enter keys: ",0
    key_num          db "k[ ",30h," ] = ",0
    
    wait_for_key     db 0dh,0ah,0ah,"Press any key to exit the app... ",0   
    newline          db 0dh,0ah,0

    key128bit        db 0dh,0ah,"128-bit key: ",0
    
    table_header     db 0dh,0ah,0ah,"|Cycle|Plain Text      |Encryption      |Decryption      |",0
    table_row        db 0dh,0ah,"|     |                |                |                |",0      
    cycle_num        db "<",07h,30h,0eh,">",07h     ; char + attribute
    
    text_mode_mem    dw 0b800h                      ; text mode vodeo mem address
    pt_buffer_start  dw 0018h                       ; 0b800h:0018h, text_mode_mem + 24 bytes, write plain text here
    k_buffer_start   dw 00cah                       ; 0b800h:00cah, text_mode_mem + 202 bytes, write keys here
    trimmed_value    dw 00ddh                       ; last digit will be red color if not fit in 32 bits
ends
    
assume ds:datasg,cs:code

segment code 
start:
    mov ax,datasg                       ; load ds
    mov ds,ax
    
    mov ax,[text_mode_mem]              ; set es to text mode address
    mov es,ax

    mov ax,3                            ; text mode
    int 10h

    mov ah,01h                          ; hide cursor
    mov cx,2000h
    int 10h 

;------------------------- input plain txt  
    mov si, offset plain_txt_msg        ; "Plain text: "
    call print_text                 
    
    mov di, offset plain_txt_buffer     ; store plain text here
    mov bx,[pt_buffer_start]            ; address in video memory of the plain_text_buffer  
    
    call user_input                     ; take chars from a user

;------------------------- input keys
    mov si, offset keys_msg             ; "Enter keys: "
    call print_text

    mov bx,[k_buffer_start]             ; address in video memory of the keys_buffer    
    mov [word input_flag],2             ; change data set to digits
    
    mov cx,4                            ; read 4 keys
    mov dx,010ch                        ; cursor position
    
    enter_keys:
        mov di, offset keys_buffer      ; write keys here
        push dx                         ; save cursor position
        push bx                         ; save video memory offset of the current key 0,1,2,3
        
        mov ah,2                        ; set cursor position
        mov bh,0
        int 10h                         ; BIOS video interrupt
        
        pop bx
        push bx
        
        mov si, offset key_num          ; print key number, "k[ ",30h," ] = " 
        push si                         ; save, lodsb inside print_text changes si
        call print_text 
                
        call user_input                 ; take ascii digits from a user         
        
        pop si                          ; restore       
    
        call key32bit                   ; convert ascii digits to 32bit and clear keys_buffer

        pop bx                          ; current key position
        add bx,160                      ; move to the next key
        
        mov si, offset newline          ; go to new line
        call print_text
        
        pop dx                          ; restore cursor position
        inc dh                          ; next row
        dec cx                          ; decrement loop counter
        jnz enter_keys                  ; enter next key

;-----------------------show 128 bit key

    mov si,offset key128bit             ; "128-bit key: "
    call print_text
    
    call print128key                    ; this proc prints full key in hex format

;----------------------------------------   

    call remove_0dh                 ; remove 0dh from plain_txt_buffer
    
    mov cx,4                        ; run encryption 4 times
    mov si, offset plain_txt_buffer ; offsets to buffers
    mov di, offset enc_buffer
    mov bx, offset dec_buffer
    
    cycle_enc_dec:                  ; start encryption - decryption cycle
        push bx
        mov eax, [si]               ; p1,take 4 bytes from plain_txt_buffer
        mov [p1],eax                ; p1,p2 are used inside enc and dec procs
        add si,4                    ; move to p2
        mov eax, [si]               ; p2,take 4 bytes from plain_txt_buffer
        mov [p2],eax                ;
        
        call encrypt                ; start encryption
    
        mov eax,[p1]                ; take decrypted 2 x 4 bytes and store them inside enc_buffer   
        mov [di],eax                ; p1
        add di,4                    ; move to p2
        mov eax,[p2]            
        mov [di],eax                ; p2
        
;-------------------------------------  
        
        call decrypt                ; start decryption
        
        pop bx                      ; pop dec_buffer address
        mov eax,[p1]                ; and save p1 and p2 inside
        mov [bx],eax                
        add bx,4
        mov eax,[p2]
        mov [bx],eax
        
        add si,4                    ; next 2 x 4 bytes of plain text
        add di,4                    ; move 8 bytes inside encryption buffer
        add bx,4                    ; move 8 bytes inside decryption buffer
        
        mov [dword sum],0           ; reset sum
        
        dec cx                      ; decrement cycles  
        jnz cycle_enc_dec           ; go to next cycle
    
;------ data is in memory, now show results

    mov si, offset table_header     ; |Cycle|Plain Text      |Encryption      |Decryption      |
    call print_text
    
    mov cx,13                       ; print 13 rows
    
    show_table:
        mov si, offset table_row
        call print_text 
        
        dec cx
        jnz show_table

    call print_data                 ; show all data,number of cycle, plain text, enrypted text
                                    ; and after decryption, back to original message

;------------------------- end app

    mov si,offset wait_for_key
    call print_text
    
    mov ah,0
    int 16h
    
    mov ax,3                ; clear screen
    int 10h
    
    mov ax,4c00h
    int 21h

;----------------------------------------   
;   print128key
;   prints full key in hex format

proc print128key
    
    mov di,986                      ; screen offset, start printing at this location
    mov si, offset k0               ; offset of first key, all the keys are in memory together
                                    ; k1 = k0 + 4 bytes
                                    ; k2 = k0 + 8 bytes
                                    ; k3 = k0 + 12 bytes

    add si,3                        ; bytes in memory are in litlle endian format
                                    ; translate to human readable form
                                    
    mov dx,4                        ; print 4 keys
    
    one_of_the_4_parts:                             
    
        mov cx,4                    ; 4 bytes each

        byte_inside:
        
            mov al,[si]             ; each byte of the key
        
            call char2hex           ; print 2 hex values
        
            dec si                  ; offset of the next byte of the key
            dec cx                  ; bytes left
            jnz byte_inside
        
        add si,8                    ; move to the next part
        add di,2                    ; insert space
        dec dx                      ; parts left
        jnz one_of_the_4_parts
        
    ret
endp print128key

;----------------------------------------   
;   print_data
;   prints result of encrypton and decryption

proc print_data
    push bp
    mov bp, sp
    
    mov cx,4                ; 4 rows            
    mov di,1604             ; memory offset of the first table row
    
    mov [word bp-2],offset plain_txt_buffer
    mov [word bp-4],offset enc_buffer
    mov [word bp-6],offset dec_buffer
    sub sp,6
    
    show_rows:
        push cx     
        
        ;cycle column
        
        mov si,offset cycle_num     ; print cycle number
        mov cx,6
        rep movsb
        
        add [byte si-4],1           ; modify row number
    
        ;plain text column
    
        add di,4
        
        mov si, [bp-2]
        mov cx,8
    
        plain_text_column:
            mov al,[si]             ; char from plain_txt_buffer
            mov [es:di],al  
            add di,1
            
            mov dl,15               ; white color
            mov [es:di],dl
            add di,159
            
            call char2hex
            
            sub di,160
            
            inc si                  ; take next char
            dec cx
            jnz plain_text_column
        
        mov [bp-2],si               ; save current plain_txt_buffer offset
        
        ;encryption column
    
        add di,2
        
        mov si, [bp-4]
        mov cx,8
    
        enc_column:
            mov al,[si]             ; char from enc_buffer
            mov [es:di],al  
            add di,1
            
            mov dl,10               ; light green color
            mov [es:di],dl
            add di,159
            
            call char2hex
            
            sub di,160
            
            inc si                  ; take next char
            dec cx
            jnz enc_column
        
        mov [bp-4],si               ; save current enc_buffer offset

        ;decryption column
    
        add di,2
        
        mov si, [bp-6]
        mov cx,8
    
        dec_column:
            mov al,[si]             ; char from dec_buffer
            mov [es:di],al  
            add di,1
            
            mov dl,13               ; purple color
            mov [es:di],dl
            add di,159
            
            call char2hex
            
            sub di,160
            
            inc si                  ; take next char
            dec cx
            jnz dec_column
        
        mov [bp-6],si               ; save current enc_buffer offset

        add di,370                  ; go next row
        
        pop cx  
        dec cx
        jnz show_rows
        
    add sp,6    
    pop bp  
    ret
endp print_data

;----------------------------------------
;   remove_0dh  
;   removes 0dh from plain text buffer
;   we want only plain text
  
proc remove_0dh

    mov di,offset plain_txt_buffer
    
    search_for_0dh:
        cmp [byte di],0dh
        jz search_done
            
        inc di                      ; next address of the char
        jmp search_for_0dh
    
        search_done:
            mov [byte di],0         ; remove 0dh
    ret
endp remove_0dh

;----------------------------------------   
;   char2hex
;   prints byte as sequence of 2 hex values

proc char2hex

    ; al - char 
    push cx                         ; save previous loop's counter
    push ax                         ; char will change after shr, save it
    mov bl,2                        ; process 2 nibbles
    
    shr al,4                        ; al = xxxxxxxx, - shr,4 - 0000xxxx, higher half moved to lower half
        
    hex_2:
        cmp al,10
        jae print_letter
        
        add al,30h                  ; print_digit
        jmp to_mem
        
        print_letter:
            add al,37h      
                
        to_mem:
            mov [es:di],al          ; move to mem
            
        add di,1                    ; move to the attribute byte
        
        mov cl,3                    ; turquoise color
        mov [es:di],cl              ; change char attribute
        inc di
        
        dec bl              
        jz done_printing
        
        pop ax      
        and al,0fh                  ; al = 0000xxxx, lower half
        jmp hex_2
        
    done_printing:
        pop cx
    ret
endp char2hex

;----------------------------------------
;   convert ascii string to 32bit value
;   and save in var k0,k1,k2,k3

proc key32bit
    push cx
    mov di, offset keys_buffer      ; ascii digit key is stored here
    
                                    ; calculate offset of k0,k1,k2,k3
    add si,3                        ; take number of the key from string key_num
    xor ah,ah                       ; ah = 0
    mov al,[byte si]                ; al = 30h,31h,32h,33h      
    push ax                         ; save
    sub al,30h                      ; al = 0,1,2,3
    shl ax,2                        ; calculat desired offset k0 = 0,k1 = 4,k2 = 8,k3 = 12 bytes
    mov bx,ax                       

    pop ax                          ; restore
    inc al                          ; al = 31h,32h,33h,34h          
    mov [byte si],al                ; next key number
    
    mov si,offset k0            
    add si,bx                       ; [si] here will be each key
    
    push si                         ; save address
    
    xor ch,ch                       ;
    mov cl,[chars_in_buffer]        ; number of digits in the buffer
    
    mov ebx,0                       ; after all the calculations 32bit key will be stored here
    
    cmp cl,0                        ; no digits, only 0dh
    jz end_of_data
    cmp cl,1                        ; 1 digits
    jz last_digit   
    
    
    add di,cx                       ; location of enter in the buffer
    mov [byte di],30h               ; remove 0dh    
    sub di,cx                       ; go back to start of the buffer
    
    dec cx                          ; these digits will be mul by 10, last one will be added
    mov esi,10
        
    key_in_the_buffer:          
        xor eax,eax                 ; eax = 0
        mov al,[di]                 ; [di] - ascii digit            
        sub al,'0'                  ; al = [0...9]      
        add eax,ebx
        mul esi                     ; mul by 10
        jc key_too_big_2
        mov ebx,eax
        
        inc di
        dec cx
        jnz key_in_the_buffer
        
    last_digit: 
        xor eax,eax                 ; eax = 0
        mov al,[di]                 ; [di] - ascii digit            
        sub al,'0'                  ; al = [0...9]
        add eax,ebx         
        jc key_too_big
        mov ebx,eax
        jmp end_of_data
    
    key_too_big_2:
        push di
        mov al,0ch                  ; red digit
        mov di, [trimmed_value]     
        mov [es:di],al
        pop di
        jmp last_digit
        
    key_too_big:        
        mov al,0ch                  ; red digit
        mov di, [trimmed_value]     
        mov [es:di],al
        
    end_of_data:    
        pop si      
        mov [si],ebx                ; save 32bit key to memory

        mov di, [trimmed_value]     ; 
        cmp [byte chars_in_buffer],0; is buffer empty?      
        jnz key_is_visible
        
        mov al,'0'                  ; '0' if user pressed only enter                
        sub di,19                   ; move to the left
        mov [es:di],al              ; show '0'
        add di,19                   ; go back, code uses last value of trimmed_value 

        key_is_visible:
            add di,160              ; next location of "bad" digit
            mov [trimmed_value],di
        
;---------------------------------------        
    mov di, offset keys_buffer      ; clear buffer
        
    mov cx,11
    mov dl,0
        
    clear_keys_buffer:
        mov [di],dl
        inc di
        dec cx
        jnz clear_keys_buffer
        
    pop cx  
    ret
endp key32bit

;----------------------------------------   
;   data encryption

proc encrypt
    pusha

    mov cx, 32
    encryptLoop:
        ; sum += delta
        mov eax, [delta]
        add [sum], eax

        xor eax,eax
        ; ((p2 << 4) + k0)
        mov edx, [p2]
        shl edx, 4
        add edx, [k0]

        ; (p2 + sum)
        mov ebx, [p2]
        add ebx, [sum]

        ; ((p2 << 4) + k0) ^ (p2 + sum)
        xor edx, ebx

        xor ebx, ebx

        ; ((p2 >> 5) + k1)
        mov ebx, [p2]
        shr ebx, 5
        add ebx, [k1]
        ; ((p2 << 4) + k0) ^ (p2 + sum) ^ ((p2 >> 5) + k1)
        xor edx, ebx
        
        ;---
        add [p1],edx
        
        ;add [pe1], edx

        ; ((p1 << 4) + k2)
        mov edx, [p1]
        shl edx, 4
        add edx, [k2]

        ; (p1 + sum)
        mov ebx, [p1]
        add ebx, [sum]

        ; ((p0 << 4) + k2) ^ (p0 + sum)
        xor edx, ebx

        xor ebx, ebx

        ; ((p1 >> 5 ) + k3)
        mov ebx,[p1]
        shr ebx, 5
        add ebx, [k3] 
        ; ((p0 << 4) + k2) ^ (p0 + sum) ^ ((p1 >> 5 ) + k3)
        xor edx, ebx

        add [p2],edx

        ;add [pe2], edx
    loop encryptLoop

    popa
    ret
endp encrypt

;----------------------------------------   
;   data dencryption

proc decrypt
   pusha

    mov cx, 32
    decryptLoop:
       
        ; ((p1 << 4) + k2)
        mov edx, [p1]
        shl edx, 4
        add edx, [k2]

        ; (p1 + sum)
        mov ebx, [p1]
        add ebx, [sum]
        
        ; ((p1 << 4) + k2) ^ (p1 + sum)
        xor edx, ebx

        xor ebx, ebx

        ; ((p1 >> 5) + k3)
        mov ebx, [p1]
        shr ebx, 5
        add ebx, [k3]
        ; ((p1 << 4) + k0) ^ (p2 + sum) ^ ((p1 >> 5) + k3)
        xor edx, ebx
        
        sub [p2], edx   
    
    
        ; ((p2 << 4) + k0)
        mov edx, [p2]
        shl edx, 4
        add edx, [k0]

        ; (p2 + sum)
        mov ebx, [p2]
        add ebx, [sum]

        ; ((p2 << 4) + k0) ^ (p2 + sum)
        xor edx, ebx

        xor ebx, ebx

        ; ((p2 >> 5 ) + k1)
        mov ebx,[p2]
        shr ebx, 5
        add ebx, [k1] 
        ; ((p2 << 4) + k0) ^ (p2 + sum) ^ ((p2 >> 5 ) + k1)
        xor edx, ebx

        sub [p1], edx

        ; sum -= delta
        mov eax, [delta]
        sub [sum], eax
    loop decryptLoop

    popa
    ret
endp decrypt

;----------------------------------------
;   data input, buffer operations
;   di - offset to buffer

proc user_input
    
    mov dh,0                        ; chars counter
    mov dl,0                        ; flag  
    mov si,[input_flag]             ; switch between data sets
                                    ; if keys we need only digits
                                    ; if plain text we want more chars
    new_char:
        mov ah,0                    ; wait for key
        int 16h                     ; BIOS keyboard interrupt
        
;----------------------------------------
        call check_chars            ; we want chars from set 1 or set 2

        ; check flag

        cmp dl,0                    ; 0 - data set 1 - keys (20h - 7fh) 
        jz char_ok                  ; or  data set 2 - keys (30h - 39h) 
                            
        cmp dl,1                    ; 1 - wrong char, do nothing
        jz reset_flag       

        cmp dl,2                    ; 2 - backspace, delete char
        jz key_backspace    

        cmp dl,3                    ; 3 - enter, accept string
        jz insert_0dh       

;----------------------------------------       
        char_ok:
            mov [di],al             ; write to buffer
            inc di                  ; next position in buffer

            mov [es:bx],al          ; write to video mem
            add bx,2                ; next offset in video mem
        
            inc dh                  ; count chars               
            
            cmp si,1                ; switch between data sets
            jz plain_txt_ds
            
            cmp dh,[k_buffer_size]  ; is keys_bufferr full?
            jz insert_0dh           ; yes, we are done here
            jmp new_char            ; no, enter next char
            
            plain_txt_ds:
                cmp dh,[pt_buffer_size] ; is plain_text_buffer full?
                jz insert_0dh           ; yes, we are done here
                jmp new_char            ; no, enter next char
            
;----------------------------------------
        key_backspace:      
            cmp dh,0                ; is buffer empty?
            jz reset_flag           ; yes
                                    ; no
            dec di                  ; move buffer pointer to the left
            dec dh                  ; decrease number of the chars in the buffer 
            mov al,0                ; 
            mov [di],al             ; delete char in buffer
            
            sub bx,2                ; and clear char on the screen too
            mov al,0                ; 
            mov [byte es:bx],0      ; remove char from video mem
            
            reset_flag:
                mov dl,0
            
                jmp new_char        

        insert_0dh:
            mov al,0dh              ; insert enter 
            mov [di],al             ; at the end of the string                  
        
            mov [chars_in_buffer],dh; used in key32bit proc
    ret
endp user_input

;----------------------------------------
;   check_chars
;   proc accepts only chars from data set 1 and 2

proc check_chars
    
    enter_key:
        cmp al,0dh                  ; enter
        mov dl,3                    ; flag = 2, accept entered data
        jz checking_done    

    backspace:
        cmp al,08h                  ; backspace
        mov dl,2                    ; flag = 3, delete previous char
        jz checking_done

    cmp si, 1                       ; plain text data set
    jz plain_txt_data_set
    
    from_30h:                       ; keys data set
        cmp al,30h                  ; 0
        jb wrong_char
        
    to_39h:
        cmp al,39h                  ; 9
        ja wrong_char
        mov dl,0                    ; flag = 0, all good
        jmp checking_done       
    
    plain_txt_data_set:
        from_20h:   
            cmp al,20h              ; space
            jb wrong_char
        
        to_7eh:
            cmp al,7eh              ; tilde
            ja wrong_char           
            mov dl,0                ; flag = 0, all good
            jmp checking_done   
        
    wrong_char:
        mov dl,1                    ; flag = 1, wrong char  
        
    checking_done:      
        ret
endp check_chars

;----------------------------------------
; print string

proc print_text

    next_letter:
        mov ah,0eh
        lodsb       ; al = ds:[si]
        or al,al
        jz done
        
        int 10h
        jmp next_letter
    
    done:
    ret
endp print_text
ends
end start

Как я могу взять строку из ввода и преобразовать ее в шестнадцатеричное значение? кстати, спасибо

ChickenRei 18.05.2024 10:20

Самый простой способ, вероятно, использовать mov ah,0ah, int 21h, как описано, например, здесь: stackoverflow.com/questions/47379024/how-buffered-input-work‌​s. Я пишу свой собственный процесс, который принимает ключи 20h - 7eh, enter, backspace и записывает символы в память. Я обновлю свой код позже.

Nassau 18.05.2024 10:31

Хорошо, теперь пользователь может вводить данные. Я имею в виду простой текст, потому что другие точки еще не соединены. Что теперь? Вы хотите изменить обычный текст на шестнадцатеричный? Это увеличит размер данных в 2 раза. Обычный текст: от ABCD до 41424344 и эта шестнадцатеричная строка будет отправлена ​​в encryption proc?

Nassau 18.05.2024 12:15

Проблема теперь в том, что выходные данные шифрования должны быть читаемыми буквами, чтобы пользователь мог их расшифровать. В своей программе я создал меню, в котором можно выбрать, хочет ли пользователь зашифровать или расшифровать. Итак, как я могу это реализовать? Спасибо !

ChickenRei 18.05.2024 18:03

Итак, вы хотите выводить зашифрованные символы в шестнадцатеричном виде. Например, если A закодировано как F3, используйте mov dl,0F3h,shr dl,4, если значение — цифра, add dl,30h, если буква add dl,37h. То же самое для 3, просто and dl,0fh для очистки верхнего полубайта.

Nassau 18.05.2024 18:22

Можете ли вы добавить это в код, чтобы я мог видеть, что вы имеете в виду, более наглядно?

ChickenRei 18.05.2024 18:38

Давайте продолжим обсуждение в чате.

ChickenRei 18.05.2024 18:41

О db 0dh,0ah,0dh,0ah,... Хотя на платформе DOS нам нужны и 13, и 10 для создания новой строки, когда возникает необходимость в нескольких новых строках подряд, дублировать 13 нет необходимости, так как каретка уже вернулась в левую часть экрана. Если оставить лишние 13, это не повредит, но приведет к бесполезному использованию байтов.

Sep Roland 20.05.2024 00:46

@SepRoland Да, эти байты обычно объединяются в строку. Думаю, это моя вредная привычка копипастить, потому что в этом случае я всегда выделяю и копирую эти два байта. Небольшой шаг к уменьшению размера кода. Спасибо!. :))

Nassau 20.05.2024 08:28

Другие вопросы по теме