diff --git a/src/Aprismatic.PohligHellman/Aprismatic.PohligHellman.csproj b/src/Aprismatic.PohligHellman/Aprismatic.PohligHellman.csproj
index 1ff4615..65fea81 100644
--- a/src/Aprismatic.PohligHellman/Aprismatic.PohligHellman.csproj
+++ b/src/Aprismatic.PohligHellman/Aprismatic.PohligHellman.csproj
@@ -4,6 +4,6 @@
Extension for the .NET Framework cryptography subsystem, which introduces the Pohlig-Hellman exponentiation cipher.
-
+
\ No newline at end of file
diff --git a/src/Aprismatic.PohligHellman/PohligHellman.cs b/src/Aprismatic.PohligHellman/PohligHellman.cs
index 6add0d9..a2b5f11 100644
--- a/src/Aprismatic.PohligHellman/PohligHellman.cs
+++ b/src/Aprismatic.PohligHellman/PohligHellman.cs
@@ -19,13 +19,14 @@ public class PohligHellman : IDisposable
public PohligHellman(int keySize) {
_rng = RandomNumberGenerator.Create();
KeySize = keySize;
- _keyStruct = CreateKeyPair();
+ var p = BigInteger.One.GenPseudoPrime(KeySize, 16, _rng);
+ _keyStruct = CreateKeyPair(p);
}
- public PohligHellman(BigInteger P) {
+ public PohligHellman(BigInteger p) {
_rng = RandomNumberGenerator.Create();
- KeySize = P.BitCount();
- _keyStruct = CreateKeyPair(P);
+ KeySize = p.BitCount();
+ _keyStruct = CreateKeyPair(p);
}
// TODO: Consolidate constructors in one method
@@ -42,11 +43,6 @@ public PohligHellman(PohligHellmanParameters prms) {
public PohligHellman(string xml) : this(PohligHellmanParameters.FromXml(xml)) { }
// TODO: This method should probably move to KeyStruct
- private PohligHellmanKeyStruct CreateKeyPair() {
- var P = BigInteger.One.GenPseudoPrime(KeySize, 16, _rng);
- return CreateKeyPair(P);
- }
-
private PohligHellmanKeyStruct CreateKeyPair(BigInteger P) {
BigInteger E, D;
var PminusOne = P - BigInteger.One;
@@ -62,7 +58,7 @@ private PohligHellmanKeyStruct CreateKeyPair(BigInteger P) {
public byte[] EncryptData(BigInteger message) {
if (message < 0 || message > MaxEncryptableValue)
- throw new ArgumentException($"Value should be 0 <= m <= {MaxEncryptableValue}", nameof(message));
+ throw new ArgumentException($"Value should be 0 <= m <= {MaxEncryptableValue} under the current encryption key", nameof(message));
var ctbs = _keyStruct.CiphertextLength;
var array = new byte[ctbs];
diff --git a/test/PohligHellmanTests/MainTests.cs b/test/PohligHellmanTests/MainTests.cs
new file mode 100644
index 0000000..0ef7947
--- /dev/null
+++ b/test/PohligHellmanTests/MainTests.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Numerics;
+using System.Security.Cryptography;
+using Aprismatic;
+using Aprismatic.PohligHellman;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace PohligHellmanTests
+{
+ public class MainTests : IDisposable
+ {
+ private readonly ITestOutputHelper _output;
+
+ private readonly Random _rnd = new();
+ private readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
+
+ public MainTests(ITestOutputHelper output) {
+ _output = output;
+ }
+
+ public void Dispose() {
+ _rng.Dispose();
+ }
+
+ [Fact(DisplayName = "Correctness")]
+ public void TestCorrectness() {
+ for (var i = 0; i < Globals.Iterations; i++) {
+ var ks = _rnd.Next(Globals.MinKeyLength, Globals.MaxKeyLength);
+ using var algorithm = new PohligHellman(ks);
+
+ Assert.Equal(ks, algorithm.KeySize);
+
+ var o = BigInteger.Zero.GenRandomBits(1, BigInteger.Pow(2, algorithm.KeySize - 1) - 1, _rng);
+
+ var o_enc = algorithm.EncryptData(o);
+ var o_dec = algorithm.DecryptData(o_enc);
+
+ Assert.Equal(o, o_dec);
+ }
+
+ for (var i = 0; i < Globals.Iterations; i++) {
+ var p = BigInteger.One.GenPseudoPrime(_rnd.Next(Globals.MinKeyLength, Globals.MaxKeyLength), 16, _rng);
+ using var algorithm = new PohligHellman(p);
+
+ Assert.Equal(p, algorithm.P);
+
+ var o = BigInteger.Zero.GenRandomBits(1, BigInteger.Pow(2, algorithm.KeySize - 1) - 1, _rng);
+
+ var o_enc = algorithm.EncryptData(o);
+ var o_dec = algorithm.DecryptData(o_enc);
+
+ Assert.Equal(o, o_dec);
+ }
+ }
+ }
+}