• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lumip / CompactCryptoGroupAlgebra / 11419755082

19 Oct 2024 06:18PM UTC coverage: 43.483%. First build
11419755082

Pull #5

github

web-flow
Merge 35b7fb76e into 8e1b35867
Pull Request #5: GitHub actions

310 of 362 branches covered (85.64%)

Branch coverage included in aggregate %.

30 of 111 new or added lines in 18 files covered. (27.03%)

1895 of 4709 relevant lines covered (40.24%)

5887.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/CompactCryptoGroupAlgebra.Tests/Multiplicative/MultiplicativeGroupAlgebraTests.cs
1
// CompactCryptoGroupAlgebra - C# implementation of abelian group algebra for experimental cryptography
2

3
// SPDX-FileCopyrightText: 2022 Lukas Prediger <lumip@lumip.de>
4
// SPDX-License-Identifier: GPL-3.0-or-later
5
// SPDX-FileType: SOURCE
6

7
// CompactCryptoGroupAlgebra is free software: you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation, either version 3 of the License, or
10
// (at your option) any later version.
11
//
12
// CompactCryptoGroupAlgebra is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
// GNU General Public License for more details.
16
//
17
// You should have received a copy of the GNU General Public License
18
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
19

20
using System;
21
using System.Diagnostics;
22
using System.Numerics;
23
using System.Security.Cryptography;
24
using Moq;
25
using NUnit.Framework;
26

27
namespace CompactCryptoGroupAlgebra.Multiplicative
28
{
29
    [TestFixture]
30
    public class MultiplicativeGroupAlgebraTests
31
    {
32
        private MultiplicativeGroupAlgebra? groupAlgebra;
33

34
        [SetUp]
35
        public void SetUpAlgebra()
36
        {
×
37
            groupAlgebra = new MultiplicativeGroupAlgebra(
×
38
                prime: BigPrime.CreateWithoutChecks(23),
×
39
                order: BigPrime.CreateWithoutChecks(11),
×
40
                generator: 2
×
41
            );
×
42
            // group elements: 1,  2,  3,  4,  6,  8,  9, 12, 13, 16, 18
43
        }
×
44

45
        [Test]
46
        public void TestAdd()
47
        {
×
48
            var result = groupAlgebra!.Add(4, 18);
×
49
            var expected = new BigInteger(3);
×
50

51
            Assert.AreEqual(expected, result);
×
52
        }
×
53

54
        [Test]
55
        public void TestComputeSecurityLevel()
56
        {
×
57
            var mod = BigPrime.CreateWithoutChecks(BigInteger.One << 2047);
×
58
            Assert.AreEqual(115, MultiplicativeGroupAlgebra.ComputeSecurityLevel(mod, mod));
×
59

60
            var smallOrder = BigPrime.CreateWithoutChecks(new BigInteger(4));
×
61
            Assert.AreEqual(2 * NumberLength.GetLength(smallOrder).InBits, MultiplicativeGroupAlgebra.ComputeSecurityLevel(mod, smallOrder));
×
62
        }
×
63

64
        [Test]
65
        public void TestComputePrimeLengthForSecurityLevel()
66
        {
×
67
            // dominated by NFS
68
            var l = MultiplicativeGroupAlgebra.ComputePrimeLengthForSecurityLevel(100);
×
69
            var p = BigPrime.CreateWithoutChecks(BigInteger.One << (l.InBits - 1));
×
70
            var s = MultiplicativeGroupAlgebra.ComputeSecurityLevel(p, p);
×
71
            Assert.AreEqual(100, s);
×
72

73
            // dominated by Pollard Rho
74
            l = MultiplicativeGroupAlgebra.ComputePrimeLengthForSecurityLevel(1);
×
75
            Assert.AreEqual(2, l.InBits);
×
76
        }
×
77

78
        [Test]
79
        public void TestSecurityLevel()
80
        {
×
81
            var expected = MultiplicativeGroupAlgebra.ComputeSecurityLevel(groupAlgebra!.Prime, groupAlgebra!.Order);
×
82
            Assert.AreEqual(expected, groupAlgebra!.SecurityLevel);
×
83
        }
×
84

85
        [Test]
86
        [TestCase(0, 1)]
87
        [TestCase(1, 3)]
88
        [TestCase(2, 9)]
89
        [TestCase(3, 4)]
90
        [TestCase(4, 12)]
91
        [TestCase(6, 16)]
92
        [TestCase(13, 9)]
93
        [TestCase(5, 13)] // this is not part of the actual (sub)group but the embedding group, we confirm that it works anyways
94
        public void TestMultiplyScalar(int scalarInt, int expectedInt)
95
        {
×
96
            var k = new BigInteger(scalarInt);
×
97
            var expected = new BigInteger(expectedInt);
×
98

99
            var x = new BigInteger(3);
×
100
            var result = groupAlgebra!.MultiplyScalar(x, k);
×
101
            Assert.AreEqual(expected, result);
×
102
        }
×
103

104
        [Test]
105
        public void TestGeneratorIsAsSet()
106
        {
×
107
            var generator = new BigInteger(2);
×
108
            Assert.AreEqual(generator, groupAlgebra!.Generator);
×
109
        }
×
110

111
        [Test]
112
        [TestCase(0)]
113
        [TestCase(-3)]
114
        [TestCase(23)]
115
        [TestCase(136)]
116
        public void TestInvalidElementRejectedAsGenerator(int generatorInt)
117
        {
×
118
            var generator = new BigInteger(generatorInt);
×
119
            Assert.Throws<ArgumentException>(
×
120
                () => new MultiplicativeGroupAlgebra(groupAlgebra!.Prime, groupAlgebra!.Order, generator)
×
121
            );
×
122
        }
×
123

124
        [Test]
125
        [TestCase(2)]
126
        [TestCase(9)]
127
        [TestCase(13)]
128
        public void TestIsElementAcceptsValidElements(int elementInt)
129
        {
×
130
            var element = new BigInteger(elementInt);
×
131
            Assert.IsTrue(groupAlgebra!.IsPotentialElement(element));
×
132
            Assert.IsTrue(groupAlgebra!.IsSafeElement(element));
×
133
        }
×
134

135
        [Test]
136
        [TestCase(0)]
137
        [TestCase(-3)]
138
        [TestCase(23)]
139
        [TestCase(136)]
140
        public void TestIsElementRejectsInvalidElementsOutOfBounds(int elementInt)
141
        {
×
142
            var element = new BigInteger(elementInt);
×
143
            Assert.IsFalse(groupAlgebra!.IsPotentialElement(element));
×
144
            Assert.IsFalse(groupAlgebra!.IsSafeElement(element));
×
145
        }
×
146

147
        [Test]
148
        [TestCase(1)]
149
        [TestCase(22)]
150
        public void TestIsSafeElementRejectsUnsafeElements(int elementInt)
151
        {
×
152
            var element = new BigInteger(elementInt);
×
153
            Assert.IsTrue(groupAlgebra!.IsPotentialElement(element));
×
154
            Assert.IsFalse(groupAlgebra!.IsSafeElement(element));
×
155
        }
×
156

157
        [Test]
158
        public void TestIsSafeElementForNeutralElementCofactorOne()
159
        {
×
160
            var groupAlgebra = new MultiplicativeGroupAlgebra(BigPrime.CreateWithoutChecks(11), BigPrime.CreateWithoutChecks(10), 2);
×
161
            Assert.That(groupAlgebra.IsPotentialElement(groupAlgebra.NeutralElement));
×
162
            Assert.That(!groupAlgebra.IsSafeElement(groupAlgebra.NeutralElement));
×
163
        }
×
164

165
        [Test]
166
        public void TestGroupElementBitLength()
167
        {
×
168
            Assert.AreEqual(5, groupAlgebra!.ElementBitLength);
×
169
        }
×
170

171
        [Test]
172
        public void TestOrderBitLength()
173
        {
×
174
            Assert.AreEqual(4, groupAlgebra!.OrderBitLength);
×
175
        }
×
176

177
        [Test]
178
        [TestCase(1)]
179
        [TestCase(2)]
180
        [TestCase(9)]
181
        [TestCase(18)]
182
        public void TestNegate(int elementInt)
183
        {
×
184
            var x = new BigInteger(elementInt);
×
185
            var negated = groupAlgebra!.Negate(x);
×
186

187
            Assert.AreEqual(groupAlgebra!.Add(negated, x), BigInteger.One, "adding negated value does not result in neutral element");
×
188
            Assert.AreEqual(groupAlgebra!.MultiplyScalar(x, groupAlgebra!.Order - 1), negated, "negated value not as expected");
×
189
        }
×
190

191
        public void TestNegateForNonSubgroup()
192
        {
×
193
            var x = new BigInteger(5);
×
194
            var negated = groupAlgebra!.Negate(x);
×
195

196
            Assert.AreEqual(groupAlgebra!.Add(negated, x), BigInteger.One,
×
197
                "adding negated value for embedding group element does not result in neutral element"
×
198
            );
×
199
        }
×
200

201
        [Test]
202
        public void TestNeutralElement()
203
        {
×
204
            Assert.AreEqual(BigInteger.One, groupAlgebra!.NeutralElement);
×
205
        }
×
206

207
        [Test]
208
        public void TestFromBytes()
209
        {
×
210
            var expected = new BigInteger(7);
×
211
            var buffer = expected.ToByteArray();
×
212

213
            var result = groupAlgebra!.FromBytes(buffer);
×
214
            Assert.AreEqual(expected, result);
×
215
        }
×
216

217
        [Test]
218
        public void TestToBytes()
219
        {
×
220
            var element = new BigInteger(7);
×
221
            var expected = element.ToByteArray();
×
222

223
            var result = groupAlgebra!.ToBytes(element);
×
224

225
            CollectionAssert.AreEqual(expected, result);
×
226
        }
×
227

228
        [Test]
229
        public void TestProperties()
230
        {
×
231
            var generator = new BigInteger(2);
×
232
            var neutralElement = BigInteger.One;
×
233
            var modulo = BigPrime.CreateWithoutChecks(23);
×
234
            var order = BigPrime.CreateWithoutChecks(11);
×
235
            var cofactor = new BigInteger(2);
×
236

237
            Assert.AreEqual(neutralElement, groupAlgebra!.NeutralElement, "verifying neutral element");
×
238
            Assert.AreEqual(generator, groupAlgebra!.Generator, "verifying generator");
×
239
            Assert.AreEqual(order, groupAlgebra!.Order, "verifying order");
×
240
            Assert.AreEqual(modulo, groupAlgebra!.Prime, "verifying modulo");
×
241
            Assert.AreEqual(cofactor, groupAlgebra!.Cofactor, "verifying cofactor");
×
242
        }
×
243

244
        [Test]
245
        public void TestEqualsTrue()
246
        {
×
247
            var otherAlgebra = new MultiplicativeGroupAlgebra(
×
248
                groupAlgebra!.Prime, groupAlgebra!.Order, groupAlgebra!.Generator
×
249
            );
×
250

251
            bool result = groupAlgebra!.Equals(otherAlgebra);
×
252
            Assert.IsTrue(result);
×
253
        }
×
254

255
        [Test]
256
        public void TestEqualsFalseForNull()
257
        {
×
258
            bool result = groupAlgebra!.Equals(null);
×
259
            Assert.IsFalse(result);
×
260
        }
×
261

262
        [Test]
263
        public void TestEqualsFalseForUnrelatedObject()
264
        {
×
265
            var otherAlgebra = new object();
×
266
            bool result = groupAlgebra!.Equals(otherAlgebra);
×
267
            Assert.IsFalse(result);
×
268
        }
×
269

270
        [Test]
271
        public void TestEqualsFalseForOtherAlgebra()
272
        {
×
273
            var otherAlgebra = new MultiplicativeGroupAlgebra(
×
274
                BigPrime.CreateWithoutChecks(2*53+1),
×
275
                BigPrime.CreateWithoutChecks(53),
×
276
                4
×
277
            );
×
278
            Assert.IsFalse(groupAlgebra!.Equals(otherAlgebra));
×
279
        }
×
280

281

282
        [Test]
283
        public void TestGetHashCodeSameForEqual()
284
        {
×
285
            var otherAlgebra = new MultiplicativeGroupAlgebra(
×
286
                groupAlgebra!.Prime, groupAlgebra!.Order, groupAlgebra!.Generator
×
287
            );
×
288

289
            Assert.AreEqual(groupAlgebra!.GetHashCode(), otherAlgebra.GetHashCode());
×
290
        }
×
291

292
        [Test]
293
        public void TestCreateCryptoGroup()
294
        {
×
295
            var group = MultiplicativeGroupAlgebra.CreateCryptoGroup(
×
296
                groupAlgebra!.Prime, groupAlgebra!.Order, groupAlgebra!.Generator
×
297
            );
×
298
            Assert.AreEqual(groupAlgebra, group.Algebra);
×
299
        }
×
300

301
        [Test]
302
        public void TestCreateCryptoGroupForLevelRngReturnsOdd()
303
        {
×
304
            int securityLevel = 32;
×
305
            var expectedPrimeLength = MultiplicativeGroupAlgebra.ComputePrimeLengthForSecurityLevel(securityLevel);
×
306
            var expectedOrderLength = NumberLength.FromBitLength(expectedPrimeLength.InBits - 1);
×
307

308
            var primeBeforeOrder = BigInteger.Parse("332306998946228968225951765070101393");
×
309
            var order = BigPrime.CreateWithoutChecks(BigInteger.Parse("166153499473114484112975882535050719"));
×
310
            var prime = BigPrime.CreateWithoutChecks(BigInteger.Parse("332306998946228968225951765070101439"));
×
311

312
            var rngResponse = (primeBeforeOrder - 2).ToByteArray();
×
313

314
            Debug.Assert(expectedPrimeLength.InBits == NumberLength.GetLength(prime).InBits);
×
315
            Debug.Assert(expectedOrderLength.InBits == NumberLength.GetLength(order).InBits);
×
316

317
            var rngMock = new Mock<RandomNumberGenerator>(MockBehavior.Strict);
×
318
            rngMock.Setup(rng => rng.GetBytes(It.IsAny<byte[]>()))
×
NEW
319
                   .Callback<byte[]>(buffer =>
×
NEW
320
                        {
×
NEW
321
                            Buffer.BlockCopy(buffer, 0, rngResponse, 0, Math.Min(rngResponse.Length, buffer.Length));
×
NEW
322
                        }
×
NEW
323
                   );
×
324

325
            var group = MultiplicativeGroupAlgebra.CreateCryptoGroup(securityLevel, rngMock.Object);
×
326
            Assert.IsInstanceOf<MultiplicativeGroupAlgebra>(group.Algebra);
×
327

328
            Assert.That(group.SecurityLevel >= securityLevel, "Created group does not meet security level!");
×
329
            Assert.AreEqual(order, group.Algebra.Order);
×
330
            Assert.AreEqual(prime, ((MultiplicativeGroupAlgebra)group.Algebra).Prime);
×
331
            Assert.That(group.Algebra.IsSafeElement(group.Algebra.Generator));
×
332
        }
×
333

334

335
        [Test]
336
        public void TestCreateCryptoGroupForLevelRngReturnsEven()
337
        {
×
338
            int securityLevel = 32;
×
339
            var expectedPrimeLength = MultiplicativeGroupAlgebra.ComputePrimeLengthForSecurityLevel(securityLevel);
×
340
            var expectedOrderLength = NumberLength.FromBitLength(expectedPrimeLength.InBits - 1);
×
341

342
            var primeBeforeOrder = BigInteger.Parse("332306998946228968225951765070101393");
×
343
            var order = BigPrime.CreateWithoutChecks(BigInteger.Parse("166153499473114484112975882535050719"));
×
344
            var prime = BigPrime.CreateWithoutChecks(BigInteger.Parse("332306998946228968225951765070101439"));
×
345

346
            var rngResponse = (primeBeforeOrder - 3).ToByteArray();
×
347

348
            Debug.Assert(expectedPrimeLength.InBits == NumberLength.GetLength(prime).InBits);
×
349
            Debug.Assert(expectedOrderLength.InBits == NumberLength.GetLength(order).InBits);
×
350

351
            var rngMock = new Mock<RandomNumberGenerator>(MockBehavior.Strict);
×
352
            rngMock.Setup(rng => rng.GetBytes(It.IsAny<byte[]>()))
×
NEW
353
                   .Callback<byte[]>(buffer =>
×
NEW
354
                        {
×
NEW
355
                            Buffer.BlockCopy(buffer, 0, rngResponse, 0, Math.Min(rngResponse.Length, buffer.Length));
×
NEW
356
                        }
×
NEW
357
                   );
×
358

359
            var group = MultiplicativeGroupAlgebra.CreateCryptoGroup(securityLevel, rngMock.Object);
×
360
            Assert.IsInstanceOf<MultiplicativeGroupAlgebra>(group.Algebra);
×
361

362
            Assert.That(group.SecurityLevel >= securityLevel, "Created group does not meet security level!");
×
363
            Assert.AreEqual(order, group.Algebra.Order);
×
364
            Assert.AreEqual(prime, ((MultiplicativeGroupAlgebra)group.Algebra).Prime);
×
365
            Assert.That(group.Algebra.IsSafeElement(group.Algebra.Generator));
×
366
        }
×
367

368
    }
369
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc