1 // Copyright (c) Microsoft Corporation. All rights reserved. 2 // Licensed under the MIT license. 3 4 using Microsoft.Research.SEAL; 5 using Microsoft.VisualStudio.TestTools.UnitTesting; 6 using System.Collections.Generic; 7 8 namespace SEALNetTest 9 { 10 [TestClass] 11 public class SEALContextTests 12 { 13 [TestMethod] SEALContextCreateTest()14 public void SEALContextCreateTest() 15 { 16 EncryptionParameters encParams1 = new EncryptionParameters(SchemeType.BFV); 17 EncryptionParameters encParams2 = new EncryptionParameters(SchemeType.CKKS); 18 19 SEALContext context1 = new SEALContext(encParams1); 20 SEALContext context2 = new SEALContext(encParams2); 21 22 Assert.IsNotNull(context1); 23 Assert.IsNotNull(context2); 24 25 Assert.IsFalse(context1.ParametersSet); 26 Assert.IsFalse(context2.ParametersSet); 27 28 Assert.AreNotSame(context1.FirstParmsId, context1.LastParmsId); 29 Assert.AreEqual(context1.FirstParmsId, context1.LastParmsId); 30 31 SEALContext.ContextData data1 = context2.FirstContextData; 32 SEALContext.ContextData data2 = context2.GetContextData(context2.FirstParmsId); 33 34 Assert.AreNotSame(data1, data2); 35 ulong[] totalCoeffMod1 = data1.TotalCoeffModulus; 36 ulong[] totalCoeffMod2 = data2.TotalCoeffModulus; 37 38 int bitCount1 = data1.TotalCoeffModulusBitCount; 39 int bitCount2 = data2.TotalCoeffModulusBitCount; 40 41 Assert.AreEqual(bitCount1, bitCount2); 42 Assert.AreEqual(totalCoeffMod1.Length, totalCoeffMod2.Length); 43 44 for (int i = 0; i < totalCoeffMod1.Length; i++) 45 { 46 Assert.AreEqual(totalCoeffMod1[i], totalCoeffMod2[i]); 47 } 48 } 49 50 [TestMethod] SEALContextParamsTest()51 public void SEALContextParamsTest() 52 { 53 EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV) 54 { 55 PolyModulusDegree = 128, 56 PlainModulus = new Modulus(1 << 6), 57 CoeffModulus = CoeffModulus.Create(128, new int[] { 30, 30, 30 }) 58 }; 59 SEALContext context = new SEALContext(parms, expandModChain: true, secLevel: SecLevelType.None); 60 61 SEALContext.ContextData data = context.KeyContextData; 62 Assert.IsNotNull(data); 63 64 EncryptionParameters parms2 = data.Parms; 65 Assert.AreEqual(parms.PolyModulusDegree, parms2.PolyModulusDegree); 66 67 EncryptionParameterQualifiers qualifiers = data.Qualifiers; 68 Assert.IsNotNull(qualifiers); 69 70 Assert.IsTrue(qualifiers.ParametersSet); 71 Assert.IsFalse(qualifiers.UsingBatching); 72 Assert.IsTrue(qualifiers.UsingFastPlainLift); 73 Assert.IsTrue(qualifiers.UsingFFT); 74 Assert.IsTrue(qualifiers.UsingNTT); 75 Assert.AreEqual(SecLevelType.None, qualifiers.SecLevel); 76 Assert.IsFalse(qualifiers.UsingDescendingModulusChain); 77 Assert.IsTrue(context.UsingKeyswitching); 78 79 ulong[] cdpm = data.CoeffDivPlainModulus; 80 Assert.AreEqual(3, cdpm.Length); 81 82 Assert.AreEqual(32ul, data.PlainUpperHalfThreshold); 83 84 Assert.AreEqual(3, data.PlainUpperHalfIncrement.Length); 85 Assert.IsNull(data.UpperHalfThreshold); 86 Assert.IsNotNull(data.UpperHalfIncrement); 87 Assert.AreEqual(3, data.UpperHalfIncrement.Length); 88 Assert.AreEqual(2ul, data.ChainIndex); 89 90 Assert.IsNull(data.PrevContextData); 91 SEALContext.ContextData data2 = data.NextContextData; 92 Assert.IsNotNull(data2); 93 Assert.AreEqual(1ul, data2.ChainIndex); 94 Assert.AreEqual(2ul, data2.PrevContextData.ChainIndex); 95 96 SEALContext.ContextData data3 = data2.NextContextData; 97 Assert.IsNotNull(data3); 98 Assert.AreEqual(0ul, data3.ChainIndex); 99 Assert.AreEqual(1ul, data3.PrevContextData.ChainIndex); 100 Assert.IsNull(data3.NextContextData); 101 102 parms = new EncryptionParameters(SchemeType.BFV) 103 { 104 PolyModulusDegree = 127, 105 PlainModulus = new Modulus(1 << 6), 106 CoeffModulus = CoeffModulus.Create(128, new int[] { 30, 30, 30 }) 107 }; 108 context = new SEALContext(parms, expandModChain: true, secLevel: SecLevelType.None); 109 Assert.AreEqual(context.ParameterErrorName(), "invalid_poly_modulus_degree_non_power_of_two"); 110 Assert.AreEqual(context.ParameterErrorMessage(), "poly_modulus_degree is not a power of two"); 111 } 112 113 [TestMethod] SEALContextCKKSParamsTest()114 public void SEALContextCKKSParamsTest() 115 { 116 int slotSize = 4; 117 EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS) 118 { 119 PolyModulusDegree = 2 * (ulong)slotSize, 120 CoeffModulus = CoeffModulus.Create(2 * (ulong)slotSize, new int[] { 40, 40, 40, 40 }) 121 }; 122 SEALContext context = new SEALContext(parms, 123 expandModChain: true, 124 secLevel: SecLevelType.None); 125 126 SEALContext.ContextData data = context.KeyContextData; 127 Assert.IsNotNull(data); 128 129 // This should be available in CKKS 130 Assert.IsNotNull(data.UpperHalfThreshold); 131 Assert.AreEqual(4, data.UpperHalfThreshold.Length); 132 Assert.IsNull(data.UpperHalfIncrement); 133 Assert.AreEqual(3ul, data.ChainIndex); 134 135 Assert.IsNull(data.PrevContextData); 136 SEALContext.ContextData data2 = data.NextContextData; 137 Assert.IsNotNull(data2); 138 Assert.AreEqual(2ul, data2.ChainIndex); 139 Assert.AreEqual(3ul, data2.PrevContextData.ChainIndex); 140 141 SEALContext.ContextData data3 = data2.NextContextData; 142 Assert.IsNotNull(data3); 143 Assert.AreEqual(1ul, data3.ChainIndex); 144 Assert.AreEqual(2ul, data3.PrevContextData.ChainIndex); 145 146 SEALContext.ContextData data4 = data3.NextContextData; 147 Assert.IsNotNull(data4); 148 Assert.AreEqual(0ul, data4.ChainIndex); 149 Assert.AreEqual(1ul, data4.PrevContextData.ChainIndex); 150 151 Assert.IsNull(data4.NextContextData); 152 } 153 154 [TestMethod] ExpandModChainTest()155 public void ExpandModChainTest() 156 { 157 EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV) 158 { 159 PolyModulusDegree = 4096, 160 CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree: 4096), 161 PlainModulus = new Modulus(1 << 20) 162 }; 163 164 SEALContext context1 = new SEALContext(parms, 165 expandModChain: true, 166 secLevel: SecLevelType.None); 167 168 // By default there is a chain 169 SEALContext.ContextData contextData = context1.KeyContextData; 170 Assert.IsNotNull(contextData); 171 Assert.IsNull(contextData.PrevContextData); 172 Assert.IsNotNull(contextData.NextContextData); 173 contextData = context1.FirstContextData; 174 Assert.IsNotNull(contextData); 175 Assert.IsNotNull(contextData.PrevContextData); 176 Assert.IsNotNull(contextData.NextContextData); 177 178 // This should not create a chain 179 SEALContext context2 = new SEALContext(parms, expandModChain: false); 180 contextData = context2.KeyContextData; 181 Assert.IsNotNull(contextData); 182 Assert.IsNull(contextData.PrevContextData); 183 Assert.IsNotNull(contextData.NextContextData); 184 contextData = context2.FirstContextData; 185 Assert.IsNotNull(contextData); 186 Assert.IsNotNull(contextData.PrevContextData); 187 Assert.IsNull(contextData.NextContextData); 188 } 189 } 190 } 191