diff --git a/src/Aprismatic.PaillierExt/Aprismatic.PaillierExt.csproj b/src/Aprismatic.PaillierExt/Aprismatic.PaillierExt.csproj
index 996ed15..67831cf 100644
--- a/src/Aprismatic.PaillierExt/Aprismatic.PaillierExt.csproj
+++ b/src/Aprismatic.PaillierExt/Aprismatic.PaillierExt.csproj
@@ -1,11 +1,11 @@
- netstandard2.0
+ netstandard2.1
Extension for the .NET Framework cryptography subsystem, which introduces the Paillier public key cryptosystem with support for homomorphic addition.
-
-
+
+
diff --git a/src/Aprismatic.PaillierExt/Paillier.cs b/src/Aprismatic.PaillierExt/Paillier.cs
index 53a483c..32cbf6e 100644
--- a/src/Aprismatic.PaillierExt/Paillier.cs
+++ b/src/Aprismatic.PaillierExt/Paillier.cs
@@ -7,105 +7,129 @@
namespace Aprismatic.PaillierExt
{
- public class Paillier : AsymmetricAlgorithm
+ public class Paillier : AsymmetricAlgorithm, IDisposable
{
- private PaillierKeyStruct keyStruct;
+ private readonly PaillierKeyStruct keyStruct;
+ private readonly PaillierEncryptor encryptor;
+ private readonly PaillierDecryptor decryptor;
- public PaillierKeyStruct KeyStruct
+ public Paillier(int keySize)
{
- get
- {
- if (NeedToGenerateKey())
- {
- CreateKeyPair(KeySizeValue);
- }
- return keyStruct;
- }
- set => keyStruct = value;
+ LegalKeySizesValue = new[] { new KeySizes(384, 1088, 8) };
+ KeySizeValue = keySize;
+ keyStruct = CreateKeyPair();
+ encryptor = new PaillierEncryptor(keyStruct);
+ decryptor = new PaillierDecryptor(keyStruct);
}
- public Paillier()
+ public Paillier(PaillierParameters prms)
{
- keyStruct = new PaillierKeyStruct
- {
- N = BigInteger.Zero,
- G = BigInteger.Zero,
- Lambda = BigInteger.Zero,
- Miu = BigInteger.Zero
- };
+ LegalKeySizesValue = new[] { new KeySizes(384, 1088, 8) };
- // set the default key size value
- KeySizeValue = 384;
+ keyStruct = new PaillierKeyStruct(
+ new BigInteger(prms.N),
+ new BigInteger(prms.G),
+ (prms.Lambda?.Length ?? 0) > 0 ? new BigInteger(prms.Lambda) : BigInteger.Zero,
+ (prms.Miu?.Length ?? 0) > 0 ? new BigInteger(prms.Miu) : BigInteger.Zero
+ );
- // set the range of legal keys
- LegalKeySizesValue = new[] { new KeySizes(384, 1088, 8) };
+ KeySizeValue = keyStruct.NLength * 8;
+
+ encryptor = new PaillierEncryptor(keyStruct);
+ decryptor = new PaillierDecryptor(keyStruct);
}
- private bool NeedToGenerateKey()
+ public Paillier(string Xml)
{
- return keyStruct.N == 0
- && keyStruct.G == 0;
+ LegalKeySizesValue = new[] { new KeySizes(384, 1088, 8) };
+
+ var prms = new PaillierParameters();
+ var keyValues = XDocument.Parse(Xml).Element("PaillierKeyValue");
+ prms.N = Convert.FromBase64String((String) keyValues.Element("N") ?? "");
+ prms.G = Convert.FromBase64String((String) keyValues.Element("G") ?? "");
+ prms.Lambda = Convert.FromBase64String((String) keyValues.Element("Lambda") ?? "");
+ prms.Miu = Convert.FromBase64String((String) keyValues.Element("Miu") ?? "");
+
+ keyStruct = new PaillierKeyStruct(
+ new BigInteger(prms.N),
+ new BigInteger(prms.G),
+ new BigInteger(prms.Lambda),
+ new BigInteger(prms.Miu)
+ );
+
+ KeySizeValue = keyStruct.NLength * 8;
+
+ encryptor = new PaillierEncryptor(keyStruct);
+ decryptor = new PaillierDecryptor(keyStruct);
}
+ public int MaxPlaintextBits() => PaillierKeyStruct.MaxPlaintextBits;
+ public BigInteger PlaintextExp => PaillierKeyStruct.PlaintextExp;
+ public int GetPlaintextDecPlace() => PaillierKeyStruct.PlaintextDecPlace;
+
// TODO: check again for Miu
- private void CreateKeyPair(int pKeyStrength)
+ private PaillierKeyStruct CreateKeyPair()
{
+ BigInteger N, Lambda, G, Miu;
+
// create the large prime number, p and q
- // p and q are assumed to have the same bit length (512 bit each, so that N is 1024)
- // if N length is not the same to KeySize, will regenerate p and q which will make a new N
- using (var rng = RandomNumberGenerator.Create())
+ // p and q are assumed to have the same bit length (e.g., 192 bit each, so that N is 384)
+ // if N length is not the same to keySize, will regenerate p and q which will make a new N
+ using var rng = RandomNumberGenerator.Create();
+ var p = new BigInteger();
+ var q = new BigInteger();
+ var halfKeyStrength = KeySizeValue >> 1; // div 2
+ do
{
- var p = new BigInteger();
- var q = new BigInteger();
- do
- {
- p = p.GenPseudoPrime(pKeyStrength / 2, 16, rng);
- q = q.GenPseudoPrime(pKeyStrength / 2, 16, rng);
-
- // compute N
- // N = p*q
- keyStruct.N = p * q;
- } while (KeyStruct.getNLength() != pKeyStrength / 8);
-
- // compute G
- // First option: g is random in Z*(n^2)
-
- // Second option: g = n + 1
- keyStruct.G = keyStruct.N + 1;
-
- // compute lambda
- // lambda = lcm(p-1, q-1) = (p-1)*(q-1)/gcd(p-1, q-1)
- // or simpler variant, lambda = (p-1)(q-1), since p and q have same length
- keyStruct.Lambda = (p - 1) * (q - 1);
-
- // Miu = (L(g^lambda mod NSq))^-1 mod n
- // or simple: Miu = lambda^-1 (mod n)
- keyStruct.Miu = keyStruct.Lambda.ModInverse(keyStruct.N);
- }
+ p = p.GenPseudoPrime(halfKeyStrength, 16, rng);
+ q = q.GenPseudoPrime(halfKeyStrength, 16, rng);
+
+ // compute N
+ // N = p*q
+ N = p * q;
+ } while (N.BitCount() < KeySizeValue - 7);
+
+ // compute G
+ // First option: G is random in Z*(N^2)
+ // Second option: G = N + 1
+ G = N + 1;
+
+ // compute lambda
+ // lambda = lcm(p-1, q-1) = (p-1)*(q-1)/gcd(p-1, q-1)
+ // or simpler variant, lambda = (p-1)(q-1), since p and q have same length
+ Lambda = (p - 1) * (q - 1);
+
+ // Miu = (L(g^lambda mod NSq))^-1 mod n
+ // or simple: Miu = lambda^-1 (mod n)
+ Miu = Lambda.ModInverse(N);
+
+ return new PaillierKeyStruct(N, G, Lambda, Miu);
}
- public byte[] EncryptData(BigFraction message)
+ public byte[] EncryptDataOld(BigFraction message)
{
- if (NeedToGenerateKey())
- {
- CreateKeyPair(KeySizeValue);
- }
-
using (var encryptor = new PaillierEncryptor(keyStruct))
{
- return encryptor.ProcessBigInteger(message);
+ return encryptor.ProcessBigIntegerOld(message);
}
}
- public BigFraction DecryptData(byte[] p_data)
+ public byte[] EncryptData(BigFraction message)
{
- if (NeedToGenerateKey())
- {
- CreateKeyPair(KeySizeValue);
- }
+ var res = new byte[keyStruct.CiphertextBlocksize * 2];
+ encryptor.ProcessBigInteger(message, res.AsSpan());
+ return res;
+ }
+ public BigFraction DecryptDataOld(byte[] p_data)
+ {
var decryptor = new PaillierDecryptor(keyStruct);
+ return decryptor.ProcessByteBlockOld(p_data);
+ }
+
+ public BigFraction DecryptData(byte[] p_data)
+ {
return decryptor.ProcessByteBlock(p_data);
}
@@ -140,53 +164,12 @@ public override string ToXmlString(bool includePrivateParameters)
return sb.ToString();
}
- public override void FromXmlString(string str)
- {
- var prms = new PaillierParameters();
-
- var keyValues = XDocument.Parse(str).Element("PaillierKeyValue");
-
- prms.N = Convert.FromBase64String((String)keyValues.Element("N") ?? "");
- prms.G = Convert.FromBase64String((String)keyValues.Element("G") ?? "");
- prms.Lambda = Convert.FromBase64String((String)keyValues.Element("Lambda") ?? "");
- prms.Miu = Convert.FromBase64String((String)keyValues.Element("Miu") ?? "");
-
- ImportParameters(prms);
- }
-
- public void ImportParameters(PaillierParameters parameters)
- {
- keyStruct.N = new BigInteger(parameters.N);
- keyStruct.G = new BigInteger(parameters.G);
-
- if (parameters.Lambda != null
- && parameters.Lambda.Length > 0
- && parameters.Miu != null
- && parameters.Miu.Length > 0)
- {
- keyStruct.Lambda = new BigInteger(parameters.Lambda);
- keyStruct.Miu = new BigInteger(parameters.Miu);
- }
- else
- {
- keyStruct.Lambda = BigInteger.Zero;
- keyStruct.Miu = BigInteger.Zero;
- }
-
- KeySizeValue = keyStruct.N.BitCount();
- }
-
public PaillierParameters ExportParameters(bool includePrivateParams)
{
- if (NeedToGenerateKey())
- {
- CreateKeyPair(KeySizeValue);
- }
-
var prms = new PaillierParameters
{
N = keyStruct.N.ToByteArray(),
- G = keyStruct.G.ToByteArray(),
+ G = keyStruct.G.ToByteArray()
};
// if required, include the private value, X
@@ -204,5 +187,10 @@ public PaillierParameters ExportParameters(bool includePrivateParams)
return prms;
}
+
+ public new void Dispose()
+ {
+ encryptor.Dispose();
+ }
}
}
diff --git a/src/Aprismatic.PaillierExt/PaillierAbstractCipher.cs b/src/Aprismatic.PaillierExt/PaillierAbstractCipher.cs
deleted file mode 100644
index bb3eb96..0000000
--- a/src/Aprismatic.PaillierExt/PaillierAbstractCipher.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Aprismatic.PaillierExt
-{
- public abstract class PaillierAbstractCipher
- {
- protected readonly int CiphertextBlocksize;
- protected PaillierKeyStruct KeyStruct;
-
- public PaillierAbstractCipher(PaillierKeyStruct keyStruct)
- {
- KeyStruct = keyStruct;
- CiphertextBlocksize = keyStruct.getCiphertextBlocksize();
- }
- }
-}
diff --git a/src/Aprismatic.PaillierExt/PaillierDecryptor.cs b/src/Aprismatic.PaillierExt/PaillierDecryptor.cs
index 69a6583..efb0cf6 100644
--- a/src/Aprismatic.PaillierExt/PaillierDecryptor.cs
+++ b/src/Aprismatic.PaillierExt/PaillierDecryptor.cs
@@ -3,13 +3,16 @@
namespace Aprismatic.PaillierExt
{
- public class PaillierDecryptor : PaillierAbstractCipher
+ public class PaillierDecryptor
{
+ private readonly PaillierKeyStruct _keyStruct;
+
public PaillierDecryptor(PaillierKeyStruct keyStruct)
- : base(keyStruct)
- { }
+ {
+ _keyStruct = keyStruct;
+ }
- public BigFraction ProcessByteBlock(byte[] block)
+ public BigFraction ProcessByteBlockOld(byte[] block)
{
var block_half = new byte[block.Length / 2];
Array.Copy(block, block_half, block.Length / 2);
@@ -17,17 +20,29 @@ public BigFraction ProcessByteBlock(byte[] block)
// calculate M
// m = (c^lambda(mod nsquare) - 1) / n * miu (mod n)
- var m = (BigInteger.ModPow(bBlock, KeyStruct.Lambda, KeyStruct.NSquare) - 1) / KeyStruct.N * KeyStruct.Miu % KeyStruct.N;
+ var m = (BigInteger.ModPow(bBlock, _keyStruct.Lambda, _keyStruct.NSquare) - 1) / _keyStruct.N * _keyStruct.Miu % _keyStruct.N;
+
+ return Decode(m);
+ }
+
+ public BigFraction ProcessByteBlock(byte[] block)
+ {
+ var bBlock = new BigInteger(block.AsSpan(0, block.Length >> 1)); // div 2
+
+ // calculate M
+ // m = (c^lambda(mod nsquare) - 1) / n * miu (mod n)
+ var L = (BigInteger.ModPow(bBlock, _keyStruct.Lambda, _keyStruct.NSquare) - BigInteger.One) / _keyStruct.N;
+ var m = L * _keyStruct.Miu % _keyStruct.N;
return Decode(m);
}
private BigFraction Decode(BigInteger n)
{
- var a = new BigFraction(n, KeyStruct.PlaintextExp);
- a = a % (KeyStruct.MaxRawPlaintext + 1);
- if ( a > KeyStruct.MaxRawPlaintext / 2)
- a = a - KeyStruct.MaxRawPlaintext - 1;
+ var a = new BigFraction(n, PaillierKeyStruct.PlaintextExp);
+ a %= (PaillierKeyStruct.MaxRawPlaintext + 1);
+ if (a > PaillierKeyStruct.MaxEncryptableValue)
+ a = a - PaillierKeyStruct.MaxRawPlaintext - BigInteger.One;
return a;
}
}
diff --git a/src/Aprismatic.PaillierExt/PaillierEncryptor.cs b/src/Aprismatic.PaillierExt/PaillierEncryptor.cs
index 9a39ac6..95f3569 100644
--- a/src/Aprismatic.PaillierExt/PaillierEncryptor.cs
+++ b/src/Aprismatic.PaillierExt/PaillierEncryptor.cs
@@ -4,58 +4,90 @@
namespace Aprismatic.PaillierExt
{
- public class PaillierEncryptor : PaillierAbstractCipher, IDisposable
+ public class PaillierEncryptor : IDisposable
{
- private RandomNumberGenerator rng;
+ private readonly RandomNumberGenerator rng;
+ private readonly PaillierKeyStruct _keyStruct;
public PaillierEncryptor(PaillierKeyStruct keyStruct)
- : base(keyStruct)
{
rng = RandomNumberGenerator.Create();
+ _keyStruct = keyStruct;
}
- public byte[] ProcessBigInteger(BigFraction message)
+ public byte[] ProcessBigIntegerOld(BigFraction message)
{
- if (message.Denominator > KeyStruct.PlaintextExp)
+ if (message.Denominator > PaillierKeyStruct.PlaintextExp)
{
- BigInteger denominator = KeyStruct.PlaintextExp;
+ BigInteger denominator = PaillierKeyStruct.PlaintextExp;
BigInteger numerator = message.Numerator * denominator / message.Denominator;
message = new BigFraction(numerator, denominator);
}
- if (BigInteger.Abs(message.Numerator) > KeyStruct.MaxEncryptableValue)
- throw new ArgumentException($"Numerator to encrypt is too large. Message should be |m| < 2^{KeyStruct.getMaxPlaintextBits() - 1}");
+ if (BigInteger.Abs(message.Numerator) > PaillierKeyStruct.MaxEncryptableValue)
+ throw new ArgumentException($"Numerator to encrypt is too large. Message should be |m| < 2^{PaillierKeyStruct.MaxPlaintextBits - 1}");
// generate random R
var R = new BigInteger();
- R = R.GenRandomBits(KeyStruct.N.BitCount() - 1, rng); // R's bitlength is n-1 so that r is within Zn
+ R = R.GenRandomBits(_keyStruct.N.BitCount() - 1, rng); // R's bitlength is n-1 so that r is within Zn
// ciphertext c = g^m * r^n mod n^2
- var RN = BigInteger.ModPow(R, KeyStruct.N, KeyStruct.NSquare);
+ var RN = BigInteger.ModPow(R, _keyStruct.N, _keyStruct.NSquare);
// if we use simple key generation (g = n + 1), we can use
// (n+1)^m = n*m + 1 mod n^2
- var Gm = (KeyStruct.N * Encode(message) + 1) % KeyStruct.NSquare;
- var Gm_Neg = (KeyStruct.N * Encode(-message) + 1) % KeyStruct.NSquare;
+ var Gm = (_keyStruct.N * Encode(message) + 1) % _keyStruct.NSquare;
+ var Gm_Neg = (_keyStruct.N * Encode(-message) + 1) % _keyStruct.NSquare;
- var C = (Gm * RN) % KeyStruct.NSquare;
- var C_Neg = (Gm_Neg * RN) % KeyStruct.NSquare;
+ var C = (Gm * RN) % _keyStruct.NSquare;
+ var C_Neg = (Gm_Neg * RN) % _keyStruct.NSquare;
- var res = new byte[CiphertextBlocksize * 2];
+ var res = new byte[_keyStruct.CiphertextBlocksize * 2];
var c_bytes = C.ToByteArray();
var c_Neg_bytes = C_Neg.ToByteArray();
Array.Copy(c_bytes, 0, res, 0, c_bytes.Length);
- Array.Copy(c_Neg_bytes, 0, res, CiphertextBlocksize, c_Neg_bytes.Length);
+ Array.Copy(c_Neg_bytes, 0, res, _keyStruct.CiphertextBlocksize, c_Neg_bytes.Length);
return res;
}
+ public void ProcessBigInteger(BigFraction message, Span res)
+ {
+ if (message.Denominator > PaillierKeyStruct.PlaintextExp)
+ {
+ var denominator = PaillierKeyStruct.PlaintextExp;
+ var numerator = message.Numerator * denominator / message.Denominator;
+ message = new BigFraction(numerator, denominator);
+ }
+
+ if (BigInteger.Abs(message.Numerator) > PaillierKeyStruct.MaxEncryptableValue)
+ throw new ArgumentException($"Numerator to encrypt is too large. Message should be |m| < 2^{PaillierKeyStruct.MaxPlaintextBits - 1}");
+
+ // generate random R
+ var R = BigInteger.Zero.GenRandomBits(_keyStruct.NBitCount - 1, rng); // R's bitlength is n-1 so that r is within Zn
+
+ // ciphertext c = g^m * r^n mod n^2
+ var RN = BigInteger.ModPow(R, _keyStruct.N, _keyStruct.NSquare);
+
+ // if we use simple key generation (g = n + 1), we can use
+ // (n+1)^m = n*m + 1 mod n^2
+ var Gm = (_keyStruct.N * Encode(message) + 1) % _keyStruct.NSquare;
+ var Gm_Neg = (_keyStruct.N * Encode(-message) + 1) % _keyStruct.NSquare;
+
+ var C = (Gm * RN) % _keyStruct.NSquare;
+ var C_Neg = (Gm_Neg * RN) % _keyStruct.NSquare;
+
+ var lgth = res.Length >> 1;
+ C.TryWriteBytes(res.Slice(0, lgth), out _);
+ C_Neg.TryWriteBytes(res.Slice(lgth, lgth), out _);
+ }
+
private BigInteger Encode(BigFraction a)
{
if (a < 0)
- a = a + KeyStruct.MaxRawPlaintext + 1;
- a = a * KeyStruct.PlaintextExp;
+ a = a + PaillierKeyStruct.MaxRawPlaintext + BigInteger.One;
+ a *= PaillierKeyStruct.PlaintextExp;
return a.ToBigInteger();
}
diff --git a/src/Aprismatic.PaillierExt/PaillierKeyStruct.cs b/src/Aprismatic.PaillierExt/PaillierKeyStruct.cs
index bf92a19..c6bc759 100644
--- a/src/Aprismatic.PaillierExt/PaillierKeyStruct.cs
+++ b/src/Aprismatic.PaillierExt/PaillierKeyStruct.cs
@@ -4,85 +4,42 @@ namespace Aprismatic.PaillierExt
{
public struct PaillierKeyStruct
{
- private BigInteger _n;
+ public readonly BigInteger N;
+ public readonly BigInteger G;
+ public readonly BigInteger Lambda;
+ public readonly BigInteger Miu;
- public BigInteger N
+ public PaillierKeyStruct(BigInteger n, BigInteger g, BigInteger lambda, BigInteger miu)
{
- get => _n;
- set
- {
- _n = value;
- NSquare = _n * _n;
- }
- }
- public BigInteger NSquare { get; private set; }
-
- public BigInteger G;
- public BigInteger Lambda;
- public BigInteger Miu;
+ N = n;
+ NSquare = n * n;
+ NBitCount = n.BitCount();
+ NLength = (NBitCount + 7) >> 3; // div 8
+ NSquareLength = NLength * 2;
- private BigInteger _maxRawPT;
- public BigInteger MaxRawPlaintext
- {
- get
- {
- if (_maxRawPT == BigInteger.Zero)
- _maxRawPT = BigInteger.Pow(2, getMaxPlaintextBits()) - BigInteger.One;
- return _maxRawPT;
- }
- }
+ G = g;
- private BigInteger _maxRawPT_half;
- public BigInteger MaxEncryptableValue
- {
- get
- {
- if (_maxRawPT_half == BigInteger.Zero)
- _maxRawPT_half = MaxRawPlaintext / 2;
- return _maxRawPT_half;
- }
- }
+ Lambda = lambda;
+ Miu = miu;
- private BigInteger _PTExp;
- public BigInteger PlaintextExp
- {
- get
- {
- if (_PTExp == BigInteger.Zero)
- _PTExp = BigInteger.Pow(10, getPlaintextDecPlace());
- return _PTExp;
- }
+ CiphertextBlocksize = NLength * 2 + 2; // We add 2 because last bit of a BigInteger is reserved to store its sign.
+ CiphertextLength = CiphertextBlocksize * 2; // Therefore, theoretically, each part of ciphertext might need an extra byte to hold that one bit
}
- public int getMaxPlaintextBits()
- {
- return 128; // 128 bit
- }
+ public const int MaxPlaintextBits = 128;
+ public const int PlaintextDecPlace = 12; // 12 decimal places allowed in plain text
+ public static readonly BigInteger PlaintextExp = BigInteger.Pow(10, PlaintextDecPlace);
- public int getPlaintextDecPlace()
- {
- return 12; // 12 decimal places allowed in plain text
- }
+ public static readonly BigInteger MaxRawPlaintext = BigInteger.Pow(2, MaxPlaintextBits) - BigInteger.One;
+ public static readonly BigInteger MaxEncryptableValue = MaxRawPlaintext >> 1;
- public int getCiphertextBlocksize()
- {
- return getNLength() * 2 + 2;
- }
-
- public int getCiphertextLength()
- {
- return getCiphertextBlocksize() * 2;
- }
+ public readonly int NBitCount;
+ public readonly int NLength;
+ public readonly BigInteger NSquare;
+ public readonly int NSquareLength;
- public int getNLength()
- {
- return (_n.BitCount() + 7) / 8;
- }
-
- public int getNSquareLength()
- {
- return getNLength() * 2;
- }
+ public readonly int CiphertextBlocksize;
+ public readonly int CiphertextLength;
}
}
diff --git a/test/PaillierTests/EdgeCases.cs b/test/PaillierTests/EdgeCases.cs
index df8c14e..0631eb7 100644
--- a/test/PaillierTests/EdgeCases.cs
+++ b/test/PaillierTests/EdgeCases.cs
@@ -30,16 +30,10 @@ public void TestZero()
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
+ var algorithm = new Paillier(keySize);
- var encryptAlgorithm = new Paillier();
- encryptAlgorithm.FromXmlString(algorithm.ToXmlString(false));
-
- var decryptAlgorithm = new Paillier();
- decryptAlgorithm.FromXmlString(algorithm.ToXmlString(true));
+ var encryptAlgorithm = new Paillier(algorithm.ToXmlString(false));
+ var decryptAlgorithm = new Paillier(algorithm.ToXmlString(true));
var z = new BigInteger(0);
var r = new BigInteger(rnd.Next(1, 65536));
@@ -80,17 +74,10 @@ public void MinAndMaxValues()
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
-
- var encryptAlgorithm = new Paillier();
- encryptAlgorithm.FromXmlString(algorithm.ToXmlString(false));
-
- var decryptAlgorithm = new Paillier();
- decryptAlgorithm.FromXmlString(algorithm.ToXmlString(true));
+ var algorithm = new Paillier(keySize);
+ var encryptAlgorithm = new Paillier(algorithm.ToXmlString(false));
+ var decryptAlgorithm = new Paillier(algorithm.ToXmlString(true));
// MAX
var max_enc = encryptAlgorithm.EncryptData(max);
@@ -127,19 +114,13 @@ public void BigDenominator()
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
-
- var encryptAlgorithm = new Paillier();
- encryptAlgorithm.FromXmlString(algorithm.ToXmlString(false));
+ var algorithm = new Paillier(keySize);
- var decryptAlgorithm = new Paillier();
- decryptAlgorithm.FromXmlString(algorithm.ToXmlString(true));
+ var encryptAlgorithm = new Paillier(algorithm.ToXmlString(false));
+ var decryptAlgorithm = new Paillier(algorithm.ToXmlString(true));
var n = new BigInteger(10000);
- var d = algorithm.KeyStruct.PlaintextExp * 2;
+ var d = algorithm.PlaintextExp * 2;
var f = new BigFraction(n, d);
var f_enc = encryptAlgorithm.EncryptData(f);
diff --git a/test/PaillierTests/FpAddSub.cs b/test/PaillierTests/FpAddSub.cs
index a7bfce2..2756c15 100644
--- a/test/PaillierTests/FpAddSub.cs
+++ b/test/PaillierTests/FpAddSub.cs
@@ -35,29 +35,22 @@ public void TestMultiplication_BatchFrac()
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
-
- var encryptAlgorithm = new Paillier();
- encryptAlgorithm.FromXmlString(algorithm.ToXmlString(false));
-
- var decryptAlgorithm = new Paillier();
- decryptAlgorithm.FromXmlString(algorithm.ToXmlString(true));
+ var algorithm = new Paillier(keySize);
+ var encryptAlgorithm = new Paillier(algorithm.ToXmlString(false));
+ var decryptAlgorithm = new Paillier(algorithm.ToXmlString(true));
BigFraction a, b;
do
{
- var n = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.KeyStruct.getMaxPlaintextBits() / 4), rng);
- var d = new BigInteger(Math.Pow(10, (rnd.Next() % algorithm.KeyStruct.getPlaintextDecPlace()) + 1));
+ var n = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.MaxPlaintextBits() / 4), rng);
+ var d = new BigInteger(Math.Pow(10, (rnd.Next() % algorithm.GetPlaintextDecPlace()) + 1));
a = new BigFraction(n, d);
} while (a == 0);
do
{
- var n = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.KeyStruct.getMaxPlaintextBits() / 4), rng);
- var d = new BigInteger(Math.Pow(10, (rnd.Next() % algorithm.KeyStruct.getPlaintextDecPlace()) + 1));
+ var n = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.MaxPlaintextBits() / 4), rng);
+ var d = new BigInteger(Math.Pow(10, (rnd.Next() % algorithm.GetPlaintextDecPlace()) + 1));
b = new BigFraction(n, d);
} while (b == 0);
diff --git a/test/PaillierTests/FpEncDec.cs b/test/PaillierTests/FpEncDec.cs
index 605aaaa..6811472 100644
--- a/test/PaillierTests/FpEncDec.cs
+++ b/test/PaillierTests/FpEncDec.cs
@@ -32,19 +32,14 @@ public void TestRandomBigFraction()
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
+ var algorithm = new Paillier(keySize);
- var encryptAlgorithm = new Paillier();
- encryptAlgorithm.FromXmlString(algorithm.ToXmlString(false));
+ var encryptAlgorithm = new Paillier(algorithm.ToXmlString(false));
- var decryptAlgorithm = new Paillier();
- decryptAlgorithm.FromXmlString(algorithm.ToXmlString(true));
+ var decryptAlgorithm = new Paillier(algorithm.ToXmlString(true));
- var n = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.KeyStruct.getMaxPlaintextBits() - 1), rng);
- var d = new BigInteger(Math.Pow(10, (rnd.Next() % algorithm.KeyStruct.getPlaintextDecPlace()) + 1));
+ var n = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.MaxPlaintextBits() - 1), rng);
+ var d = new BigInteger(Math.Pow(10, (rnd.Next() % algorithm.GetPlaintextDecPlace()) + 1));
var f = new BigFraction(n, d);
if (rnd.Next() % 2 == 0) // random sign
f *= -1;
diff --git a/test/PaillierTests/IntAddSub.cs b/test/PaillierTests/IntAddSub.cs
index 49ac530..9c02adb 100644
--- a/test/PaillierTests/IntAddSub.cs
+++ b/test/PaillierTests/IntAddSub.cs
@@ -35,25 +35,19 @@ public void TestMultiplication_Batch()
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
-
- var encryptAlgorithm = new Paillier();
- encryptAlgorithm.FromXmlString(algorithm.ToXmlString(false));
+ var algorithm = new Paillier(keySize);
- var decryptAlgorithm = new Paillier();
- decryptAlgorithm.FromXmlString(algorithm.ToXmlString(true));
+ var encryptAlgorithm = new Paillier(algorithm.ToXmlString(false));
+ var decryptAlgorithm = new Paillier(algorithm.ToXmlString(true));
BigInteger a, b;
do
{
- a = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.KeyStruct.getMaxPlaintextBits() / 4), rng);
+ a = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.MaxPlaintextBits() / 4), rng);
} while (a == 0);
do
{
- b = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.KeyStruct.getMaxPlaintextBits() / 4), rng);
+ b = new BigInteger().GenRandomBits(rnd.Next(1, algorithm.MaxPlaintextBits() / 4), rng);
} while (b == 0);
if (rnd.Next() % 2 == 0) // randomly change signs
diff --git a/test/PaillierTests/IntEncDec.cs b/test/PaillierTests/IntEncDec.cs
index 4c3a8ce..8e04cea 100644
--- a/test/PaillierTests/IntEncDec.cs
+++ b/test/PaillierTests/IntEncDec.cs
@@ -32,20 +32,15 @@ public void TestRandomBigInteger()
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
+ var algorithm = new Paillier(keySize);
- var encryptAlgorithm = new Paillier();
- encryptAlgorithm.FromXmlString(algorithm.ToXmlString(false));
+ var encryptAlgorithm = new Paillier(algorithm.ToXmlString(false));
- var decryptAlgorithm = new Paillier();
- decryptAlgorithm.FromXmlString(algorithm.ToXmlString(true));
+ var decryptAlgorithm = new Paillier(algorithm.ToXmlString(true));
var z = new BigInteger();
- z = z.GenRandomBits(rnd.Next(1, algorithm.KeyStruct.getMaxPlaintextBits() - 1), rng);
+ z = z.GenRandomBits(rnd.Next(1, algorithm.MaxPlaintextBits() - 1), rng);
if (rnd.Next() % 2 == 0) // random sign
z = -z;
diff --git a/test/PaillierTests/KeyStruct.cs b/test/PaillierTests/KeyStruct.cs
index a8e043d..00a53c9 100644
--- a/test/PaillierTests/KeyStruct.cs
+++ b/test/PaillierTests/KeyStruct.cs
@@ -1,5 +1,7 @@
using System;
+using System.Numerics;
using System.Security.Cryptography;
+using Aprismatic;
using Aprismatic.PaillierExt;
using Xunit;
using Xunit.Abstractions;
@@ -26,19 +28,15 @@ public void Dispose()
[Fact(DisplayName = "Lengths")]
public void TestLengths()
{
- var rnd = new Random();
- var rng = new RNGCryptoServiceProvider();
-
for (var i = 0; i < Globals.iterations; i++)
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
+ var algorithm = new Paillier(keySize);
+ var prms = algorithm.ExportParameters(false);
+ var bi = new BigInteger(prms.N);
- Assert.Equal(algorithm.KeySize / 8, algorithm.KeyStruct.getNLength());
+ Assert.Equal(algorithm.KeySize / 8, (bi.BitCount() + 7) / 8);
algorithm.Dispose();
}
diff --git a/test/PaillierTests/PaillierTests.csproj b/test/PaillierTests/PaillierTests.csproj
index 273566c..57f339d 100644
--- a/test/PaillierTests/PaillierTests.csproj
+++ b/test/PaillierTests/PaillierTests.csproj
@@ -4,7 +4,7 @@
false
-
+
all
diff --git a/test/PaillierTests/SimpleFastTests.cs b/test/PaillierTests/SimpleFastTests.cs
index 94a345d..ff0ad78 100644
--- a/test/PaillierTests/SimpleFastTests.cs
+++ b/test/PaillierTests/SimpleFastTests.cs
@@ -29,10 +29,7 @@ public void Dispose()
public void TestSpecificCases()
{
{
- var algorithm = new Paillier
- {
- KeySize = 384
- };
+ var algorithm = new Paillier(384);
var z = new BigFraction(BigInteger.Parse("1000"), BigInteger.Parse("1"));
@@ -48,10 +45,7 @@ public void TestSpecificCases()
// based on https://github.com/bazzilic/PaillierExt/issues/15
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
+ var algorithm = new Paillier(keySize);
var sum = algorithm.EncryptData(new BigInteger(0));
var one = algorithm.EncryptData(new BigInteger(1));
@@ -72,10 +66,7 @@ public void TestSpecificCases()
{
for (var keySize = 384; keySize <= 1088; keySize += 8)
{
- var algorithm = new Paillier
- {
- KeySize = keySize
- };
+ var algorithm = new Paillier(keySize);
var a = 123;
var b = 234;
@@ -117,10 +108,7 @@ public void TestSpecificCases()
public void TestNegativeCases()
{
{
- var algorithm = new Paillier
- {
- KeySize = 384
- };
+ var algorithm = new Paillier(384);
//Test negative number
var z = new BigInteger(8);
@@ -152,10 +140,7 @@ public void TestNegativeCases()
public void TestFloatingPoint()
{
{
- var algorithm = new Paillier
- {
- KeySize = 384
- };
+ var algorithm = new Paillier(384);
//Test 1 decimal place
var z = new BigFraction(BigInteger.Parse("1"), BigInteger.Parse("10"));
@@ -188,10 +173,7 @@ public void TestFloatingPoint()
public void TestNegativeFloatingPoint()
{
{
- var algorithm = new Paillier
- {
- KeySize = 384
- };
+ var algorithm = new Paillier(384);
//Test 0 > plaintext > -1
var z = new BigFraction(BigInteger.Parse("-1001"), BigInteger.Parse("100"));