public void KeyCopyTest() { { SEALContext context = GlobalContext.BFVContext; PublicKey pk; SecretKey sk = null; using (KeyGenerator keygen = new KeyGenerator(context)) { keygen.CreatePublicKey(out pk); sk = keygen.SecretKey; } ParmsId parmsIdPK = pk.ParmsId; ParmsId parmsIdSK = sk.ParmsId; Assert.AreEqual(parmsIdPK, parmsIdSK); Assert.AreEqual(parmsIdPK, context.KeyParmsId); } { SEALContext context = GlobalContext.BGVContext; PublicKey pk; SecretKey sk = null; using (KeyGenerator keygen = new KeyGenerator(context)) { keygen.CreatePublicKey(out pk); sk = keygen.SecretKey; } ParmsId parmsIdPK = pk.ParmsId; ParmsId parmsIdSK = sk.ParmsId; Assert.AreEqual(parmsIdPK, parmsIdSK); Assert.AreEqual(parmsIdPK, context.KeyParmsId); } }
public void ParamIDConstructorTest() { ParmsId id = new ParmsId(); Assert.AreEqual(0ul, id.Block[0]); Assert.AreEqual(0ul, id.Block[1]); Assert.AreEqual(0ul, id.Block[2]); Assert.AreEqual(0ul, id.Block[3]); id.Block[0] = 5; id.Block[1] = 4; id.Block[2] = 3; id.Block[3] = 2; ParmsId id2 = new ParmsId(id); id.Block[1] = 7; Assert.AreEqual(5ul, id2.Block[0]); Assert.AreEqual(4ul, id2.Block[1]); Assert.AreEqual(3ul, id2.Block[2]); Assert.AreEqual(2ul, id2.Block[3]); Assert.AreEqual(7ul, id.Block[1]); Assert.IsFalse(id2.Equals(null)); Assert.AreNotEqual(id.GetHashCode(), id2.GetHashCode()); }
public void ExceptionsTest() { ParmsId id = new ParmsId(); ParmsId id_null = null; Utilities.AssertThrows <ArgumentNullException>(() => id = new ParmsId(id_null)); }
public void ExceptionsTest() { ParmsId id = new ParmsId(); ParmsId id_null = null; Assert.ThrowsException <ArgumentNullException>(() => id = new ParmsId(id_null)); Assert.ThrowsException <ArgumentNullException>(() => id.Load(null)); Assert.ThrowsException <ArgumentNullException>(() => id.Save(null)); }
public void ToStringTest() { ParmsId id = new ParmsId(); id.Block[0] = 1; id.Block[1] = 2; id.Block[2] = 3; id.Block[3] = 4; Assert.AreEqual("0000000000000001 0000000000000002 0000000000000003 0000000000000004", id.ToString()); }
public void Create3Test() { SEALContext context = GlobalContext.BFVContext; ParmsId parms = context.FirstParmsId; Assert.AreNotEqual(0ul, parms.Block[0]); Assert.AreNotEqual(0ul, parms.Block[1]); Assert.AreNotEqual(0ul, parms.Block[2]); Assert.AreNotEqual(0ul, parms.Block[3]); Ciphertext cipher = new Ciphertext(context, parms, sizeCapacity: 5); Assert.AreEqual(5ul, cipher.SizeCapacity); }
public void Create2Test() { SEALContext context = GlobalContext.BFVContext; ParmsId parms = context.FirstParmsId; Assert.AreNotEqual(0ul, parms.Block[0]); Assert.AreNotEqual(0ul, parms.Block[1]); Assert.AreNotEqual(0ul, parms.Block[2]); Assert.AreNotEqual(0ul, parms.Block[3]); Ciphertext cipher = new Ciphertext(context, parms); Assert.AreEqual(parms, cipher.ParmsId); }
public void ExceptionsTest() { SEALContext context = GlobalContext.BFVContext; KeyGenerator keygen = new KeyGenerator(context); PublicKey pubKey = keygen.PublicKey; PublicKey pubKey_invalid = new PublicKey(); SecretKey secKey = keygen.SecretKey; SecretKey secKey_invalid = new SecretKey(); Encryptor encryptor = new Encryptor(context, pubKey); Plaintext plain = new Plaintext(); Ciphertext cipher = new Ciphertext(); MemoryPoolHandle pool_invalid = new MemoryPoolHandle(); ParmsId parmsId_invalid = new ParmsId(); Utilities.AssertThrows <ArgumentNullException>(() => encryptor = new Encryptor(context, null)); Utilities.AssertThrows <ArgumentNullException>(() => encryptor = new Encryptor(null, pubKey)); Utilities.AssertThrows <ArgumentException>(() => encryptor = new Encryptor(context, pubKey_invalid)); Utilities.AssertThrows <ArgumentException>(() => encryptor = new Encryptor(context, pubKey_invalid, secKey)); encryptor = new Encryptor(context, pubKey, secKey); Utilities.AssertThrows <ArgumentException>(() => encryptor.SetPublicKey(pubKey_invalid)); Utilities.AssertThrows <ArgumentException>(() => encryptor.SetSecretKey(secKey_invalid)); Utilities.AssertThrows <ArgumentNullException>(() => encryptor.Encrypt(plain, null)); Utilities.AssertThrows <ArgumentNullException>(() => encryptor.Encrypt(null, cipher)); Utilities.AssertThrows <ArgumentException>(() => encryptor.Encrypt(plain, cipher, pool_invalid)); Utilities.AssertThrows <ArgumentException>(() => encryptor.EncryptZero(cipher, pool_invalid)); Utilities.AssertThrows <ArgumentException>(() => encryptor.EncryptZero(parmsId_invalid, cipher)); Utilities.AssertThrows <ArgumentNullException>(() => encryptor.EncryptSymmetric(plain, null)); Utilities.AssertThrows <ArgumentNullException>(() => encryptor.EncryptSymmetric(null, cipher)); Utilities.AssertThrows <ArgumentException>(() => encryptor.EncryptSymmetric(plain, cipher, pool_invalid)); Utilities.AssertThrows <ArgumentException>(() => encryptor.EncryptZeroSymmetric(cipher, pool_invalid)); Utilities.AssertThrows <ArgumentException>(() => encryptor.EncryptZeroSymmetric(parmsId_invalid, cipher)); Utilities.AssertThrows <ArgumentNullException>(() => encryptor.EncryptSymmetricSave(plain, null)); Utilities.AssertThrows <ArgumentNullException>(() => encryptor.EncryptZeroSymmetricSave(null)); Utilities.AssertThrows <ArgumentException>(() => encryptor.EncryptZeroSymmetricSave(parmsId_invalid, null)); }
public void ResizeTest() { SEALContext context = GlobalContext.Context; ParmsId parms = context.FirstParmsId; Ciphertext cipher = new Ciphertext(context, parms); Assert.AreEqual(2ul, cipher.SizeCapacity); Assert.AreEqual(16384ul, cipher.UInt64CountCapacity); cipher.Reserve(context, parms, sizeCapacity: 10); Assert.AreEqual(10ul, cipher.SizeCapacity); Assert.AreEqual(16384ul * 5, cipher.UInt64CountCapacity); Ciphertext cipher2 = new Ciphertext(); Assert.AreEqual(2ul, cipher2.SizeCapacity); cipher2.Reserve(context, 5); Assert.AreEqual(5ul, cipher2.SizeCapacity); Ciphertext cipher3 = new Ciphertext(); Assert.AreEqual(2ul, cipher3.SizeCapacity); cipher3.Reserve(4); Assert.AreEqual(4ul, cipher3.SizeCapacity); Ciphertext cipher4 = new Ciphertext(context); cipher4.Resize(context, context.GetContextData(context.FirstParmsId).NextContextData.Parms.ParmsId, 4); Assert.AreEqual(10ul, cipher.SizeCapacity); Ciphertext cipher5 = new Ciphertext(context); cipher5.Resize(context, 6ul); Assert.AreEqual(2ul, cipher5.SizeCapacity); }
public void OperatorsTest() { ParmsId id = new ParmsId(); id.Block[0] = 1; id.Block[1] = 2; id.Block[2] = 3; id.Block[3] = 4; ParmsId id2 = new ParmsId(id); ParmsId id3 = new ParmsId(id); id3.Block[0] = 2; Assert.IsTrue(id == id2); Assert.IsFalse(id == id3); ParmsId id_null1 = null; ParmsId id_null2 = null; Assert.IsFalse(id_null1 != id_null2); Assert.IsTrue(id_null1 != id); }
private static void ExampleCKKSBasics() { Utilities.PrintExampleBanner("Example: CKKS Basics"); /* * In this example we demonstrate evaluating a polynomial function * * PI*x^3 + 0.4*x + 1 * * on encrypted floating-point input data x for a set of 4096 equidistant points * in the interval [0, 1]. This example demonstrates many of the main features * of the CKKS scheme, but also the challenges in using it. * * We start by setting up the CKKS scheme. */ using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS); /* * We saw in `2_Encoders.cs' that multiplication in CKKS causes scales in * ciphertexts to grow. The scale of any ciphertext must not get too close to * the total size of CoeffModulus, or else the ciphertext simply runs out of * room to store the scaled-up plaintext. The CKKS scheme provides a `rescale' * functionality that can reduce the scale, and stabilize the scale expansion. * * Rescaling is a kind of modulus switch operation (recall `3_Levels.cs'). * As modulus switching, it removes the last of the primes from CoeffModulus, * but as a side-effect it scales down the ciphertext by the removed prime. * Usually we want to have perfect control over how the scales are changed, * which is why for the CKKS scheme it is more common to use carefully selected * primes for the CoeffModulus. * * More precisely, suppose that the scale in a CKKS ciphertext is S, and the * last prime in the current CoeffModulus (for the ciphertext) is P. Rescaling * to the next level changes the scale to S/P, and removes the prime P from the * CoeffModulus, as usual in modulus switching. The number of primes limits * how many rescalings can be done, and thus limits the multiplicative depth of * the computation. * * It is possible to choose the initial scale freely. One good strategy can be * to is to set the initial scale S and primes P_i in the CoeffModulus to be * very close to each other. If ciphertexts have scale S before multiplication, * they have scale S^2 after multiplication, and S^2/P_i after rescaling. If all * P_i are close to S, then S^2/P_i is close to S again. This way we stabilize the * scales to be close to S throughout the computation. Generally, for a circuit * of depth D, we need to rescale D times, i.e., we need to be able to remove D * primes from the coefficient modulus. Once we have only one prime left in the * coeff_modulus, the remaining prime must be larger than S by a few bits to * preserve the pre-decimal-point value of the plaintext. * * Therefore, a generally good strategy is to choose parameters for the CKKS * scheme as follows: * * (1) Choose a 60-bit prime as the first prime in CoeffModulus. This will * give the highest precision when decrypting; * (2) Choose another 60-bit prime as the last element of CoeffModulus, as * this will be used as the special prime and should be as large as the * largest of the other primes; * (3) Choose the intermediate primes to be close to each other. * * We use CoeffModulus.Create to generate primes of the appropriate size. Note * that our CoeffModulus is 200 bits total, which is below the bound for our * PolyModulusDegree: CoeffModulus.MaxBitCount(8192) returns 218. */ ulong polyModulusDegree = 8192; parms.PolyModulusDegree = polyModulusDegree; parms.CoeffModulus = CoeffModulus.Create( polyModulusDegree, new int[] { 60, 40, 40, 60 }); /* * We choose the initial scale to be 2^40. At the last level, this leaves us * 60-40=20 bits of precision before the decimal point, and enough (roughly * 10-20 bits) of precision after the decimal point. Since our intermediate * primes are 40 bits (in fact, they are very close to 2^40), we can achieve * scale stabilization as described above. */ double scale = Math.Pow(2.0, 40); using SEALContext context = new SEALContext(parms); Utilities.PrintParameters(context); Console.WriteLine(); using KeyGenerator keygen = new KeyGenerator(context); using PublicKey publicKey = keygen.PublicKey; using SecretKey secretKey = keygen.SecretKey; using RelinKeys relinKeys = keygen.RelinKeysLocal(); using Encryptor encryptor = new Encryptor(context, publicKey); using Evaluator evaluator = new Evaluator(context); using Decryptor decryptor = new Decryptor(context, secretKey); using CKKSEncoder encoder = new CKKSEncoder(context); ulong slotCount = encoder.SlotCount; Console.WriteLine($"Number of slots: {slotCount}"); List <double> input = new List <double>((int)slotCount); double currPoint = 0, stepSize = 1.0 / (slotCount - 1); for (ulong i = 0; i < slotCount; i++, currPoint += stepSize) { input.Add(currPoint); } Console.WriteLine("Input vector:"); Utilities.PrintVector(input, 3, 7); Console.WriteLine("Evaluating polynomial PI*x^3 + 0.4x + 1 ..."); /* * We create plaintexts for PI, 0.4, and 1 using an overload of CKKSEncoder.Encode * that encodes the given floating-point value to every slot in the vector. */ using Plaintext plainCoeff3 = new Plaintext(), plainCoeff1 = new Plaintext(), plainCoeff0 = new Plaintext(); encoder.Encode(3.14159265, scale, plainCoeff3); encoder.Encode(0.4, scale, plainCoeff1); encoder.Encode(1.0, scale, plainCoeff0); using Plaintext xPlain = new Plaintext(); Utilities.PrintLine(); Console.WriteLine("Encode input vectors."); encoder.Encode(input, scale, xPlain); using Ciphertext x1Encrypted = new Ciphertext(); encryptor.Encrypt(xPlain, x1Encrypted); /* * To compute x^3 we first compute x^2 and relinearize. However, the scale has * now grown to 2^80. */ using Ciphertext x3Encrypted = new Ciphertext(); Utilities.PrintLine(); Console.WriteLine("Compute x^2 and relinearize:"); evaluator.Square(x1Encrypted, x3Encrypted); evaluator.RelinearizeInplace(x3Encrypted, relinKeys); Console.WriteLine(" + Scale of x^2 before rescale: {0} bits", Math.Log(x3Encrypted.Scale, newBase: 2)); /* * Now rescale; in addition to a modulus switch, the scale is reduced down by * a factor equal to the prime that was switched away (40-bit prime). Hence, the * new scale should be close to 2^40. Note, however, that the scale is not equal * to 2^40: this is because the 40-bit prime is only close to 2^40. */ Utilities.PrintLine(); Console.WriteLine("Rescale x^2."); evaluator.RescaleToNextInplace(x3Encrypted); Console.WriteLine(" + Scale of x^2 after rescale: {0} bits", Math.Log(x3Encrypted.Scale, newBase: 2)); /* * Now x3Encrypted is at a different level than x1Encrypted, which prevents us * from multiplying them to compute x^3. We could simply switch x1Encrypted to * the next parameters in the modulus switching chain. However, since we still * need to multiply the x^3 term with PI (plainCoeff3), we instead compute PI*x * first and multiply that with x^2 to obtain PI*x^3. To this end, we compute * PI*x and rescale it back from scale 2^80 to something close to 2^40. */ Utilities.PrintLine(); Console.WriteLine("Compute and rescale PI*x."); using Ciphertext x1EncryptedCoeff3 = new Ciphertext(); evaluator.MultiplyPlain(x1Encrypted, plainCoeff3, x1EncryptedCoeff3); Console.WriteLine(" + Scale of PI*x before rescale: {0} bits", Math.Log(x1EncryptedCoeff3.Scale, newBase: 2)); evaluator.RescaleToNextInplace(x1EncryptedCoeff3); Console.WriteLine(" + Scale of PI*x after rescale: {0} bits", Math.Log(x1EncryptedCoeff3.Scale, newBase: 2)); /* * Since x3Encrypted and x1EncryptedCoeff3 have the same exact scale and use * the same encryption parameters, we can multiply them together. We write the * result to x3Encrypted, relinearize, and rescale. Note that again the scale * is something close to 2^40, but not exactly 2^40 due to yet another scaling * by a prime. We are down to the last level in the modulus switching chain. */ Utilities.PrintLine(); Console.WriteLine("Compute, relinearize, and rescale (PI*x)*x^2."); evaluator.MultiplyInplace(x3Encrypted, x1EncryptedCoeff3); evaluator.RelinearizeInplace(x3Encrypted, relinKeys); Console.WriteLine(" + Scale of PI*x^3 before rescale: {0} bits", Math.Log(x3Encrypted.Scale, newBase: 2)); evaluator.RescaleToNextInplace(x3Encrypted); Console.WriteLine(" + Scale of PI*x^3 after rescale: {0} bits", Math.Log(x3Encrypted.Scale, newBase: 2)); /* * Next we compute the degree one term. All this requires is one MultiplyPlain * with plainCoeff1. We overwrite x1Encrypted with the result. */ Utilities.PrintLine(); Console.WriteLine("Compute and rescale 0.4*x."); evaluator.MultiplyPlainInplace(x1Encrypted, plainCoeff1); Console.WriteLine(" + Scale of 0.4*x before rescale: {0} bits", Math.Log(x1Encrypted.Scale, newBase: 2)); evaluator.RescaleToNextInplace(x1Encrypted); Console.WriteLine(" + Scale of 0.4*x after rescale: {0} bits", Math.Log(x1Encrypted.Scale, newBase: 2)); /* * Now we would hope to compute the sum of all three terms. However, there is * a serious problem: the encryption parameters used by all three terms are * different due to modulus switching from rescaling. * * Encrypted addition and subtraction require that the scales of the inputs are * the same, and also that the encryption parameters (ParmsId) match. If there * is a mismatch, Evaluator will throw an exception. */ Console.WriteLine(); Utilities.PrintLine(); Console.WriteLine("Parameters used by all three terms are different:"); Console.WriteLine(" + Modulus chain index for x3Encrypted: {0}", context.GetContextData(x3Encrypted.ParmsId).ChainIndex); Console.WriteLine(" + Modulus chain index for x1Encrypted: {0}", context.GetContextData(x1Encrypted.ParmsId).ChainIndex); Console.WriteLine(" + Modulus chain index for plainCoeff0: {0}", context.GetContextData(plainCoeff0.ParmsId).ChainIndex); Console.WriteLine(); /* * Let us carefully consider what the scales are at this point. We denote the * primes in coeff_modulus as P_0, P_1, P_2, P_3, in this order. P_3 is used as * the special modulus and is not involved in rescalings. After the computations * above the scales in ciphertexts are: * * - Product x^2 has scale 2^80 and is at level 2; * - Product PI*x has scale 2^80 and is at level 2; * - We rescaled both down to scale 2^80/P2 and level 1; * - Product PI*x^3 has scale (2^80/P_2)^2; * - We rescaled it down to scale (2^80/P_2)^2/P_1 and level 0; * - Product 0.4*x has scale 2^80; * - We rescaled it down to scale 2^80/P_2 and level 1; * - The contant term 1 has scale 2^40 and is at level 2. * * Although the scales of all three terms are approximately 2^40, their exact * values are different, hence they cannot be added together. */ Utilities.PrintLine(); Console.WriteLine("The exact scales of all three terms are different:"); Console.WriteLine(" + Exact scale in PI*x^3: {0:0.0000000000}", x3Encrypted.Scale); Console.WriteLine(" + Exact scale in 0.4*x: {0:0.0000000000}", x1Encrypted.Scale); Console.WriteLine(" + Exact scale in 1: {0:0.0000000000}", plainCoeff0.Scale); Console.WriteLine(); /* * There are many ways to fix this problem. Since P_2 and P_1 are really close * to 2^40, we can simply "lie" to Microsoft SEAL and set the scales to be the * same. For example, changing the scale of PI*x^3 to 2^40 simply means that we * scale the value of PI*x^3 by 2^120/(P_2^2*P_1), which is very close to 1. * This should not result in any noticeable error. * * Another option would be to encode 1 with scale 2^80/P_2, do a MultiplyPlain * with 0.4*x, and finally rescale. In this case we would need to additionally * make sure to encode 1 with appropriate encryption parameters (ParmsId). * * In this example we will use the first (simplest) approach and simply change * the scale of PI*x^3 and 0.4*x to 2^40. */ Utilities.PrintLine(); Console.WriteLine("Normalize scales to 2^40."); x3Encrypted.Scale = Math.Pow(2.0, 40); x1Encrypted.Scale = Math.Pow(2.0, 40); /* * We still have a problem with mismatching encryption parameters. This is easy * to fix by using traditional modulus switching (no rescaling). CKKS supports * modulus switching just like the BFV scheme, allowing us to switch away parts * of the coefficient modulus when it is simply not needed. */ Utilities.PrintLine(); Console.WriteLine("Normalize encryption parameters to the lowest level."); ParmsId lastParmsId = x3Encrypted.ParmsId; evaluator.ModSwitchToInplace(x1Encrypted, lastParmsId); evaluator.ModSwitchToInplace(plainCoeff0, lastParmsId); /* * All three ciphertexts are now compatible and can be added. */ Utilities.PrintLine(); Console.WriteLine("Compute PI*x^3 + 0.4*x + 1."); using Ciphertext encryptedResult = new Ciphertext(); evaluator.Add(x3Encrypted, x1Encrypted, encryptedResult); evaluator.AddPlainInplace(encryptedResult, plainCoeff0); /* * First print the true result. */ using Plaintext plainResult = new Plaintext(); Utilities.PrintLine(); Console.WriteLine("Decrypt and decode PI * x ^ 3 + 0.4x + 1."); Console.WriteLine(" + Expected result:"); List <double> trueResult = new List <double>(input.Count); foreach (double x in input) { trueResult.Add((3.14159265 * x * x + 0.4) * x + 1); } Utilities.PrintVector(trueResult, 3, 7); /* * We decrypt, decode, and print the result. */ decryptor.Decrypt(encryptedResult, plainResult); List <double> result = new List <double>(); encoder.Decode(plainResult, result); Console.WriteLine(" + Computed result ...... Correct."); Utilities.PrintVector(result, 3, 7); /* * While we did not show any computations on complex numbers in these examples, * the CKKSEncoder would allow us to have done that just as easily. Additions * and multiplications of complex numbers behave just as one would expect. */ }
// Function for classification of samples // I follow the SEAL eamples recomandations to rescale and relinearize after each calculation. // useRelinearizeInplace and useReScale should be always true. // This parametrs are enabled only for debugging and learning purpose. public Ciphertext Predict(Ciphertext featuresCiphertexts, bool useRelinearizeInplace, bool useReScale, Stopwatch innerProductStopwatch, Stopwatch degreeStopwatch, Stopwatch negateStopwatch, Stopwatch serverDecisionStopWatch) { Ciphertext tempCt = new Ciphertext(); // Level 1 for (int i = 0; i < _numOfrowsCount; i++) { //inner product //calculate IP = < x, x'> innerProductStopwatch.Start(); if (UseBatchInnerProduct) { _kernels[i] = InnerProduct(featuresCiphertexts, _svPlaintexts, i, _sums, _numOfcolumnsCount, tempCt); } innerProductStopwatch.Stop(); SvcUtilities.PrintCyprherText(_decryptor, _kernels[i], _encoder, $"inner product TotalValue {i}"); SvcUtilities.PrintScale(_kernels[i], "0. kernels" + i); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(_kernels[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(_kernels[i]); } SvcUtilities.PrintScale(_kernels[i], "1. kernels" + i); _kernels[i].Scale = _scale; //For polynimial kernel calculate if (_kernel == Kernel.Poly) { // calculate (y *IP+r)^d // IP is calculated previously // y = gamma // r = _coef0 if (useReScale) { ParmsId lastParmsId = _kernels[i].ParmsId; _evaluator.ModSwitchToInplace(_gamaPlaintext, lastParmsId); } //calculate y * IP _evaluator.MultiplyPlainInplace(_kernels[i], _gamaPlaintext); SvcUtilities.PrintScale(_kernels[i], "2. kernels" + i); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(_kernels[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(_kernels[i]); } SvcUtilities.PrintScale(_kernels[i], "3. kernels" + i); // add r if (Math.Abs(_coef0) > 0) { Plaintext coef0Plaintext = new Plaintext(); _encoder.Encode(_coef0, _kernels[i].Scale, coef0Plaintext); if (useReScale) { ParmsId lastParmsId = _kernels[i].ParmsId; _evaluator.ModSwitchToInplace(coef0Plaintext, lastParmsId); } //kernels[i].Scale = coef0Plaintext.Scale; _evaluator.AddPlainInplace(_kernels[i], coef0Plaintext); } SvcUtilities.PrintScale(_kernels[i], "4. kernels" + i); degreeStopwatch.Start(); // calculate the polynom degree var kernel = new Ciphertext(_kernels[i]); for (int d = 0; d < (int)_degree - 1; d++) { kernel.Scale = _kernels[i].Scale; if (useReScale) { ParmsId lastParmsId = _kernels[i].ParmsId; _evaluator.ModSwitchToInplace(kernel, lastParmsId); } _evaluator.MultiplyInplace(_kernels[i], kernel); SvcUtilities.PrintScale(_kernels[i], d + " 5. kernels" + i); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(_kernels[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(_kernels[i]); } SvcUtilities.PrintScale(_kernels[i], d + " rescale 6. kernels" + i); } SvcUtilities.PrintScale(_kernels[i], "7. kernels" + i); degreeStopwatch.Stop(); } negateStopwatch.Start(); _evaluator.NegateInplace(_kernels[i]); negateStopwatch.Stop(); SvcUtilities.PrintScale(_kernels[i], "8. kernel" + i); SvcUtilities.PrintCyprherText(_decryptor, _kernels[i], _encoder, "kernel" + i); } serverDecisionStopWatch.Start(); // Encode coefficients : ParmsId! , scale! double scale2 = Math.Pow(2.0, _power); if (useReScale) { scale2 = _kernels[0].Scale; } for (int i = 0; i < _numOfrowsCount; i++) { _encoder.Encode(_coefficients[0][i], scale2, _coefArr[i]); SvcUtilities.PrintScale(_coefArr[i], "coefPlainText" + i); } if (useReScale) { for (int i = 0; i < _numOfrowsCount; i++) { ParmsId lastParmsId = _kernels[i].ParmsId; _evaluator.ModSwitchToInplace(_coefArr[i], lastParmsId); } } // Level 2 // Calculate decisionArr for (int i = 0; i < _numOfrowsCount; i++) { _evaluator.MultiplyPlain(_kernels[i], _coefArr[i], _decisionsArr[i]); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(_decisionsArr[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(_decisionsArr[i]); } SvcUtilities.PrintScale(_decisionsArr[i], "decision" + i); SvcUtilities.PrintCyprherText(_decryptor, _decisionsArr[i], _encoder, "decision" + i); } // Calculate decisionTotal Ciphertext decisionTotal = new Ciphertext(); //================================================================= _evaluator.AddMany(_decisionsArr, decisionTotal); //================================================================= SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); SvcUtilities.PrintCyprherText(_decryptor, decisionTotal, _encoder, "decision total"); // Encode intercepts : ParmsId! , scale! Plaintext interceptsPlainText = new Plaintext(); double scale3 = Math.Pow(2.0, _power * 3); if (useReScale) { scale3 = decisionTotal.Scale; } _encoder.Encode(_intercepts[0], scale3, interceptsPlainText); if (useReScale) { ParmsId lastParmsId = decisionTotal.ParmsId; _evaluator.ModSwitchToInplace(interceptsPlainText, lastParmsId); } SvcUtilities.PrintScale(interceptsPlainText, "interceptsPlainText"); SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //// Calculate finalTotal Ciphertext finalTotal = new Ciphertext(); //================================================================= _evaluator.AddPlainInplace(decisionTotal, interceptsPlainText); //================================================================= SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //Level 3 List <double> result = SvcUtilities.PrintCyprherText(_decryptor, decisionTotal, _encoder, "finalTotal", true); serverDecisionStopWatch.Stop(); long innerProductMilliseconds = innerProductStopwatch.ElapsedMilliseconds; //Console.WriteLine($"server innerProductStopwatch elapsed {innerProductMilliseconds} ms"); long negateMilliseconds = negateStopwatch.ElapsedMilliseconds; //Console.WriteLine($"server negateStopwatch elapsed {negateMilliseconds} ms"); long degreeMilliseconds = degreeStopwatch.ElapsedMilliseconds; //Console.WriteLine($"server degreeStopwatch elapsed {degreeMilliseconds} ms"); long serverDecisionMilliseconds = serverDecisionStopWatch.ElapsedMilliseconds; //Console.WriteLine($"server Decision elapsed {serverDecisionMilliseconds} ms"); return(decisionTotal); }
public int Predict(double[] features, int power, bool useRelinearizeInplace, bool useReScale, Stopwatch timePredictSum) { EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS); if (power < 60) { ulong polyModulusDegree = 8192; parms.PolyModulusDegree = polyModulusDegree; parms.CoeffModulus = CoeffModulus.Create(polyModulusDegree, new int[] { 60, 40, 40, 60 }); } else { ulong polyModulusDegree = 16384; parms.PolyModulusDegree = polyModulusDegree; parms.CoeffModulus = CoeffModulus.Create(polyModulusDegree, new int[] { 60, 60, 60, 60, 60, 60 }); } // double scale = Math.Pow(2.0, power); SEALContext context = new SEALContext(parms); Console.WriteLine(); KeyGenerator keygen = new KeyGenerator(context); PublicKey publicKey = keygen.PublicKey; SecretKey secretKey = keygen.SecretKey; RelinKeys relinKeys = keygen.RelinKeys(); Encryptor encryptor = new Encryptor(context, publicKey); Evaluator evaluator = new Evaluator(context); Decryptor decryptor = new Decryptor(context, secretKey); CKKSEncoder encoder = new CKKSEncoder(context); ulong slotCount = encoder.SlotCount; Console.WriteLine($"Number of slots: {slotCount}"); timePredictSum.Start(); var featuresLength = features.Length; var plaintexts = new Plaintext[featuresLength]; var featuresCiphertexts = new Ciphertext[featuresLength]; //Encode and encrypt features for (int i = 0; i < featuresLength; i++) { plaintexts[i] = new Plaintext(); encoder.Encode(features[i], scale, plaintexts[i]); SvcUtilities.PrintScale(plaintexts[i], "featurePlaintext" + i); featuresCiphertexts[i] = new Ciphertext(); encryptor.Encrypt(plaintexts[i], featuresCiphertexts[i]); SvcUtilities.PrintScale(featuresCiphertexts[i], "featurefEncrypted" + i); } // Handle SV var numOfrows = _vectors.Length; var numOfcolumns = _vectors[0].Length; var svPlaintexts = new Plaintext[numOfrows, numOfcolumns]; //Encode SV for (int i = 0; i < numOfrows; i++) { for (int j = 0; j < numOfcolumns; j++) { svPlaintexts[i, j] = new Plaintext(); encoder.Encode(_vectors[i][j], scale, svPlaintexts[i, j]); SvcUtilities.PrintScale(svPlaintexts[i, j], "supportVectorsPlaintext" + i + j); } } // Prepare sum of inner product var sums = new Ciphertext[numOfcolumns]; for (int i = 0; i < numOfcolumns; i++) { sums[i] = new Ciphertext(); } var kernels = new Ciphertext[numOfrows]; var decisionsArr = new Ciphertext[numOfrows]; var coefArr = new Plaintext [numOfrows]; for (int i = 0; i < numOfrows; i++) { kernels[i] = new Ciphertext(); decisionsArr[i] = new Ciphertext(); coefArr[i] = new Plaintext(); } // Level 1 for (int i = 0; i < numOfrows; i++) { var ciphertexts = new List <Ciphertext>(); //inner product for (int j = 0; j < numOfcolumns; j++) { evaluator.MultiplyPlain(featuresCiphertexts[j], svPlaintexts[i, j], sums[j]); if (useRelinearizeInplace) { evaluator.RelinearizeInplace(sums[j], relinKeys); } if (useReScale) { evaluator.RescaleToNextInplace(sums[j]); } SvcUtilities.PrintScale(sums[j], "tSum" + j); } evaluator.AddMany(sums, kernels[i]); evaluator.NegateInplace(kernels[i]); SvcUtilities.PrintScale(kernels[i], "kernel" + i); SvcUtilities.PrintCyprherText(decryptor, kernels[i], encoder, "kernel" + i); } // Encode coefficients : ParmsId! , scale! double scale2 = Math.Pow(2.0, power); if (useReScale) { scale2 = kernels[0].Scale; } for (int i = 0; i < numOfrows; i++) { encoder.Encode(_coefficients[0][i], scale2, coefArr[i]); SvcUtilities.PrintScale(coefArr[i], "coefPlainText+i"); } if (useReScale) { for (int i = 0; i < numOfrows; i++) { ParmsId lastParmsId = kernels[i].ParmsId; evaluator.ModSwitchToInplace(coefArr[i], lastParmsId); } } // Level 2 // Calculate decisionArr for (int i = 0; i < numOfrows; i++) { evaluator.MultiplyPlain(kernels[i], coefArr[i], decisionsArr[i]); if (useRelinearizeInplace) { evaluator.RelinearizeInplace(decisionsArr[i], relinKeys); } if (useReScale) { evaluator.RescaleToNextInplace(decisionsArr[i]); } SvcUtilities.PrintScale(decisionsArr[i], "decision" + i); SvcUtilities.PrintCyprherText(decryptor, decisionsArr[i], encoder, "decision" + i); } // Calculate decisionTotal Ciphertext decisionTotal = new Ciphertext(); //================================================================= evaluator.AddMany(decisionsArr, decisionTotal); //================================================================= SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); SvcUtilities.PrintCyprherText(decryptor, decisionTotal, encoder, "decision total"); // Encode intercepts : ParmsId! , scale! Plaintext interceptsPlainText = new Plaintext(); double scale3 = Math.Pow(2.0, power * 3); if (useReScale) { scale3 = decisionTotal.Scale; } encoder.Encode(_intercepts[0], scale3, interceptsPlainText); if (useReScale) { ParmsId lastParmsId = decisionTotal.ParmsId; evaluator.ModSwitchToInplace(interceptsPlainText, lastParmsId); } SvcUtilities.PrintScale(interceptsPlainText, "interceptsPlainText"); SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //// Calculate finalTotal Ciphertext finalTotal = new Ciphertext(); //================================================================= evaluator.AddPlainInplace(decisionTotal, interceptsPlainText); //================================================================= timePredictSum.Stop(); SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //Level 3 List <double> result = SvcUtilities.PrintCyprherText(decryptor, decisionTotal, encoder, "finalTotal"); using (System.IO.StreamWriter file = new System.IO.StreamWriter( $@"{OutputDir}IrisLinear_IrisSecureSVC_total_{power}_{useRelinearizeInplace}_{useReScale}.txt", !_firstTime) ) { _firstTime = false; file.WriteLine($"{result[0]}"); } if (result[0] > 0) { return(0); } return(1); }
public void EncryptZeroTest() { { SEALContext context = GlobalContext.BFVContext; KeyGenerator keyGen = new KeyGenerator(context); PublicKey publicKey = keyGen.PublicKey; SecretKey secretKey = keyGen.SecretKey; Encryptor encryptor = new Encryptor(context, publicKey, secretKey); Decryptor decryptor = new Decryptor(context, secretKey); Assert.IsNotNull(encryptor); Assert.IsNotNull(decryptor); Ciphertext cipher = new Ciphertext(); Plaintext plain = new Plaintext(); ParmsId nextParms = context.FirstContextData.NextContextData.ParmsId; { encryptor.EncryptZero(cipher); Assert.IsFalse(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); decryptor.Decrypt(cipher, plain); Assert.IsTrue(plain.IsZero); encryptor.EncryptZero(nextParms, cipher); Assert.IsFalse(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); Assert.AreEqual(cipher.ParmsId, nextParms); decryptor.Decrypt(cipher, plain); Assert.IsTrue(plain.IsZero); } { encryptor.EncryptZeroSymmetric(cipher); Assert.IsFalse(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); decryptor.Decrypt(cipher, plain); Assert.IsTrue(plain.IsZero); encryptor.EncryptZeroSymmetric(nextParms, cipher); Assert.IsFalse(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); Assert.AreEqual(cipher.ParmsId, nextParms); decryptor.Decrypt(cipher, plain); Assert.IsTrue(plain.IsZero); } using (MemoryStream stream = new MemoryStream()) { encryptor.EncryptZeroSymmetricSave(stream); stream.Seek(0, SeekOrigin.Begin); cipher.Load(context, stream); Assert.IsFalse(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); decryptor.Decrypt(cipher, plain); Assert.IsTrue(plain.IsZero); } using (MemoryStream stream = new MemoryStream()) { encryptor.EncryptZeroSymmetricSave(nextParms, stream); stream.Seek(0, SeekOrigin.Begin); cipher.Load(context, stream); Assert.IsFalse(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); Assert.AreEqual(cipher.ParmsId, nextParms); decryptor.Decrypt(cipher, plain); Assert.IsTrue(plain.IsZero); } } { SEALContext context = GlobalContext.CKKSContext; KeyGenerator keyGen = new KeyGenerator(context); PublicKey publicKey = keyGen.PublicKey; SecretKey secretKey = keyGen.SecretKey; Encryptor encryptor = new Encryptor(context, publicKey, secretKey); Decryptor decryptor = new Decryptor(context, secretKey); CKKSEncoder encoder = new CKKSEncoder(context); Assert.IsNotNull(encryptor); Assert.IsNotNull(decryptor); Ciphertext cipher = new Ciphertext(); Plaintext plain = new Plaintext(); ParmsId nextParms = context.FirstContextData.NextContextData.ParmsId; List <Complex> res = new List <Complex>(); { encryptor.EncryptZero(cipher); Assert.IsTrue(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); cipher.Scale = Math.Pow(2.0, 30); decryptor.Decrypt(cipher, plain); encoder.Decode(plain, res); foreach (Complex val in res) { Assert.AreEqual(val.Real, 0.0, 0.01); Assert.AreEqual(val.Imaginary, 0.0, 0.01); } encryptor.EncryptZero(nextParms, cipher); Assert.IsTrue(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); cipher.Scale = Math.Pow(2.0, 30); Assert.AreEqual(cipher.ParmsId, nextParms); decryptor.Decrypt(cipher, plain); Assert.AreEqual(plain.ParmsId, nextParms); encoder.Decode(plain, res); foreach (Complex val in res) { Assert.AreEqual(val.Real, 0.0, 0.01); Assert.AreEqual(val.Imaginary, 0.0, 0.01); } } { encryptor.EncryptZeroSymmetric(cipher); Assert.IsTrue(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); cipher.Scale = Math.Pow(2.0, 30); decryptor.Decrypt(cipher, plain); encoder.Decode(plain, res); foreach (Complex val in res) { Assert.AreEqual(val.Real, 0.0, 0.01); Assert.AreEqual(val.Imaginary, 0.0, 0.01); } encryptor.EncryptZeroSymmetric(nextParms, cipher); Assert.IsTrue(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); cipher.Scale = Math.Pow(2.0, 30); Assert.AreEqual(cipher.ParmsId, nextParms); decryptor.Decrypt(cipher, plain); Assert.AreEqual(plain.ParmsId, nextParms); encoder.Decode(plain, res); foreach (Complex val in res) { Assert.AreEqual(val.Real, 0.0, 0.01); Assert.AreEqual(val.Imaginary, 0.0, 0.01); } } using (MemoryStream stream = new MemoryStream()) { encryptor.EncryptZeroSymmetricSave(stream); stream.Seek(0, SeekOrigin.Begin); cipher.Load(context, stream); Assert.IsTrue(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); cipher.Scale = Math.Pow(2.0, 30); decryptor.Decrypt(cipher, plain); encoder.Decode(plain, res); foreach (Complex val in res) { Assert.AreEqual(val.Real, 0.0, 0.01); Assert.AreEqual(val.Imaginary, 0.0, 0.01); } } using (MemoryStream stream = new MemoryStream()) { encryptor.EncryptZeroSymmetricSave(nextParms, stream); stream.Seek(0, SeekOrigin.Begin); cipher.Load(context, stream); Assert.IsTrue(cipher.IsNTTForm); Assert.IsFalse(cipher.IsTransparent); Assert.AreEqual(cipher.Scale, 1.0, double.Epsilon); cipher.Scale = Math.Pow(2.0, 30); Assert.AreEqual(cipher.ParmsId, nextParms); decryptor.Decrypt(cipher, plain); Assert.AreEqual(plain.ParmsId, nextParms); encoder.Decode(plain, res); foreach (Complex val in res) { Assert.AreEqual(val.Real, 0.0, 0.01); Assert.AreEqual(val.Imaginary, 0.0, 0.01); } } } }
public int Predict(double[] features, int power, bool useRelinearizeInplace, bool useReScale, Stopwatch timePredictSum) { EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS); if (power < 60) { ulong polyModulusDegree = 8192; parms.PolyModulusDegree = polyModulusDegree; parms.CoeffModulus = CoeffModulus.Create(polyModulusDegree, new int[] { 60, 40, 40, 60 }); } else { ulong polyModulusDegree = 16384; parms.PolyModulusDegree = polyModulusDegree; parms.CoeffModulus = CoeffModulus.Create(polyModulusDegree, new int[] { 60, 60, 60, 60, 60, 60 }); } // double scale = Math.Pow(2.0, power); SEALContext context = new SEALContext(parms); Console.WriteLine(); KeyGenerator keygen = new KeyGenerator(context); PublicKey publicKey = keygen.PublicKey; SecretKey secretKey = keygen.SecretKey; RelinKeys relinKeys = keygen.RelinKeys(); Encryptor encryptor = new Encryptor(context, publicKey); Evaluator evaluator = new Evaluator(context); Decryptor decryptor = new Decryptor(context, secretKey); CKKSEncoder encoder = new CKKSEncoder(context); ulong slotCount = encoder.SlotCount; Console.WriteLine($"Number of slots: {slotCount}"); timePredictSum.Start(); Plaintext fPlaintext0 = new Plaintext(); Plaintext fPlaintext1 = new Plaintext(); Plaintext fPlaintext2 = new Plaintext(); Plaintext fPlaintext3 = new Plaintext(); encoder.Encode(features[0], scale, fPlaintext0); encoder.Encode(features[1], scale, fPlaintext1); encoder.Encode(features[2], scale, fPlaintext2); encoder.Encode(features[3], scale, fPlaintext3); SvcUtilities.PrintScale(fPlaintext0, "fPlaintext0"); SvcUtilities.PrintScale(fPlaintext1, "fPlaintext1"); SvcUtilities.PrintScale(fPlaintext2, "fPlaintext2"); Ciphertext f0Encrypted = new Ciphertext(); Ciphertext f1Encrypted = new Ciphertext(); Ciphertext f2Encrypted = new Ciphertext(); Ciphertext f3Encrypted = new Ciphertext(); encryptor.Encrypt(fPlaintext0, f0Encrypted); encryptor.Encrypt(fPlaintext1, f1Encrypted); encryptor.Encrypt(fPlaintext2, f2Encrypted); encryptor.Encrypt(fPlaintext3, f3Encrypted); SvcUtilities.PrintScale(f0Encrypted, "f0Encrypted"); SvcUtilities.PrintScale(f1Encrypted, "f1Encrypted"); SvcUtilities.PrintScale(f2Encrypted, "f2Encrypted"); Plaintext v00Plaintext1 = new Plaintext(); Plaintext v01Plaintext1 = new Plaintext(); Plaintext v02Plaintext1 = new Plaintext(); Plaintext v03Plaintext1 = new Plaintext(); Plaintext v10Plaintext1 = new Plaintext(); Plaintext v11Plaintext1 = new Plaintext(); Plaintext v12Plaintext1 = new Plaintext(); Plaintext v13Plaintext1 = new Plaintext(); Plaintext v20Plaintext1 = new Plaintext(); Plaintext v21Plaintext1 = new Plaintext(); Plaintext v22Plaintext1 = new Plaintext(); Plaintext v23Plaintext1 = new Plaintext(); encoder.Encode(_vectors[0][0], scale, v00Plaintext1); encoder.Encode(_vectors[0][1], scale, v01Plaintext1); encoder.Encode(_vectors[0][2], scale, v02Plaintext1); encoder.Encode(_vectors[0][3], scale, v03Plaintext1); encoder.Encode(_vectors[1][0], scale, v10Plaintext1); encoder.Encode(_vectors[1][1], scale, v11Plaintext1); encoder.Encode(_vectors[1][2], scale, v12Plaintext1); encoder.Encode(_vectors[1][3], scale, v13Plaintext1); encoder.Encode(_vectors[2][0], scale, v20Plaintext1); encoder.Encode(_vectors[2][1], scale, v21Plaintext1); encoder.Encode(_vectors[2][2], scale, v22Plaintext1); encoder.Encode(_vectors[2][3], scale, v23Plaintext1); SvcUtilities.PrintScale(v00Plaintext1, "v00Plaintext1"); SvcUtilities.PrintScale(v01Plaintext1, "v01Plaintext1"); SvcUtilities.PrintScale(v02Plaintext1, "v02Plaintext1"); SvcUtilities.PrintScale(v03Plaintext1, "v03Plaintext1"); SvcUtilities.PrintScale(v10Plaintext1, "v10Plaintext1"); SvcUtilities.PrintScale(v11Plaintext1, "v11Plaintext1"); SvcUtilities.PrintScale(v12Plaintext1, "v12Plaintext1"); SvcUtilities.PrintScale(v13Plaintext1, "v13Plaintext1"); SvcUtilities.PrintScale(v20Plaintext1, "v20Plaintext1"); SvcUtilities.PrintScale(v21Plaintext1, "v21Plaintext1"); SvcUtilities.PrintScale(v22Plaintext1, "v22Plaintext1"); SvcUtilities.PrintScale(v23Plaintext1, "v23Plaintext1"); Plaintext coef00PlainText = new Plaintext(); Plaintext coef01PlainText = new Plaintext(); Plaintext coef02PlainText = new Plaintext(); Ciphertext tSum1 = new Ciphertext(); Ciphertext tSum2 = new Ciphertext(); Ciphertext tSum3 = new Ciphertext(); Ciphertext tSum4 = new Ciphertext(); Ciphertext kernel0 = new Ciphertext(); //Level 1->2 //================================================================= evaluator.MultiplyPlain(f0Encrypted, v00Plaintext1, tSum1); evaluator.MultiplyPlain(f1Encrypted, v01Plaintext1, tSum2); evaluator.MultiplyPlain(f2Encrypted, v02Plaintext1, tSum3); evaluator.MultiplyPlain(f3Encrypted, v03Plaintext1, tSum4); //================================================================= if (useRelinearizeInplace) { Console.WriteLine("RelinearizeInplace sums 1"); evaluator.RelinearizeInplace(tSum1, relinKeys); evaluator.RelinearizeInplace(tSum2, relinKeys); evaluator.RelinearizeInplace(tSum3, relinKeys); evaluator.RelinearizeInplace(tSum4, relinKeys); } if (useReScale) { Console.WriteLine("useReScale sums 1"); evaluator.RescaleToNextInplace(tSum1); evaluator.RescaleToNextInplace(tSum2); evaluator.RescaleToNextInplace(tSum3); evaluator.RescaleToNextInplace(tSum4); } SvcUtilities.PrintScale(tSum1, "tSum1"); //Level 2 SvcUtilities.PrintScale(tSum2, "tSum2"); //Level 2 SvcUtilities.PrintScale(tSum3, "tSum3"); //Level 2 SvcUtilities.PrintScale(tSum4, "tSum4"); //Level 2 var ciphertexts1 = new List <Ciphertext>(); ciphertexts1.Add(tSum1); ciphertexts1.Add(tSum2); ciphertexts1.Add(tSum3); ciphertexts1.Add(tSum4); //================================================================= evaluator.AddMany(ciphertexts1, kernel0); //Level 2 //================================================================= SvcUtilities.PrintScale(kernel0, "kernel0"); //Level 2 SvcUtilities.PrintCyprherText(decryptor, kernel0, encoder, "kernel0"); Ciphertext kernel1 = new Ciphertext(); //Level 1-> 2 //================================================================= evaluator.MultiplyPlain(f0Encrypted, v10Plaintext1, tSum1); evaluator.MultiplyPlain(f1Encrypted, v11Plaintext1, tSum2); evaluator.MultiplyPlain(f2Encrypted, v12Plaintext1, tSum3); evaluator.MultiplyPlain(f3Encrypted, v13Plaintext1, tSum4); //================================================================= if (useRelinearizeInplace) { Console.WriteLine("RelinearizeInplace sums 2"); evaluator.RelinearizeInplace(tSum1, relinKeys); evaluator.RelinearizeInplace(tSum2, relinKeys); evaluator.RelinearizeInplace(tSum3, relinKeys); evaluator.RelinearizeInplace(tSum4, relinKeys); } if (useReScale) { Console.WriteLine("useReScale sums 2"); evaluator.RescaleToNextInplace(tSum1); evaluator.RescaleToNextInplace(tSum2); evaluator.RescaleToNextInplace(tSum3); evaluator.RescaleToNextInplace(tSum4); } ciphertexts1.Add(tSum1); ciphertexts1.Add(tSum2); ciphertexts1.Add(tSum3); ciphertexts1.Add(tSum4); Console.WriteLine("Second time : "); SvcUtilities.PrintScale(tSum1, "tSum1"); //Level 2 SvcUtilities.PrintScale(tSum2, "tSum2"); //Level 2 SvcUtilities.PrintScale(tSum3, "tSum3"); //Level 2 SvcUtilities.PrintScale(tSum4, "tSum4"); //Level 2 var ciphertexts2 = new List <Ciphertext>(); ciphertexts2.Add(tSum1); ciphertexts2.Add(tSum2); ciphertexts2.Add(tSum3); ciphertexts2.Add(tSum4); //================================================================= evaluator.AddMany(ciphertexts2, kernel1); // Level 2 //================================================================= SvcUtilities.PrintScale(kernel1, "kernel1"); SvcUtilities.PrintCyprherText(decryptor, kernel1, encoder, "kernel1"); Ciphertext kernel2 = new Ciphertext(); //Level 1->2 //================================================================= evaluator.MultiplyPlain(f0Encrypted, v20Plaintext1, tSum1); evaluator.MultiplyPlain(f1Encrypted, v21Plaintext1, tSum2); evaluator.MultiplyPlain(f2Encrypted, v22Plaintext1, tSum3); evaluator.MultiplyPlain(f3Encrypted, v23Plaintext1, tSum4); //================================================================= if (useRelinearizeInplace) { Console.WriteLine("RelinearizeInplace sums 3"); evaluator.RelinearizeInplace(tSum1, relinKeys); evaluator.RelinearizeInplace(tSum2, relinKeys); evaluator.RelinearizeInplace(tSum3, relinKeys); evaluator.RelinearizeInplace(tSum4, relinKeys); } if (useReScale) { Console.WriteLine("useReScale sums 3"); evaluator.RescaleToNextInplace(tSum1); evaluator.RescaleToNextInplace(tSum2); evaluator.RescaleToNextInplace(tSum3); evaluator.RescaleToNextInplace(tSum4); } var ciphertexts3 = new List <Ciphertext>(); ciphertexts3.Add(tSum1); ciphertexts3.Add(tSum2); ciphertexts3.Add(tSum3); ciphertexts3.Add(tSum4); Console.WriteLine("Third time : "); SvcUtilities.PrintScale(tSum1, "tSum1"); //Level 2 SvcUtilities.PrintScale(tSum2, "tSum2"); //Level 2 SvcUtilities.PrintScale(tSum3, "tSum3"); //Level 2 SvcUtilities.PrintScale(tSum4, "tSum4"); //Level 2 //================================================================= evaluator.AddMany(ciphertexts3, kernel2); //================================================================= SvcUtilities.PrintScale(kernel2, "kernel2"); //Level 2 SvcUtilities.PrintCyprherText(decryptor, kernel2, encoder, "kernel2"); Ciphertext decision1 = new Ciphertext(); Ciphertext decision2 = new Ciphertext(); Ciphertext decision3 = new Ciphertext(); SvcUtilities.PrintScale(decision1, "decision1"); //Level 0 SvcUtilities.PrintScale(decision2, "decision2"); //Level 0 SvcUtilities.PrintScale(decision3, "decision3"); //Level 0 Ciphertext nKernel0 = new Ciphertext(); Ciphertext nKernel1 = new Ciphertext(); Ciphertext nKernel2 = new Ciphertext(); //================================================================= evaluator.Negate(kernel0, nKernel0); evaluator.Negate(kernel1, nKernel1); //Level 2 evaluator.Negate(kernel2, nKernel2); //Level 2 //================================================================= //nKernel0.Scale = scale; //nKernel1.Scale = scale; //nKernel2.Scale = scale; double scale2 = Math.Pow(2.0, power); if (useReScale) { scale2 = nKernel0.Scale; } encoder.Encode(_coefficients[0][0], scale2, coef00PlainText); encoder.Encode(_coefficients[0][1], scale2, coef01PlainText); encoder.Encode(_coefficients[0][2], scale2, coef02PlainText); SvcUtilities.PrintScale(coef00PlainText, "coef00PlainText"); SvcUtilities.PrintScale(coef01PlainText, "coef01PlainText"); SvcUtilities.PrintScale(coef02PlainText, "coef02PlainText"); if (useReScale) { ParmsId lastParmsId = nKernel0.ParmsId; evaluator.ModSwitchToInplace(coef00PlainText, lastParmsId); lastParmsId = nKernel1.ParmsId; evaluator.ModSwitchToInplace(coef01PlainText, lastParmsId); lastParmsId = nKernel2.ParmsId; evaluator.ModSwitchToInplace(coef02PlainText, lastParmsId); } SvcUtilities.PrintScale(nKernel0, "nKernel0"); //Level 2 SvcUtilities.PrintScale(nKernel1, "nKernel1"); //Level 2 SvcUtilities.PrintScale(nKernel2, "nKernel2"); //Level 2 //Level 2->3 //================================================================= evaluator.MultiplyPlain(nKernel0, coef00PlainText, decision1); evaluator.MultiplyPlain(nKernel1, coef01PlainText, decision2); evaluator.MultiplyPlain(nKernel2, coef02PlainText, decision3); //================================================================= if (useRelinearizeInplace) { Console.WriteLine("RelinearizeInplace decisions"); evaluator.RelinearizeInplace(decision1, relinKeys); evaluator.RelinearizeInplace(decision2, relinKeys); evaluator.RelinearizeInplace(decision3, relinKeys); } if (useReScale) { Console.WriteLine("Rescale decisions"); evaluator.RescaleToNextInplace(decision1); evaluator.RescaleToNextInplace(decision2); evaluator.RescaleToNextInplace(decision3); } SvcUtilities.PrintScale(decision1, "decision1"); //Level 3 SvcUtilities.PrintScale(decision2, "decision2"); //Level 3 SvcUtilities.PrintScale(decision3, "decision3"); //Level 3 SvcUtilities.PrintCyprherText(decryptor, decision1, encoder, "decision1"); SvcUtilities.PrintCyprherText(decryptor, decision2, encoder, "decision2"); SvcUtilities.PrintCyprherText(decryptor, decision3, encoder, "decision3"); //================================================================= //evaluator.RelinearizeInplace(decision1,keygen.RelinKeys()); //evaluator.RelinearizeInplace(decision2, keygen.RelinKeys()); //evaluator.RelinearizeInplace(decision3, keygen.RelinKeys()); //================================================================= //PrintScale(decision1, "decision1"); var decisions = new List <Ciphertext>(); decisions.Add(decision1); decisions.Add(decision2); decisions.Add(decision3); Ciphertext decisionTotal = new Ciphertext(); //================================================================= evaluator.AddMany(decisions, decisionTotal); //================================================================= SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); SvcUtilities.PrintCyprherText(decryptor, decisionTotal, encoder, "decision total"); Ciphertext finalTotal = new Ciphertext(); Plaintext interceptsPlainText = new Plaintext(); double scale3 = Math.Pow(2.0, power * 3); if (useReScale) { scale3 = decisionTotal.Scale; } encoder.Encode(_intercepts[0], scale3, interceptsPlainText); if (useReScale) { ParmsId lastParmsId = decisionTotal.ParmsId; evaluator.ModSwitchToInplace(interceptsPlainText, lastParmsId); } SvcUtilities.PrintScale(interceptsPlainText, "interceptsPlainText"); SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //================================================================= evaluator.AddPlainInplace(decisionTotal, interceptsPlainText); //================================================================= timePredictSum.Stop(); SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //Level 3 List <double> result = SvcUtilities.PrintCyprherText(decryptor, decisionTotal, encoder, "finalTotal"); using (System.IO.StreamWriter file = new System.IO.StreamWriter( $@"{OutputDir}IrisSimple_IrisSecureSVC_total_{power}_{useRelinearizeInplace}_{useReScale}.txt", !_firstTime) ) { _firstTime = false; file.WriteLine($"{result[0]}"); } if (result[0] > 0) { return(0); } return(1); }
public int Predict(double[] features, bool useRelinearizeInplace,bool useReScale,out double finalResult) { Console.WriteLine(); ulong slotCount = _encoder.SlotCount; //Console.WriteLine($"Number of slots: {slotCount}"); var featuresLength = features.Length; var plaintexts = new Plaintext(); var featuresCiphertexts = new Ciphertext(); Stopwatch clientStopwatch = new Stopwatch(); clientStopwatch.Start(); //Encode and encrypt features double scale = Math.Pow(2.0, _power); _encoder.Encode(features, scale, plaintexts); _encryptor.Encrypt(plaintexts, featuresCiphertexts); SvcUtilities.PrintScale(plaintexts, "featurePlaintext"); SvcUtilities.PrintScale(featuresCiphertexts, "featurefEncrypted"); clientStopwatch.Stop(); Stopwatch serverInitStopwatch = new Stopwatch(); serverInitStopwatch.Start(); // Handle SV var numOfrowsCount = _vectors.Length; var numOfcolumnsCount = _vectors[0].Length; var svPlaintexts = new Plaintext[numOfrowsCount]; //Encode SV var sums = new Ciphertext[numOfrowsCount]; for (int i = 0; i < numOfrowsCount; i++) { svPlaintexts[i] = new Plaintext(); _encoder.Encode(_vectors[i], scale, svPlaintexts[i]); SvcUtilities.PrintScale(svPlaintexts[i], "supportVectorsPlaintext"+i); sums[i] = new Ciphertext(); } var kernels = new Ciphertext[numOfrowsCount]; var decisionsArr = new Ciphertext[numOfrowsCount]; var coefArr = new Plaintext [numOfrowsCount]; for (int i = 0; i < numOfrowsCount; i++) { kernels[i] = new Ciphertext(); decisionsArr[i] = new Ciphertext(); coefArr[i] = new Plaintext(); } Plaintext gamaPlaintext= new Plaintext(); _encoder.Encode(_gamma, scale, gamaPlaintext); Ciphertext tempCt = new Ciphertext(); serverInitStopwatch.Stop(); Stopwatch innerProductStopwatch = new Stopwatch(); Stopwatch negateStopwatch = new Stopwatch(); Stopwatch degreeStopwatch = new Stopwatch(); // Level 1 for (int i = 0; i < numOfrowsCount; i++) { //Console.WriteLine(i); //inner product innerProductStopwatch.Start(); _evaluator.MultiplyPlain(featuresCiphertexts, svPlaintexts[i],sums[i]); int numOfRotations = (int)Math.Ceiling(Math.Log2(numOfcolumnsCount)); for (int k = 1,m=1; m <= numOfRotations/*(int)encoder.SlotCount/2*/; k <<= 1,m++) { _evaluator.RotateVector(sums[i], k, _galoisKeys, tempCt); _evaluator.AddInplace(sums[i], tempCt); } innerProductStopwatch.Stop(); kernels[i] = sums[i]; SvcUtilities.PrintCyprherText(_decryptor, kernels[i], _encoder, $"inner product TotalValue {i}" ); SvcUtilities.PrintScale(kernels[i], "0. kernels" + i); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(kernels[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(kernels[i]); } SvcUtilities.PrintScale(kernels[i], "1. kernels" + i); kernels[i].Scale = scale; if(_kernel == Kernel.Poly) { if (useReScale) { ParmsId lastParmsId = kernels[i].ParmsId; _evaluator.ModSwitchToInplace(gamaPlaintext, lastParmsId); } _evaluator.MultiplyPlainInplace(kernels[i], gamaPlaintext); SvcUtilities.PrintScale(kernels[i], "2. kernels" + i); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(kernels[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(kernels[i]); } SvcUtilities.PrintScale(kernels[i], "3. kernels" + i); if (Math.Abs(_coef0) > 0) { Plaintext coef0Plaintext = new Plaintext(); _encoder.Encode(_coef0, kernels[i].Scale, coef0Plaintext); if (useReScale) { ParmsId lastParmsId = kernels[i].ParmsId; _evaluator.ModSwitchToInplace(coef0Plaintext, lastParmsId); } //kernels[i].Scale = coef0Plaintext.Scale; _evaluator.AddPlainInplace(kernels[i], coef0Plaintext); } SvcUtilities.PrintScale(kernels[i], "4. kernels" + i); degreeStopwatch.Start(); var kernel = new Ciphertext(kernels[i]); for (int d = 0; d < (int)_degree-1; d++) { kernel.Scale = kernels[i].Scale; if (useReScale) { ParmsId lastParmsId = kernels[i].ParmsId; _evaluator.ModSwitchToInplace(kernel, lastParmsId); } _evaluator.MultiplyInplace(kernels[i], kernel); SvcUtilities.PrintScale(kernels[i], d + " 5. kernels" + i); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(kernels[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(kernels[i]); } SvcUtilities.PrintScale(kernels[i], d + " rescale 6. kernels" + i); } SvcUtilities.PrintScale(kernels[i], "7. kernels" + i); degreeStopwatch.Stop(); } negateStopwatch.Start(); _evaluator.NegateInplace(kernels[i]); negateStopwatch.Stop(); SvcUtilities.PrintScale(kernels[i], "8. kernel"+i); SvcUtilities.PrintCyprherText(_decryptor, kernels[i], _encoder, "kernel"+i); } Stopwatch serverDecisionStopWatch = new Stopwatch(); serverDecisionStopWatch.Start(); // Encode coefficients : ParmsId! , scale! double scale2 = Math.Pow(2.0, _power); if (useReScale) { scale2 = kernels[0].Scale; } for (int i = 0; i < numOfrowsCount; i++) { _encoder.Encode(_coefficients[0][i], scale2, coefArr[i]); SvcUtilities.PrintScale(coefArr[i], "coefPlainText"+i); } if (useReScale) { for (int i = 0; i < numOfrowsCount; i++) { ParmsId lastParmsId = kernels[i].ParmsId; _evaluator.ModSwitchToInplace(coefArr[i], lastParmsId); } } // Level 2 // Calculate decisionArr for (int i = 0; i < numOfrowsCount; i++) { _evaluator.MultiplyPlain(kernels[i], coefArr[i], decisionsArr[i]); if (useRelinearizeInplace) { _evaluator.RelinearizeInplace(decisionsArr[i], _relinKeys); } if (useReScale) { _evaluator.RescaleToNextInplace(decisionsArr[i]); } SvcUtilities.PrintScale(decisionsArr[i], "decision"+i); SvcUtilities.PrintCyprherText(_decryptor, decisionsArr[i], _encoder, "decision" + i); } // Calculate decisionTotal Ciphertext decisionTotal = new Ciphertext(); //================================================================= _evaluator.AddMany(decisionsArr, decisionTotal); //================================================================= SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); SvcUtilities.PrintCyprherText(_decryptor, decisionTotal, _encoder, "decision total"); // Encode intercepts : ParmsId! , scale! Plaintext interceptsPlainText = new Plaintext(); double scale3 = Math.Pow(2.0, _power*3); if (useReScale) { scale3 = decisionTotal.Scale; } _encoder.Encode(_intercepts[0], scale3, interceptsPlainText); if (useReScale) { ParmsId lastParmsId = decisionTotal.ParmsId; _evaluator.ModSwitchToInplace(interceptsPlainText, lastParmsId); } SvcUtilities.PrintScale(interceptsPlainText, "interceptsPlainText"); SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //// Calculate finalTotal Ciphertext finalTotal = new Ciphertext(); //================================================================= _evaluator.AddPlainInplace(decisionTotal, interceptsPlainText); //================================================================= SvcUtilities.PrintScale(decisionTotal, "decisionTotal"); //Level 3 List<double> result = SvcUtilities.PrintCyprherText(_decryptor, decisionTotal, _encoder, "finalTotal",true); serverDecisionStopWatch.Stop(); Console.WriteLine($"client Init elapsed {clientStopwatch.ElapsedMilliseconds} ms"); Console.WriteLine($"server Init elapsed {serverInitStopwatch.ElapsedMilliseconds} ms"); Console.WriteLine($"server innerProductStopwatch elapsed {innerProductStopwatch.ElapsedMilliseconds} ms"); Console.WriteLine($"server negateStopwatch elapsed {negateStopwatch.ElapsedMilliseconds} ms"); Console.WriteLine($"server degreeStopwatch elapsed {degreeStopwatch.ElapsedMilliseconds} ms"); Console.WriteLine($"server Decision elapsed {serverDecisionStopWatch.ElapsedMilliseconds} ms"); finalResult = result[0]; if (result[0] > 0) { return 0; } return 1; }