DCPU Diffie-Hellman Key Exchange
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; jump | |
set pc, test | |
; TEST DATA | |
:t_a | |
dat 61 | |
:t_g | |
dat 412 | |
:t_p | |
dat 617 | |
:test | |
; we need to get our secret number, preferably randomly | |
set a, [t_a] ; secret number | |
; we also need to know what our pre-agreed prime and general number are | |
set b, [t_g] ; general number | |
set c, [t_p] ; prime number | |
set i, a ; store our secret number | |
jsr calculate_key ; a is now our key | |
set j, a ; store our key | |
; next, we need to send our key to the other person, and await their key | |
jsr test_send_our_key ; ( NEEDS TO BE MANUALLY IMPLEMENTED BASED ON USER SYSTEM ) | |
; get their key ( ALSO NEEDS TO BE MANUALLY IMPLEMENTED BASED ON USER SYSTEM ) | |
jsr test_get_other_key ; a is now their key | |
set b, a ; move their key to b | |
set a, i ; move our secret num to a | |
; c is still prime | |
jsr calculate_s ; a is now s, the shared key. Symmetric-key encryption can now commence. | |
set pc, end | |
:end set pc, end | |
; ARGS: X -> base value, B-> power, C-> mod value | |
; RETURNS: X -> modified value | |
:pow_mod | |
; we need to initialize by calculating the root mod (0x10000 mod C) | |
set push, y ; push registers for init | |
set y, 0xffff ; we need to find 0x10000 mod C without using actual 32-bit mod | |
mod y, c ; because otherwise this would be an infinite recursive loop | |
add y, 1 | |
mod y, c | |
set [root_mod], y ; set root mod variable | |
set y, pop ; re-pop it so we can push it later | |
; we also need to store the actual base value since x changes throughout the recursion | |
set [base_val], x | |
:pow_mod_actual_start | |
; PUSH REGISTERS | |
set push, j | |
set push, i | |
set push, y | |
set push, a | |
set push, b | |
; ALGORITHM | |
set i, b ; check evenness of b | |
mod i, 2 | |
; start testing n | |
ife b, 1 | |
set pc, algo_end ; go back up | |
ife i, 0 ; n is even | |
set pc, n_even ; go to even response | |
ife i, 1 ; n is odd | |
set pc, n_odd ; go to odd response | |
:algo_end | |
; POP REGISTERS | |
set b, pop | |
set a, pop | |
set y, pop | |
set i, pop | |
set j, pop | |
set pc, pop ; return to calling function (might be just another pow_mod recursion) | |
; specific responses | |
:n_even | |
div b, 2 ; n -> n/2 | |
jsr pow_mod_actual_start ; get x^n/2 | |
mul x, x ; do the square of final value | |
set y, ex ; store ex | |
mod y, c ; quick 32-bit mod in case of overflow | |
mul y, [root_mod] | |
mod x, c ; lower word modulus | |
add x, y ; add in lower and higher mods | |
mod x, c ; one last mod | |
set pc, algo_end ; don't test other possibilities | |
:n_odd | |
sub b, 1 ; take out 1 from b | |
jsr pow_mod_actual_start ; get x^(n-1) | |
mul x, [base_val] ; multiply by base value | |
set y, ex ; store ex | |
mod y, c ; quick 32-bit mod in case of overflow | |
mul y, [root_mod] ; actually don't know why this works, too lazy to figure out, but it does | |
mod x, c ; lower word modulus | |
add x, y ; add in lower and higher mods | |
mod x, c ; one last mod | |
set pc, algo_end ; don't test other possibilities | |
; DATA | |
:root_mod | |
dat 0 | |
:base_val | |
dat 0 | |
; ARGS: A-> a, B -> g, C -> p | |
; RETURNS: A -> our key | |
:calculate_key | |
set push, x | |
set x, b ; base value | |
set b, a ; power | |
; c already equals c | |
jsr pow_mod ; do the operation | |
set a, x ; set a to result | |
set x, pop | |
set pc, pop | |
; RETURNS: A -> other key | |
:test_get_other_key | |
set a, 19 ; example number | |
set pc, pop | |
:test_send_our_key ; placeholder | |
set pc, pop | |
; ARGS: A -> our secret num, B -> their key, C -> prime | |
; RETURNS: A -> s | |
:calculate_s | |
set push, x | |
set push, c | |
set push, b | |
set x, b ; base value | |
set b, a ; power | |
set c, [p] ; prime number | |
jsr pow_mod ; do the power/mod | |
set a, x ; set return value | |
set b, pop | |
set c, pop | |
set x, pop | |
set pc, pop | |
:wait | |
set pc, wait |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment