Skip to content

Commit f1e2495

Browse files
authored
Merge pull request #25 from str4d/24-fieldelement-tests
Refactor FieldElement tests Closes #24
2 parents 8cd3e98 + f7ad048 commit f1e2495

File tree

3 files changed

+277
-269
lines changed

3 files changed

+277
-269
lines changed
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/**
2+
* EdDSA-Java by str4d
3+
*
4+
* To the extent possible under law, the person who associated CC0 with
5+
* EdDSA-Java has waived all copyright and related or neighboring rights
6+
* to EdDSA-Java.
7+
*
8+
* You should have received a copy of the CC0 legalcode along with this
9+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
10+
*
11+
*/
12+
package net.i2p.crypto.eddsa.math;
13+
14+
import net.i2p.crypto.eddsa.math.*;
15+
import org.hamcrest.core.*;
16+
import org.junit.*;
17+
18+
import java.math.BigInteger;
19+
20+
/**
21+
* Tests rely on the BigInteger class.
22+
*/
23+
public abstract class AbstractFieldElementTest {
24+
25+
protected abstract FieldElement getRandomFieldElement();
26+
protected abstract BigInteger toBigInteger(FieldElement f);
27+
protected abstract BigInteger getQ();
28+
protected abstract Field getField();
29+
30+
// region isNonZero
31+
32+
protected abstract FieldElement getZeroFieldElement();
33+
protected abstract FieldElement getNonZeroFieldElement();
34+
35+
@Test
36+
public void isNonZeroReturnsFalseIfFieldElementIsZero() {
37+
// Act:
38+
final FieldElement f = getZeroFieldElement();
39+
40+
// Assert:
41+
Assert.assertThat(f.isNonZero(), IsEqual.equalTo(false));
42+
}
43+
44+
@Test
45+
public void isNonZeroReturnsTrueIfFieldElementIsNonZero() {
46+
// Act:
47+
final FieldElement f = getNonZeroFieldElement();
48+
49+
// Assert:
50+
Assert.assertThat(f.isNonZero(), IsEqual.equalTo(true));
51+
}
52+
53+
// endregion
54+
55+
// region mod q arithmetic
56+
57+
@Test
58+
public void addReturnsCorrectResult() {
59+
for (int i=0; i<1000; i++) {
60+
// Arrange:
61+
final FieldElement f1 = getRandomFieldElement();
62+
final FieldElement f2 = getRandomFieldElement();
63+
final BigInteger b1 = toBigInteger(f1);
64+
final BigInteger b2 = toBigInteger(f2);
65+
66+
// Act:
67+
final FieldElement f3 = f1.add(f2);
68+
final BigInteger b3 = toBigInteger(f3).mod(getQ());
69+
70+
// Assert:
71+
Assert.assertThat(b3, IsEqual.equalTo(b1.add(b2).mod(getQ())));
72+
}
73+
}
74+
75+
@Test
76+
public void subtractReturnsCorrectResult() {
77+
for (int i=0; i<1000; i++) {
78+
// Arrange:
79+
final FieldElement f1 = getRandomFieldElement();
80+
final FieldElement f2 = getRandomFieldElement();
81+
final BigInteger b1 = toBigInteger(f1);
82+
final BigInteger b2 = toBigInteger(f2);
83+
84+
// Act:
85+
final FieldElement f3 = f1.subtract(f2);
86+
final BigInteger b3 = toBigInteger(f3).mod(getQ());
87+
88+
// Assert:
89+
Assert.assertThat(b3, IsEqual.equalTo(b1.subtract(b2).mod(getQ())));
90+
}
91+
}
92+
93+
@Test
94+
public void negateReturnsCorrectResult() {
95+
for (int i=0; i<1000; i++) {
96+
// Arrange:
97+
final FieldElement f1 = getRandomFieldElement();
98+
final BigInteger b1 = toBigInteger(f1);
99+
100+
// Act:
101+
final FieldElement f2 = f1.negate();
102+
final BigInteger b2 = toBigInteger(f2).mod(getQ());
103+
104+
// Assert:
105+
Assert.assertThat(b2, IsEqual.equalTo(b1.negate().mod(getQ())));
106+
}
107+
}
108+
109+
@Test
110+
public void multiplyReturnsCorrectResult() {
111+
for (int i=0; i<1000; i++) {
112+
// Arrange:
113+
final FieldElement f1 = getRandomFieldElement();
114+
final FieldElement f2 = getRandomFieldElement();
115+
final BigInteger b1 = toBigInteger(f1);
116+
final BigInteger b2 = toBigInteger(f2);
117+
118+
// Act:
119+
final FieldElement f3 = f1.multiply(f2);
120+
final BigInteger b3 = toBigInteger(f3).mod(getQ());
121+
122+
// Assert:
123+
Assert.assertThat(b3, IsEqual.equalTo(b1.multiply(b2).mod(getQ())));
124+
}
125+
}
126+
127+
@Test
128+
public void squareReturnsCorrectResult() {
129+
for (int i=0; i<1000; i++) {
130+
// Arrange:
131+
final FieldElement f1 = getRandomFieldElement();
132+
final BigInteger b1 = toBigInteger(f1);
133+
134+
// Act:
135+
final FieldElement f2 = f1.square();
136+
final BigInteger b2 = toBigInteger(f2).mod(getQ());
137+
138+
// Assert:
139+
Assert.assertThat(b2, IsEqual.equalTo(b1.multiply(b1).mod(getQ())));
140+
}
141+
}
142+
143+
@Test
144+
public void squareAndDoubleReturnsCorrectResult() {
145+
for (int i=0; i<1000; i++) {
146+
// Arrange:
147+
final FieldElement f1 = getRandomFieldElement();
148+
final BigInteger b1 = toBigInteger(f1);
149+
150+
// Act:
151+
final FieldElement f2 = f1.squareAndDouble();
152+
final BigInteger b2 = toBigInteger(f2).mod(getQ());
153+
154+
// Assert:
155+
Assert.assertThat(b2, IsEqual.equalTo(b1.multiply(b1).multiply(new BigInteger("2")).mod(getQ())));
156+
}
157+
}
158+
159+
@Test
160+
public void invertReturnsCorrectResult() {
161+
for (int i=0; i<1000; i++) {
162+
// Arrange:
163+
final FieldElement f1 = getRandomFieldElement();
164+
final BigInteger b1 = toBigInteger(f1);
165+
166+
// Act:
167+
final FieldElement f2 = f1.invert();
168+
final BigInteger b2 = toBigInteger(f2).mod(getQ());
169+
170+
// Assert:
171+
Assert.assertThat(b2, IsEqual.equalTo(b1.modInverse(getQ())));
172+
}
173+
}
174+
175+
@Test
176+
public void pow22523ReturnsCorrectResult() {
177+
for (int i=0; i<1000; i++) {
178+
// Arrange:
179+
final FieldElement f1 = getRandomFieldElement();
180+
final BigInteger b1 = toBigInteger(f1);
181+
182+
// Act:
183+
final FieldElement f2 = f1.pow22523();
184+
final BigInteger b2 = toBigInteger(f2).mod(getQ());
185+
186+
// Assert:
187+
Assert.assertThat(b2, IsEqual.equalTo(b1.modPow(BigInteger.ONE.shiftLeft(252).subtract(new BigInteger("3")), getQ())));
188+
}
189+
}
190+
191+
// endregion
192+
193+
// region hashCode / equals
194+
195+
@Test
196+
public void equalsOnlyReturnsTrueForEquivalentObjects() {
197+
// Arrange:
198+
final FieldElement f1 = getRandomFieldElement();
199+
final FieldElement f2 = getField().getEncoding().decode(f1.toByteArray());
200+
final FieldElement f3 = getRandomFieldElement();
201+
final FieldElement f4 = getRandomFieldElement();
202+
203+
// Assert:
204+
Assert.assertThat(f1, IsEqual.equalTo(f2));
205+
Assert.assertThat(f1, IsNot.not(IsEqual.equalTo(f3)));
206+
Assert.assertThat(f1, IsNot.not(IsEqual.equalTo(f4)));
207+
Assert.assertThat(f3, IsNot.not(IsEqual.equalTo(f4)));
208+
}
209+
210+
@Test
211+
public void hashCodesAreEqualForEquivalentObjects() {
212+
// Arrange:
213+
final FieldElement f1 = getRandomFieldElement();
214+
final FieldElement f2 = getField().getEncoding().decode(f1.toByteArray());
215+
final FieldElement f3 = getRandomFieldElement();
216+
final FieldElement f4 = getRandomFieldElement();
217+
218+
// Assert:
219+
Assert.assertThat(f1.hashCode(), IsEqual.equalTo(f2.hashCode()));
220+
Assert.assertThat(f1.hashCode(), IsNot.not(IsEqual.equalTo(f3.hashCode())));
221+
Assert.assertThat(f1.hashCode(), IsNot.not(IsEqual.equalTo(f4.hashCode())));
222+
Assert.assertThat(f3.hashCode(), IsNot.not(IsEqual.equalTo(f4.hashCode())));
223+
}
224+
225+
// endregion
226+
}

test/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElementTest.java

Lines changed: 29 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,20 @@
1515
import static org.junit.Assert.*;
1616

1717
import java.math.BigInteger;
18+
import java.util.Random;
1819

1920
import net.i2p.crypto.eddsa.Utils;
2021
import net.i2p.crypto.eddsa.math.Field;
2122
import net.i2p.crypto.eddsa.math.FieldElement;
23+
import net.i2p.crypto.eddsa.math.MathUtils;
24+
import net.i2p.crypto.eddsa.math.AbstractFieldElementTest;
2225
import org.junit.Test;
2326

2427
/**
2528
* @author str4d
2629
*
2730
*/
28-
public class BigIntegerFieldElementTest {
31+
public class BigIntegerFieldElementTest extends AbstractFieldElementTest {
2932
static final byte[] BYTES_ZERO = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000");
3033
static final byte[] BYTES_ONE = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000");
3134
static final byte[] BYTES_TEN = Utils.hexToBytes("0a00000000000000000000000000000000000000000000000000000000000000");
@@ -39,6 +42,27 @@ public class BigIntegerFieldElementTest {
3942
static final FieldElement ONE = new BigIntegerFieldElement(ed25519Field, BigInteger.ONE);
4043
static final FieldElement TWO = new BigIntegerFieldElement(ed25519Field, BigInteger.valueOf(2));
4144

45+
protected FieldElement getRandomFieldElement() {
46+
BigInteger r;
47+
Random rnd = new Random();
48+
do {
49+
r = new BigInteger(255, rnd);
50+
} while (r.compareTo(getQ()) >= 0);
51+
return new BigIntegerFieldElement(ed25519Field, r);
52+
}
53+
54+
protected BigInteger toBigInteger(FieldElement f) {
55+
return ((BigIntegerFieldElement)f).bi;
56+
}
57+
58+
protected BigInteger getQ() {
59+
return MathUtils.getQ();
60+
}
61+
62+
protected Field getField() {
63+
return ed25519Field;
64+
}
65+
4266
/**
4367
* Test method for {@link BigIntegerFieldElement#BigIntegerFieldElement(Field, BigInteger)}.
4468
*/
@@ -69,92 +93,16 @@ public void testToByteArray() {
6993

7094
// region isNonZero
7195

72-
@Test
73-
public void isNonZeroReturnsFalseIfFieldElementIsZero() {
74-
// Assert:
75-
assertThat(ZERO.isNonZero(), is(equalTo(false)));
96+
protected FieldElement getZeroFieldElement() {
97+
return ZERO;
7698
}
7799

78-
@Test
79-
public void isNonZeroReturnsTrueIfFieldElementIsNonZero() {
80-
// Assert:
81-
assertThat(TWO.isNonZero(), is(equalTo(true)));
100+
protected FieldElement getNonZeroFieldElement() {
101+
return TWO;
82102
}
83103

84104
// endregion
85105

86-
/**
87-
* Test method for {@link FieldElement#isNegative()}.
88-
*/
89-
@Test
90-
public void testIsNegative() {
91-
fail("Not yet implemented");
92-
}
93-
94-
/**
95-
* Test method for {@link FieldElement#add(FieldElement)}.
96-
*/
97-
@Test
98-
public void testAdd() {
99-
fail("Not yet implemented");
100-
}
101-
102-
/**
103-
* Test method for {@link FieldElement#subtract(FieldElement)}.
104-
*/
105-
@Test
106-
public void testSubtract() {
107-
fail("Not yet implemented");
108-
}
109-
110-
/**
111-
* Test method for {@link FieldElement#negate()}.
112-
*/
113-
@Test
114-
public void testNegate() {
115-
fail("Not yet implemented");
116-
}
117-
118-
/**
119-
* Test method for {@link FieldElement#multiply(FieldElement)}.
120-
*/
121-
@Test
122-
public void testMultiply() {
123-
fail("Not yet implemented");
124-
}
125-
126-
/**
127-
* Test method for {@link FieldElement#square()}.
128-
*/
129-
@Test
130-
public void testSquare() {
131-
fail("Not yet implemented");
132-
}
133-
134-
/**
135-
* Test method for {@link FieldElement#squareAndDouble()}.
136-
*/
137-
@Test
138-
public void testSquareAndDouble() {
139-
fail("Not yet implemented");
140-
}
141-
142-
/**
143-
* Test method for {@link FieldElement#invert()}.
144-
*/
145-
@Test
146-
public void testInvert() {
147-
fail("Not yet implemented");
148-
}
149-
150-
/**
151-
* Test method for {@link FieldElement#pow22523()}.
152-
*/
153-
@Test
154-
public void testPow22523() {
155-
fail("Not yet implemented");
156-
}
157-
158106
/**
159107
* Test method for {@link FieldElement#equals(java.lang.Object)}.
160108
*/

0 commit comments

Comments
 (0)