public static (CryptideKey sec, CryptideKey pub) Generate(int bitSize = 128) { var(p, q) = Utils.RandomPrime(bitSize); var g = Utils.GetPrimitiveRoot(p); using (var rdmGen = new RandomField(q)) { var x = rdmGen.Generate(BigInteger.One); var y = BigInteger.ModPow(g, x, p); return(new CryptideKey(true, p, g, x), new CryptideKey(false, p, g, y)); } }
public byte[] EncryptBuffer(string data) { var ms = Utils.Decode(data, Bits); var nums = new List <BigInteger>(); using (var rdm = new RandomField(P)) { for (var i = 0; i < ms.Count; i++) { var r = rdm.Generate(); var c1 = BigInteger.ModPow(G, r, P); var c2 = BigInteger.Remainder(ms[i] * BigInteger.ModPow(Key, r, P), P); nums.Add(c1); nums.Add(c2); } } return(Utils.EncodeByteArray(nums, Bits, true)); }
public static BigInteger getPrimitiveRoot(BigInteger p) { if (p == new BigInteger(2)) { return(BigInteger.One); } var min = new BigInteger(3); // Avoid g=2 because of Bleichenbacher's attack var p1 = new BigInteger(2); // The prime divisors of p-1 are 2 and (p-1)/2 var p2 = (p - 1) / 2; // Because: p = 2q + 1 where q is a prime using (var rdmGen = new RandomField(p)) { while (true) { var g = rdmGen.Generate(min); if (BigInteger.ModPow(g, p1, p) != BigInteger.One && BigInteger.ModPow(g, p2, p) != BigInteger.One && BigInteger.Remainder(p - 1, g) != BigInteger.Zero && // g|p-1 BigInteger.Remainder(p - 1, BigInteger.ModPow(g, p - 2, p)) != BigInteger.Zero) // g^(-1)|p-1 (evades Khadir's attack) { return(g); } } } }