77 lines
1.4 KiB
C#
77 lines
1.4 KiB
C#
using System;
|
|
|
|
namespace Framework
|
|
{
|
|
public class DH64
|
|
{
|
|
private const ulong p = 0xffffffffffffffc5;
|
|
private const ulong g = 5;
|
|
|
|
private static ulong mul_mod_p(ulong a, ulong b) {
|
|
ulong m = 0;
|
|
while (b > 0) {
|
|
if ((b&1) > 0) {
|
|
var t = p - a;
|
|
if (m >= t) {
|
|
m -= t;
|
|
} else {
|
|
m += a;
|
|
}
|
|
}
|
|
if (a >= p-a) {
|
|
a = a*2 - p;
|
|
} else {
|
|
a = a * 2;
|
|
}
|
|
b >>= 1;
|
|
}
|
|
return m;
|
|
}
|
|
|
|
private static ulong pow_mod_p(ulong a, ulong b) {
|
|
if (b == 1) {
|
|
return a;
|
|
}
|
|
var t = pow_mod_p(a, b>>1);
|
|
t = mul_mod_p(t, t);
|
|
if ((b%2) > 0) {
|
|
t = mul_mod_p(t, a);
|
|
}
|
|
return t;
|
|
}
|
|
|
|
private static ulong powmodp(ulong a , ulong b) {
|
|
if (a == 0) {
|
|
throw new Exception("DH64 zero public key");
|
|
}
|
|
if (b == 0) {
|
|
throw new Exception("DH64 zero private key");
|
|
}
|
|
if (a > p) {
|
|
a %= p;
|
|
}
|
|
return pow_mod_p(a, b);
|
|
}
|
|
|
|
private Random rand;
|
|
|
|
public DH64() {
|
|
rand = new Random();
|
|
}
|
|
|
|
public void KeyPair(out ulong privateKey, out ulong publicKey) {
|
|
var a = (ulong)rand.Next();
|
|
var b = (ulong)rand.Next() + 1;
|
|
privateKey = (a<<32) | b;
|
|
publicKey = PublicKey(privateKey);
|
|
}
|
|
|
|
public ulong PublicKey(ulong privateKey) {
|
|
return powmodp(g, privateKey);
|
|
}
|
|
|
|
public ulong Secret(ulong privateKey, ulong anotherPublicKey) {
|
|
return powmodp(anotherPublicKey, privateKey);
|
|
}
|
|
}
|
|
} |