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