import dris									# code that communicates with the Dinkey Pro/FD runtime extension
import sys									# so we can load the correct extension dependent on OS & bitness

# The sample code contains 10 functions. You will not need to use all these
# functions in your code. Just use which ever functions are most appropriate
# and customise in your own way. The sample code is just a guide. You should
# implement the protection in a stronger way using the techniques described in
# the "Increasing your Protection" chapter of the manual.
#
# If you are using Dinkey Lite then you can only use 4 functions:
# ProtCheck, ProtCheckWithAlg, ProtCheckEnc, ProtCheckWithAlgEnc


# this file contains 10 protection-check functions.
# ProtCheck                           a standard protection check
# ProtCheckWithAlg                    a protection check & executing an Algorithm
# WriteBytes                          a protection check & write data to the dongle
# ReadBytes                           a protection check & read data from the dongle
# EncryptUserData                     a protection check & encrypting data and then decrypting the data

# these functions are the same as the functions listed above but encrypting all parameters passed to our API
# ProtCheckEnc                        a standard protection check
# ProtCheckWithAlgEnc                 a protection check & executing an Algorithm
# WriteBytesEnc                       a protection check & write data to the dongle
# ReadBytesEnc                        a protection check & read data from the dongle
# EncryptUserDataEnc                  a protection check & encrypting data and then decrypting the data

MY_SDSN = 10101             # !!!! change this value to be the value of your SDSN (demo = 10101)
MY_PRODCODE = "DEMO"		# !!!! change this value to be the value of the Product Code in the dongle

# *************************  our 10 functions **********************************

# **************************  ProtCheck  ***************************************
def ProtCheck():
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.PROTECTION_CHECK)        # standard protection check
	dris.set_flags(mydris, 0)                               # no extra flags, but you may want to specify some if you want to start a network user or decrement execs,...
	
	ret_code = DDProtCheck(mydris)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return
	
	if (dris.get_prodcode(mydris) != MY_PRODCODE):
		print("Incorrect Product Code! Please modify your source code so that MY_PRODCODE is set to be the Product Code in the dongle.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	print("It worked!")
	return ret_code

# **************************  ProtCheckWithAlg  ******************************

# this function should be used instead of % for modulo as python calculates this differently to C for negative numbers
def mod(x, y):
	return abs(x)%abs(y)*(1,-1)[x<0]

# this function should be used instead of // for integer division as python calculates this differently to C for negative numbers
def div(x, y):
	if (x >= 0) != (y >= 0) and x % y:
		return x // y + 1
	else:
		return x // y

# !!!! You should replace this function with the one generated by the
# "generate source code" button in Algorithm tab for DinkeyAdd (if you have specified an algorithm)
# or from DinkeyLook if you are using a Dinkey Lite dongle.
# (If it does not generate source code for Python you have translate it from C but use the mod function instead of % and div instead of //)
def MyAlgorithm(a, b, c, d, e, f, g, h):
	value = a + b + c + d + e + f + g + h       # place your algorithm here using mod instead of % and div instead of // 
	return dris.make_signed32bit(value)         # this line always needs to be here to convert the value to a signed 32bit integer

# NB for this to work you must program at least "user algorithm" into the dongle
# NB We have used a very simple algorithm here (in the MyAlgorithm function). You must patch this with the
# sample code generated by DinkeyAdd for the algorithm that you are using.  For Lite models copy the sample
# code from DinkeyLook
def ProtCheckWithAlg():
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.EXECUTE_ALGORITHM)       # standard protection check & execute algorithm
	dris.set_flags(mydris, 0)                               # no extra flags, but you may want to specify some if you want to start a network user or decrement execs,...
	dris.set_alg_number(mydris, 1)                          # execute algorithm 1 (you do not need to specify this field if you are only using Lite models).
	# you should remove these entries if you are using Dinkey Lite so that algorithm arguments are random
	dris.set_var_a(mydris, 1)                               # sample values
	dris.set_var_b(mydris, 2)
	dris.set_var_c(mydris, 3)
	dris.set_var_d(mydris, 4)
	dris.set_var_e(mydris, 5)
	dris.set_var_f(mydris, 6)
	dris.set_var_g(mydris, 7)
	dris.set_var_h(mydris, 8)

	ret_code = DDProtCheck(mydris)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	# if you want you can check the algorithm answer - however if algorithm is from your code then best to just use the answer in your code
	# !!!! Make sure you have replaced the MyAlgorithm routine with the algorithm you have specified in DinkeyAdd
	if MyAlgorithm(dris.get_var_a(mydris), dris.get_var_b(mydris), dris.get_var_c(mydris), dris.get_var_d(mydris), dris.get_var_e(mydris), \
		dris.get_var_f(mydris), dris.get_var_g(mydris), dris.get_var_h(mydris)) != dris.get_alg_answer(mydris):
		print("Dinkey protection error!\nYou have not patched your algorithm in the MyAlgorithm routine")
		return

	print("It worked!")
	return ret_code

# **************************  WriteBytes  ******************************
# This writes the string "Hello, World!" to the dongle data area at offset 7
# In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
def WriteBytes():
	datatowrite = bytearray("Hello, World!", "ascii")
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.WRITE_DATA_AREA)         # standard protection check and write data
	dris.set_flags(mydris, dris.USE_FUNCTION_ARGUMENT)      # we have to do it this way in Python
	dris.set_rw_offset(mydris, 7)
	dris.set_rw_length(mydris, len(datatowrite))

	ret_code = DDProtCheck(mydris, datatowrite)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	print("It worked!")
	return ret_code

# ************************  ReadBytes  ************************************
# This reads 13 bytes of data from offset 7 in the dongle data area
# In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
# In order for the data to be displayed properly by this routine it will need to be text data
def ReadBytes():
	datatoread = bytearray(13)
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.READ_DATA_AREA)          # standard protection check and read data
	dris.set_flags(mydris, dris.USE_FUNCTION_ARGUMENT)      # we have to do it this way in Python
	dris.set_rw_offset(mydris, 7)
	dris.set_rw_length(mydris, len(datatoread))

	ret_code = DDProtCheck(mydris, datatoread)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	print("It worked! Dinkey Dongle Data area, offset 7 is " + datatoread.decode("ascii"))
	return ret_code

# **************************  EncryptUserData  ****************************
# This function will do a protection check and ask the dongle to encrypt some data using encryption key 1
# It will then do another protection check & decrypt the data
def EncryptUserData():
	data = bytearray("Hello, World!", "ascii")
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.ENCRYPT_USER_DATA)       # standard protection check and encrypt data
	dris.set_flags(mydris, dris.USE_FUNCTION_ARGUMENT)      # we have to do it this way in Python
	dris.set_data_crypt_key_num(mydris, 1)
	dris.set_rw_length(mydris, len(data))

	ret_code = DDProtCheck(mydris, data)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# ... could add code to check other elements of the DRIS, e.g. ret_code, sdsn, ...

	# Now decrypt this (encrypted) data to get the original values
	mydris2 = dris.create()
	dris.set_function(mydris2, dris.DECRYPT_USER_DATA)      # standard protection check and decrypt data
	dris.set_flags(mydris2, dris.USE_FUNCTION_ARGUMENT)     # we have to do it this way in Python
	dris.set_data_crypt_key_num(mydris2, 1)
	dris.set_rw_length(mydris2, len(data))

	ret_code = DDProtCheck(mydris2, data)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris2))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris2) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris2) != 0):
		print("Dinkey Dongle protection error")
		return

	print("It worked! Data decrypted is " + data.decode("ascii"))
	return ret_code

# !!!!!!!!!!!   all the functions listed below encrypt all parameters to our API  !!!!!!!!!!!!!!!!!!!!!
# In order for them to work properly you need to choose "Encrypt DRIS" and "Encrypt Data passed to API"
# in the Extra Security tab of DinkeyAdd. In this example, for Data Encryption I use the r/w algorithm
# but the code can be modified easily to use the 3 encryption parameters.

# !!!! please overwrite this function with the one generated by DinkeyAdd for R/W Algorithm
# NB DinkeyAdd currently does not generate code for Python so you will have to translate it from C
def MyRWAlgorithm(a, b, c, d, e, f, g, h):
	value = a ^ b ^ c ^ d ^ e ^ f
	return dris.make_signed32bit(value)

# !!!! please overwrite this function with the one generated by DinkeyAdd
# It is not generated by DinkeyAdd for Python currently so just modify parameters 1,2 and 3 accordingly
def CryptDRIS(mydris):
	bigseed = bytearray(256)
	S = bytearray(256)

	for i in range(0, 256, 8):
		bigseed[i:i+4] = mydris[8:12]						# seed1
		bigseed[i+4:i+8] = mydris[12:16]					# seed2

	for i in range(256):
		S[i] = i

	j = 0
	for i in range(256):
		j = (j + S[i] + bigseed[i] + 123) % 256			    # !!!! parameter 1
		temp = S[i]
		S[i] = S[j]
		S[j] = temp

	i = 0
	j = 0
	for k in range(16,dris.DRIS_SIZE):
		i = (i + 1) % 256
		j = (j + S[i] + 212) % 256							# !!!! parameter 2
		temp = S[i]
		S[i] = S[j]
		S[j] = temp
		t = (S[i] + S[j] + 97) % 256						# !!!! parameter 3
		mydris[k] = mydris[k] ^ S[t]
	return

# !!!! please overwrite this function with the one generated by DinkeyAdd
# It is not generated by DinkeyAdd for Python currently. This is set-up for using r/w parameters
def CryptApiData(data, mydris, length, alg_answer):
	bigseed = bytearray(256)
	S = bytearray(256)

	for i in range(0, 256, 8):
		bigseed[i:i+4] = mydris[8:12]						# seed1
		bigseed[i+4:i+8] = mydris[12:16]					# seed2

	for i in range(256):
		S[i] = i

	j = 0
	for i in range(256):
		j = (j + S[i] + bigseed[i] + (alg_answer & 0xff)) % 256			# parameter 1
		temp = S[i]
		S[i] = S[j]
		S[j] = temp

	i = 0
	j = 0
	for k in range(length):
		i = (i + 1) % 256
		j = (j + S[i] + ((alg_answer >> 8) & 0xff)) % 256				# parameter 2
		temp = S[i]
		S[i] = S[j]
		S[j] = temp
		t = (S[i] + S[j] + ((alg_answer >> 16) & 0xff)) % 256			# parameter 3
		data[k] = data[k] ^ S[t]
	return

# *************************  ProtCheckEnc  *******************************
def ProtCheckEnc():
	# We encrypt the DRIS passed to the API. Patch the CryptDRIS function in this file from source code generated by DinkeyAdd.
	mydris = dris.create()
	dris.set_function(mydris, dris.PROTECTION_CHECK)        # standard protection check
	dris.set_flags(mydris, 0)                               # no extra flags, but you may want to specify some if you want to start a network user or decrement execs,...

	CryptDRIS(mydris)                                       # encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	ret_code = DDProtCheck(mydris)

	CryptDRIS(mydris)                                       # decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	if (dris.get_prodcode(mydris) != MY_PRODCODE):
		print("Incorrect Product Code! Please modify your source code so that MY_PRODCODE is set to be the Product Code in the dongle.")
		return
		
	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	print("It worked!")
	return ret_code

# ************************  ProtCheckWithAlgEnc  ***********************
# NB for this to work you must program at least "user algorithm" into the dongle
# NB We have used a very simple algorithm here (in the MyAlgorithm function). You must patch this with the
# sample code generated by DinkeyAdd for the algorithm that you are using.  For Lite models copy the sample
# code from DinkeyLook
# We encrypt the DRIS passed to the API. Patch the CryptDRIS function in this file from source code generated by DinkeyAdd.
def ProtCheckWithAlgEnc():
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.EXECUTE_ALGORITHM)       # standard protection check & execute algorithm
	dris.set_flags(mydris, 0)                               # no extra flags, but you may want to specify some if you want to start a network user or decrement execs,...
	dris.set_alg_number(mydris, 1)                          # execute algorithm 1 (you do not need to specify this field if you are only using Lite models).
	# you should remove these entries if you are using Dinkey Lite so that algorithm arguments are random
	dris.set_var_a(mydris, 1)                               # sample values
	dris.set_var_b(mydris, 2)
	dris.set_var_c(mydris, 3)
	dris.set_var_d(mydris, 4)
	dris.set_var_e(mydris, 5)
	dris.set_var_f(mydris, 6)
	dris.set_var_g(mydris, 7)
	dris.set_var_h(mydris, 8)

	CryptDRIS(mydris)                                       # encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	ret_code = DDProtCheck(mydris)

	CryptDRIS(mydris)                                       # decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	# if you want you can check the algorithm answer - however if algorithm is from your code then best to just use the answer in your code
	# !!!! Make sure you have replaced the MyAlgorithm routine with the algorithm you have specified in DinkeyAdd
	if MyAlgorithm(dris.get_var_a(mydris), dris.get_var_b(mydris), dris.get_var_c(mydris), dris.get_var_d(mydris), dris.get_var_e(mydris), \
			dris.get_var_f(mydris), dris.get_var_g(mydris), dris.get_var_h(mydris)) != dris.get_alg_answer(mydris):
		print("Dinkey protection error!\nYou have not patched your algorithm in the MyAlgorithm routine")
		return

	print("It worked!")
	return ret_code

# **************************  WriteBytesEnc  ******************************
# This writes the string "Hello, World!" to the dongle data area at offset 7
# In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
# We encrypt the DRIS and Data passed to the API. Patch the CryptDRIS and CryptApiData functions in this file from source code generated by DinkeyAdd.
def WriteBytesEnc():
	datatowrite = bytearray("Hello, World!", "ascii")
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.WRITE_DATA_AREA)         # standard protection check and write data
	dris.set_flags(mydris, dris.USE_FUNCTION_ARGUMENT)      # we have to do it this way in Python
	dris.set_rw_offset(mydris, 7)
	dris.set_rw_length(mydris, len(datatowrite))

	# calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code for r/w algorithm
	alg_ans = MyRWAlgorithm(dris.get_var_a(mydris), dris.get_var_b(mydris), dris.get_var_c(mydris), dris.get_var_d(mydris), \
				dris.get_var_e(mydris), dris.get_var_f(mydris), dris.get_var_g(mydris), dris.get_var_h(mydris))

	# encrypt data we want to write.
	CryptApiData(datatowrite, mydris, len(datatowrite), alg_ans)

	CryptDRIS(mydris)                                       # encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	ret_code = DDProtCheck(mydris, datatowrite)

	CryptDRIS(mydris)                                       # decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	print("It worked!")
	return ret_code

# ************************  ReadBytesEnc  ************************************
# This reads 13 bytes of data from offset 7 in the dongle data area
# In order for this function to work you will need to have a data area in your dongle that is at least 21 bytes long.
# In order for the data to be displayed properly by this routine it will need to be text data
#  We encrypt the DRIS and Data passed from the API. Patch the CryptDRIS and CryptApiData functions in this file from source code generated by DinkeyAdd.
def ReadBytesEnc():
	datatoread = bytearray(13)
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.READ_DATA_AREA)          # standard protection check and read data
	dris.set_flags(mydris, dris.USE_FUNCTION_ARGUMENT)      # we have to do it this way in Python
	dris.set_rw_offset(mydris, 7)
	dris.set_rw_length(mydris, len(datatoread))

	# calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code for r/w algorithm
	alg_ans = MyRWAlgorithm(dris.get_var_a(mydris), dris.get_var_b(mydris), dris.get_var_c(mydris), dris.get_var_d(mydris), \
				dris.get_var_e(mydris), dris.get_var_f(mydris), dris.get_var_g(mydris), dris.get_var_h(mydris))

	CryptDRIS(mydris)                                       # encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	ret_code = DDProtCheck(mydris, datatoread)

	CryptDRIS(mydris)                                       # decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris) != 0):
		print("Dinkey Dongle protection error")
		return

	# decrypt data that was read
	CryptApiData(datatoread, mydris, len(datatoread), alg_ans)
	print("It worked! Dinkey Dongle Data area, offset 7 is " + datatoread.decode("ascii"))
	return ret_code

# **************************  EncryptUserDataEnc  ****************************
# This function will do a protection check and ask the dongle to encrypt some data using encryption key 1
# It will then do another protection check & decrypt the data
# We encrypt the DRIS and Data passed to/from the API. Patch the CryptDRIS and CryptApiData functions in this file from source code generated by DinkeyAdd.
def EncryptUserDataEnc():
	data = bytearray("Hello, World!", "ascii")
	# create the DRIS and allocate the values we want to use
	mydris = dris.create()
	dris.set_function(mydris, dris.ENCRYPT_USER_DATA)       # standard protection check and encrypt data
	dris.set_flags(mydris, dris.USE_FUNCTION_ARGUMENT)      # we have to do it this way in Python
	dris.set_data_crypt_key_num(mydris, 1)
	dris.set_rw_length(mydris, len(data))

	# calculate r/w algorithm answer - NB need to replace MyRWAlgorithm code with code for r/w algorithm
	alg_ans = MyRWAlgorithm(dris.get_var_a(mydris), dris.get_var_b(mydris), dris.get_var_c(mydris), dris.get_var_d(mydris), \
				dris.get_var_e(mydris), dris.get_var_f(mydris), dris.get_var_g(mydris), dris.get_var_h(mydris))

	# encrypt data we want to pass.
	CryptApiData(data, mydris, len(data), alg_ans)

	CryptDRIS(mydris)                                       # encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	ret_code = DDProtCheck(mydris, data)

	CryptDRIS(mydris)                                       # decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris))
		return

	# ... could add code to check other elements of the DRIS, e.g. ret_code, sdsn, ...

	# Now decrypt this (encrypted) data to get the original values
	mydris2 = dris.create()
	dris.set_function(mydris2, dris.DECRYPT_USER_DATA)      # standard protection check and decrypt data
	dris.set_flags(mydris2, dris.USE_FUNCTION_ARGUMENT)     # we have to do it this way in Python
	dris.set_data_crypt_key_num(mydris2, 1)
	dris.set_rw_length(mydris2, len(data))

	CryptDRIS(mydris2)                                      # encrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	ret_code = DDProtCheck(mydris2, data)

	CryptDRIS(mydris2)                                      # decrypt DRIS (!!!!you should separate from DDProtCheck for greater security)

	if (ret_code != 0):
		dris.DisplayError(ret_code, dris.get_ext_err(mydris2))
		return

	# later in your code you can check other values in the DRIS...
	if (dris.get_sdsn(mydris2) != MY_SDSN):
		print("Incorrect SDSN! Please modify your source code so that MY_SDSN is set to be your SDSN.")
		return

	# later on in your program you can check the return code again
	if (dris.get_ret_code(mydris2) != 0):
		print("Dinkey Dongle protection error")
		return

	alg_ans = MyRWAlgorithm(dris.get_var_a(mydris2), dris.get_var_b(mydris2), dris.get_var_c(mydris2), dris.get_var_d(mydris2), \
				dris.get_var_e(mydris2), dris.get_var_f(mydris2), dris.get_var_g(mydris2), dris.get_var_h(mydris2))

	# decrypt data passed to us by the API
	CryptApiData(data, mydris2, len(data), alg_ans)

	print("It worked! Data decrypted is " + data.decode("ascii"))
	return ret_code

# entry point
if __name__ == "__main__":
	# load the correct extension dependent on the OS and bitness of Python
	if sys.platform == 'win32':
		if sys.maxsize > 2**32:
			from dpwin64py import DDProtCheck
		else:
			from dpwin32py import DDProtCheck
	elif 'linux' in sys.platform:
		if sys.maxsize > 2**32:
			from dplin64py import DDProtCheck
		else:
			from dplin32py import DDProtCheck
	elif sys.platform == 'darwin':
		if sys.maxsize > 2**32:
			from dpmac64py import DDProtCheck
		else:
			from dpmac32py import DDProtCheck

	# choose the protection check function of your choice here. We have chosen the basic protection check.
	ProtCheck()
