implement diffie hellman