OpenVMS Source-Code Demos
DIFFIE_HELLMAN
1000 %title "diffie_hellman_demo_100.2" !
declare string constant k_version = "100.2" , ! &
k_program = "diffie_hellman_demo" !
!========================================================================================================================
! title : diffie_hellman_demo_100.bas
! author : Neil Rieck ( http://www3.sympatico.ca/n.rieck/ )
! platform: OpenVMS-8.4 (Alpha)
! limits : This program demonstrates key-exchange concepts but is limited to 64-bit math (63-bits if you realize that
! most BASIC dialects, including HP-BASIC for OpenVMS, have no unsigned integers).
! If you choose values which cause y^a1 (or y^b1) to require more than 19 digits, then this program will throw
! an "integer overflow" error.
! history :
! 100 NSR 120722 1. original effort (fails with HP-BASIC-1.7-000)
! NSR 120922 2. coninued work using experimental HP-BASIC-1.7-001
!========================================================================================================================
option size = (real xfloat, integer quad) ! not sure this is required
option type = explicit ! cuz tricks are for kids
!
! Alice's data
!
declare quad a1 ,&
a2 ,&
a3
!
! Bob's data
!
declare quad b1 ,&
b2 ,&
b3
!
! Common data
!
declare quad y ,&
p ,&
alg ,&
modulus_flag ,&
junk%
!
declare string junk$ !
!=======================================================================
! main
!=======================================================================
2000 main:
on error goto trap ! 'old school' error trapping
print k_program +"_"+ k_version !
print string$(len(k_program +"_"+ k_version), asc("=")) !
print
print "Algorithm Menu:" !
print "1) a = (y ^ A) mod p (published)" !
print "2) a = (y + A) (NSR hack)" !
print "3) a = (y x A) (NSR hack)" !
print "4) a = (y + A) mod p (NSR hack)" !
print "5) a = (y x A) mod p (NSR hack)" !
input "algorithm? (1-5, default=1) ";junk$ !
when error in ! 'new school' trapping
alg = integer(junk$) !
use ! oops
print "-e-error: "+ str$(err) !
alg = 0 !
end when !
!
select alg !
case 1 ! published
modulus_flag = 1 !
case 2,3 ! hack
modulus_flag = 0 !
case 4,5 !
alg = alg -2 ! 4,5 >> 2,3
modulus_flag = 1 !
case else !
alg = 1 ! x >> 1
print "defaulting to choice: "+str$(alg) !
modulus_flag = 1 !
end select !
print
if alg=1 then !
print "Caveat: this program employs 64-bit integers. If you choose values which"
print "cause y^a1 (or y^b1) to require more than 19 digits, then this program"
print "will throw an 'integer overflow' error."
print
end if !
!
y = 7
print "enter public value 'y' (default="+str$(y)+") "; !
input junk$ !
when error in !
junk% = integer(junk$) !
use !
junk% = 0 !
end when !
y = junk% if junk% > 0 !
!
p = 11
print "enter public value 'p' (default="+str$(p)+") "; !
input junk$ !
when error in !
junk% = integer(junk$) !
use !
junk% = 0 !
end when !
p = junk% if junk% > 0 !
!=======================================================================
! in a production program, these numbers would be picked randomly
! at the beginning of each communication session
!=======================================================================
a1 = 3 ! Alice's secret number (random)
print "enter Alice's guess (default="+str$(a1)+") "; !
input junk$ !
when error in !
junk% = integer(junk$) !
use !
junk% = 0 !
end when !
a1 = junk% if junk% > 0 !
!
b1 = 19 ! Bob's secret number (random)
print "enter Bob's guess (default="+str$(b1)+") "; !
input junk$ !
when error in !
junk% = integer(junk$) !
use !
junk% = 0 !
end when !
b1 = junk% if junk% > 0 !
!
3000 select alg !
case 1
!
! Alice's calc #1 (private guess >> public)
!
3001 a2 = (y ^ a1) !
3002 a2 = mod(a2, p) if modulus_flag = 1 ! a2 will be sent to BOB
!
! Bob's calc #1 (private guess >> public)
!
3003 b2 = (y ^ b1) !
3004 b2 = mod(b2, p) if modulus_flag = 1 ! b2 will be sent to ALICE
!
! Alice's calc #2
!
3005 a3 = (b2^ a1) ! Alice's computed key
3006 a3 = mod(a3, p) if modulus_flag = 1 !
!
! Bob's calc #2
!
3007 b3 = (a2^ b1) ! Bob's computed key
3008 b3 = mod(b3, p) if modulus_flag = 1 !
case 2
a2 = (y + a1) ! public numbers
a2 = mod(a2, p) if modulus_flag = 1 !
b2 = (y + b1) !
b2 = mod(b2, p) if modulus_flag = 1 !
a3 = (b2 + a1) ! Alice's key
a3 = mod(a3, p) if modulus_flag = 1 !
b3 = (a2 + b1) ! Bob's key
b3 = mod(b3, p) if modulus_flag = 1 !
case 3
a2 = (y * a1) ! public numbers
a2 = mod(a2, p) if modulus_flag = 1 !
b2 = (y * b1) !
b2 = mod(b2, p) if modulus_flag = 1 !
a3 = (b2 * a1) ! Alice's key
a3 = mod(a3, p) if modulus_flag = 1 !
b3 = (a2 * b1) ! Bob's key
b3 = mod(b3, p) if modulus_flag = 1 !
end select !
9999 print "================================================================="
print "Data sent across the channel (Eve can see it):" !
print " public parameter P p : "+ str$(p) !
print " public parameter Y y : "+ str$(y) !
print "Randomly generated private data (never sent):" !
print " Alice's private number a1: "+ str$(a1) !
print " Bob's private key b1: "+ str$(b1) !
print "Computed data sent across the channel (Eve can see it):" !
print " Alice's public number a2: "+ str$(a2) !
print " Bob's public number b2: "+ str$(b2) !
print "Computed private data (never sent):" !
print " Alice's computed key a3: "+ str$(a3) !
print " Bob's computed key b3: "+ str$(b3) !
print "Note: Now Alice and Bob can communicate privately using" !
print " computed key '"+str$(a3)+"' to encrypt/decrypt" !
goto fini !
!=======================================================================
! old school error trapping
!=======================================================================
trap: !
print "error: ";str$(err)
print "line : ";str$(erl)
print "text : ";ert$(err)
resume fini ! fix the stack
!=======================================================================
! that's all folks
!=======================================================================
32000 fini: !
end program 1 ! vms success