public
Created

DCPU Diffie-Hellman Key Exchange

  • Download Gist
dfe.dasm16
DCPU-16 ASM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
; 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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.