Create a gist now

Instantly share code, notes, and snippets.

DCPU Diffie-Hellman Key Exchange
; 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