Instantly share code, notes, and snippets.

# Scisyhp/dfe.dasm16 Created May 10, 2012

What would you like to do?
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