One time key for authentication In a recent project I was to create a web service that would be consumed by another application. One of the requirements was to have a key in the service that authenticated the request as valid. But this key must never be the same and the key should be invalid soon after its use.

This is the code I wrote to that purpose.

public static bool isKeyValid(long testKey)
{
    var k = GetKey();

    var allowedVariance = 0.00000000004;
    var variance = k * allowedVariance;

    return (k + variance &gt;= testKey &amp;&amp; k - variance &lt;= testKey);
}

public static long GetKey()
{
    var i = (long)DateTime.UtcNow.Ticks * 5;
    var d = (long)Math.Sqrt(Math.Ceiling(400 - (DateTime.UtcNow.Day * Math.PI)));
    var k = (long)((Math.Round((Math.Sqrt(i) * Math.Pow(Math.PI + d, 3)) * Math.E - d)) * d) + DateTime.UtcNow.Minute;
    return k;
}


The point being that the caller generates a key and the receiver generates its own and then compares these two and says everything is ok if the difference is within a given variance.

Note that nothing in the message is really secret and this is just a simple check so that the request is probably from a valid source.

I have two questions for this. 


How could I have done this better in terms of existing encryption
libraries (in .Net) or using other things such as certificates. This must work     cross platform (Windows, iOS, and Android devices)
How can the given code be modified or improved to make it better for
the intended purpose?
General coding style


avoid using var because it obscures the datatypes.
use meaningful variable names.
when comparing ranges, put the thing being tested in the middle and keep both comparison operators the same.
always use the same value for UtcNow, because the clock is ticking.
document every function you write (1 or 2 lines of comments above each function)


Example:

// Returns true if this key value came from GetKey(), false otherwise.
public static bool IsKeyValid(long testKey)
{
    long k = GetKey();

    double allowedVariance = 0.00000000004;   // say what this is ...

    // You use of 'var' obscured the differing datatypes: k and testKey are long.
    double variance = k * allowedVariance;    

    return (k - variance &lt;= testKey &amp;&amp; testKey &lt;= k + variance);
}

// Returns a key based on the current time.
public static long GetKey()
{
    DateTime now = DateTime.UtcNow;

    // Explanation is called for here...
    long i = now.Ticks * 5;
    long d = (long)Math.Sqrt(Math.Ceiling(400 - (now.Day * Math.PI)));
    long k = (long)((Math.Round((Math.Sqrt(i) * Math.Pow(Math.PI + d, 3)) * Math.E - d)) * d) + now.Minute;

    return k;
}


I know nothing about encryption so cannot say whether there are built-in .NET functions which perform the same task, but there probably are.