Skip to content

Commit

Permalink
Merge pull request #30 from aprismatic/negative_pt_pow
Browse files Browse the repository at this point in the history
Add support for negative and zero plaintext powers
  • Loading branch information
bazzilic committed Aug 1, 2022
2 parents bcc2204 + ac48885 commit 914f127
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 20 deletions.
15 changes: 14 additions & 1 deletion src/Aprismatic.ElGamal/ElGamal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,23 @@ public BigInteger Decode(BigInteger encodedMessage) // TODO: Add tests now that

public byte[] PlaintextPow(ReadOnlySpan<byte> first, BigInteger exp_bi)
{
if (exp_bi.Sign < 0) throw new ArgumentOutOfRangeException(nameof(exp_bi), "Exponent should be >= 0");
if (exp_bi.Sign == 0)
return EncryptData(BigFraction.One);

var halfblock = first.Length >> 1;

if (exp_bi.Sign < 0) { // TODO: avoid copying
// flip the encrypted fraction
var flipped = new byte[first.Length];
first[..halfblock].CopyTo(flipped[halfblock..]);
first[halfblock..].CopyTo(flipped[..halfblock]);

// power the flipped fraction
var flipped_powed = PlaintextPow(flipped, -exp_bi);

return Multiply(first, flipped_powed);
}

var numerator = first[..halfblock];
var denominator = first[halfblock..];

Expand Down
10 changes: 3 additions & 7 deletions test/ElGamalTests/FracMulDiv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public void TestMultiplication_BatchFrac()
{
for (var keySize = minKeySize; keySize <= maxKeySize; keySize += step)
{
var algorithm = new ElGamal(keySize, 0);
var encryptAlgorithm = new ElGamal(algorithm.ToXmlString(false));
var decryptAlgorithm = new ElGamal(algorithm.ToXmlString(true));
using var algorithm = new ElGamal(keySize, 0);
using var encryptAlgorithm = new ElGamal(algorithm.ToXmlString(false));
using var decryptAlgorithm = new ElGamal(algorithm.ToXmlString(true));

BigFraction a, b;
do
Expand Down Expand Up @@ -108,10 +108,6 @@ public void TestMultiplication_BatchFrac()
$"b : {b}{Environment.NewLine}{Environment.NewLine}" +
$"b / a : {b / a}{Environment.NewLine}{Environment.NewLine}" +
$"bda_dec : {bda_dec}");

algorithm.Dispose();
encryptAlgorithm.Dispose();
decryptAlgorithm.Dispose();
}
}
}
Expand Down
111 changes: 99 additions & 12 deletions test/ElGamalTests/PlaintextOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,9 @@ public void TestPlaintextPow()
using var encryptAlgorithm = new ElGamal(algorithm.ToXmlString(false));
using var decryptAlgorithm = new ElGamal(algorithm.ToXmlString(true));

BigFraction a;
do
{
var n = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var d = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
a = new BigFraction(n, d);
} while (a <= 0);
var n = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var d = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var a = new BigFraction(n, d);

var b = rnd.Next(1, 10);

Expand All @@ -192,11 +188,7 @@ public void TestPlaintextPow()
{
using var algorithm = new ElGamal(512, 0);

BigInteger a;
do
{
a = new BigInteger().GenRandomBits(rnd.Next(16, 24), rng);
} while (a <= 0);
var a = new BigInteger().GenRandomBits(rnd.Next(16, 24), rng);

var P = algorithm.P;
var big_exp = BigInteger.Pow(2, 128) + 5;
Expand Down Expand Up @@ -229,5 +221,100 @@ public void TestPlaintextPow()
// TODO: Add tests for 0^x, x^0, 1^x, x^1, 0^1, 1^0
// TODO: Add tests for -2^2 (negative numbers < -2 will cause overflow on smaller key sizes with mxptbits = 128)
}

[Fact(DisplayName = "PLAINTEXT POW BY ZERO")]
public void TestPlaintextPowZero()
{
for (var i = 0; i < Globals.Iterations; i++)
{
for (var keySize = minKeySize; keySize <= maxKeySize; keySize += step)
{
using var algorithm = new ElGamal(keySize, 0);

using var encryptAlgorithm = new ElGamal(algorithm.ToXmlString(false));
using var decryptAlgorithm = new ElGamal(algorithm.ToXmlString(true));

var n = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var d = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var a = new BigFraction(n, d);

n = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
d = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var b = new BigFraction(n, d);
b = -b;

var a_enc = encryptAlgorithm.EncryptData(a);
var b_enc = encryptAlgorithm.EncryptData(b);

var ap0_enc = decryptAlgorithm.PlaintextPow(a_enc, 0);
var bp0_enc = decryptAlgorithm.PlaintextPow(b_enc, 0);
var ap0_dec = decryptAlgorithm.DecryptData(ap0_enc);
var bp0_dec = decryptAlgorithm.DecryptData(bp0_enc);

Assert.True(ap0_dec == 1,
$"{Environment.NewLine}{Environment.NewLine}" +
$"Algorithm parameters (TRUE):{Environment.NewLine}" +
$"{algorithm.ToXmlString(true)}{Environment.NewLine}{Environment.NewLine}" +
$"a : {a}{Environment.NewLine}" +
$"ap0_dec : {ap0_dec}");

Assert.True(bp0_dec == 1,
$"{Environment.NewLine}{Environment.NewLine}" +
$"Algorithm parameters (TRUE):{Environment.NewLine}" +
$"{algorithm.ToXmlString(true)}{Environment.NewLine}{Environment.NewLine}" +
$"a : {b}{Environment.NewLine}" +
$"ap0_dec : {bp0_dec}");
}
}
}

[Fact(DisplayName = "PLAINTEXT POW BY NEGATIVE")]
public void TestPlaintextPowNegative()
{
for (var i = 0; i < Globals.Iterations; i++)
{
for (var keySize = minKeySize; keySize <= maxKeySize; keySize += step)
{
using var algorithm = new ElGamal(keySize, 0);

using var encryptAlgorithm = new ElGamal(algorithm.ToXmlString(false));
using var decryptAlgorithm = new ElGamal(algorithm.ToXmlString(true));

var n = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var d = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var a = new BigFraction(n, d);

n = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
d = new BigInteger().GenRandomBits(rnd.Next(1, 12), rng);
var b = new BigFraction(n, d);
b = -b;

var pow = new BigInteger().GenRandomBits(rnd.Next(2,3), rng);
pow = -pow;

var a_enc = encryptAlgorithm.EncryptData(a);
var b_enc = encryptAlgorithm.EncryptData(b);

var ap0_enc = decryptAlgorithm.PlaintextPow(a_enc, pow);
var bp0_enc = decryptAlgorithm.PlaintextPow(b_enc, pow);
var ap0_dec = decryptAlgorithm.DecryptData(ap0_enc);
var bp0_dec = decryptAlgorithm.DecryptData(bp0_enc);

Assert.True(ap0_dec == new BigFraction(BigInteger.Pow(a.Denominator, (int)(-pow)), BigInteger.Pow(a.Numerator, (int)(-pow))),
$"{Environment.NewLine}{Environment.NewLine}" +
$"Algorithm parameters (TRUE):{Environment.NewLine}" +
$"{algorithm.ToXmlString(true)}{Environment.NewLine}{Environment.NewLine}" +
$"a : {a}{Environment.NewLine}" +
$"ap0_dec : {ap0_dec}");

Assert.True(ap0_dec == new BigFraction(BigInteger.Pow(b.Denominator, (int)(-pow)), BigInteger.Pow(b.Numerator, (int)(-pow))),
$"{Environment.NewLine}{Environment.NewLine}" +
$"Algorithm parameters (TRUE):{Environment.NewLine}" +
$"{algorithm.ToXmlString(true)}{Environment.NewLine}{Environment.NewLine}" +
$"a : {b}{Environment.NewLine}" +
$"ap0_dec : {bp0_dec}");
}
}
}
}
}

0 comments on commit 914f127

Please sign in to comment.