Skip to content

Commit 462090c

Browse files
authored
Merge pull request #137 from cryptimeleon/develop
Release v3.0.0
2 parents 2250b1a + 65d16d5 commit 462090c

48 files changed

Lines changed: 2754 additions & 713 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
10+
## [3.0.0]
11+
12+
### Changed
13+
- `DebugGroup` group operation counting data is now split up into buckets that allow, for example, to separately count operations done by different parties in an interactive protocol. Furthermore, counting is now done statically, i.e. the data in each bucket persists across `DebugGroup` instances.
14+
- Reduce collisions for `Zn#injectiveValueOf`
15+
16+
### Added
17+
- Add lazy and naive wrappers around `Secp256k1` curve, and make curve implementation package-private
18+
19+
### Fixed
20+
- Fixed [issue](https://github.com/cryptimeleon/math/pull/134) where exceptions during group computations could hang up the whole applications without surfacing the exception.
21+
922
## [2.1.0]
1023

1124
### Added
@@ -17,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1730
## [2.0.0] - 2021-06-23
1831

1932
### Added
33+
- New indifferentiable hash functions to G1 and G2 for Barreto-Naehrig bilinear groups
2034
- Additional operator overload methods added to `ExponentExpr`
2135
- `BasicBilinearGroup` wrappers for the implemented bilinear groups
2236
- Convenience methods for the vector classes
@@ -42,7 +56,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4256
- Initial release
4357

4458

45-
[Unreleased]: https://github.com/cryptimeleon/math/compare/v2.1.0...HEAD
59+
[Unreleased]: https://github.com/cryptimeleon/math/compare/v3.0.0...HEAD
60+
[3.0.0]: https://github.com/cryptimeleon/math/compare/v2.1.0...v3.0.0
4661
[2.1.0]: https://github.com/cryptimeleon/math/compare/v2.0.0...v2.1.0
4762
[2.0.0]: https://github.com/cryptimeleon/math/compare/v1.0.0...v2.0.0
4863
[1.0.0]: https://github.com/cryptimeleon/math/releases/tag/v1.0.0

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ To add the newest Math version as a dependency, add this to your project's POM:
6767
<dependency>
6868
<groupId>org.cryptimeleon</groupId>
6969
<artifactId>math</artifactId>
70-
<version>2.1.0</version>
70+
<version>3.0.0</version>
7171
</dependency>
7272
```
7373

7474
### Installation With Gradle
7575

7676
Math is published via Maven Central.
7777
Therefore, you need to add `mavenCentral()` to the `repositories` section of your project's `build.gradle` file.
78-
Then, add `implementation group: 'org.cryptimeleon', name: 'math', version: '2.1.0'` to the `dependencies` section of your `build.gradle` file.
78+
Then, add `implementation group: 'org.cryptimeleon', name: 'math', version: '3.0.0'` to the `dependencies` section of your `build.gradle` file.
7979

8080
For example:
8181

@@ -85,7 +85,7 @@ repositories {
8585
}
8686
8787
dependencies {
88-
implementation group: 'org.cryptimeleon', name: 'math', version: '2.1.0'
88+
implementation group: 'org.cryptimeleon', name: 'math', version: '3.0.0'
8989
}
9090
```
9191

build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77
group = 'org.cryptimeleon'
88
archivesBaseName = project.name
99
boolean isRelease = project.hasProperty("release")
10-
version = '2.1.0' + (isRelease ? "" : "-SNAPSHOT")
10+
version = '3.0.0' + (isRelease ? "" : "-SNAPSHOT")
1111

1212
sourceCompatibility = 1.8
1313
targetCompatibility = 1.8
@@ -31,12 +31,12 @@ dependencies {
3131
'junit:junit:4.12'
3232
)
3333
testImplementation(
34-
'org.junit.jupiter:junit-jupiter-api:5.1.0',
35-
'org.junit.jupiter:junit-jupiter-params:5.1.0'
34+
'org.junit.jupiter:junit-jupiter-api:5.7.2',
35+
'org.junit.jupiter:junit-jupiter-params:5.7.2'
3636
)
3737
testRuntimeOnly(
38-
'org.junit.jupiter:junit-jupiter-engine:5.1.0',
39-
'org.junit.vintage:junit-vintage-engine:5.1.0'
38+
'org.junit.jupiter:junit-jupiter-engine:5.7.2',
39+
'org.junit.vintage:junit-vintage-engine:5.7.2'
4040
)
4141
}
4242

src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentConstantExpr.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public ExponentConstantExpr(BigInteger exponent) {
2121
}
2222

2323
public ExponentConstantExpr(Zn.ZnElement exponent) {
24-
this.exponent = exponent.getInteger();
24+
this.exponent = exponent.asInteger();
2525
}
2626

2727
public ExponentConstantExpr(long exponent) {

src/main/java/org/cryptimeleon/math/expressions/group/GroupPowExpr.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.cryptimeleon.math.expressions.Expression;
44
import org.cryptimeleon.math.expressions.Substitution;
5+
import org.cryptimeleon.math.expressions.exponent.ExponentEmptyExpr;
56
import org.cryptimeleon.math.expressions.exponent.ExponentExpr;
67
import org.cryptimeleon.math.expressions.exponent.ExponentSumExpr;
78
import org.cryptimeleon.math.structures.groups.GroupElement;
@@ -74,10 +75,16 @@ public GroupOpExpr linearize() throws IllegalArgumentException {
7475

7576
if (baseHasVariables) { //hence exponent doesn't
7677
GroupOpExpr baseLinear = base.linearize();
77-
return new GroupOpExpr(baseLinear.getLhs().pow(exponent), baseLinear.getRhs().pow(exponent));
78+
if (baseLinear.getLhs() instanceof GroupEmptyExpr) //base is linear already, hence this PowExpr is linear
79+
return new GroupOpExpr(new GroupEmptyExpr(base.getGroup()), this);
80+
else //split base into linear and constant part
81+
return new GroupOpExpr(baseLinear.getLhs().pow(exponent), baseLinear.getRhs().pow(exponent));
7882
} else { //exponent has variables, base doesn't.
7983
ExponentSumExpr exponentLinear = exponent.linearize();
80-
return new GroupOpExpr(base.pow(exponentLinear.getLhs()), base.pow(exponentLinear.getRhs()));
84+
if (exponentLinear.getLhs() instanceof ExponentEmptyExpr) //exponent is linear already, hence this PowExpr is linear
85+
return new GroupOpExpr(new GroupEmptyExpr(base.getGroup()), this);
86+
else //split exponent into linear and constant part
87+
return new GroupOpExpr(base.pow(exponentLinear.getLhs()), base.pow(exponentLinear.getRhs()));
8188
}
8289
}
8390

src/main/java/org/cryptimeleon/math/expressions/group/PairingExpr.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,16 @@ public GroupOpExpr linearize() throws IllegalArgumentException {
7373

7474
if (lhsHasVariables) { //hence rhs doesn't
7575
GroupOpExpr lhsLinearized = lhs.linearize();
76-
return new GroupOpExpr(new PairingExpr(map, lhsLinearized.getLhs(), rhs), new PairingExpr(map, lhsLinearized.getRhs(), rhs));
76+
if (lhsLinearized.getLhs() instanceof GroupEmptyExpr) //lhs is already linearized, so this PairingExpr is already linear
77+
return new GroupOpExpr(new GroupEmptyExpr(map.getGT()), this);
78+
else
79+
return new GroupOpExpr(new PairingExpr(map, lhsLinearized.getLhs(), rhs), new PairingExpr(map, lhsLinearized.getRhs(), rhs));
7780
} else { //lhs is constant, rhs isn't
7881
GroupOpExpr rhsLinearized = rhs.linearize();
79-
return new GroupOpExpr(new PairingExpr(map, lhs, rhsLinearized.getLhs()), new PairingExpr(map, lhs, rhsLinearized.getRhs()));
82+
if (rhsLinearized.getLhs() instanceof GroupEmptyExpr) //rhs is already linearized, so this PairingExpr is already linear
83+
return new GroupOpExpr(new GroupEmptyExpr(map.getGT()), this);
84+
else
85+
return new GroupOpExpr(new PairingExpr(map, lhs, rhsLinearized.getLhs()), new PairingExpr(map, lhs, rhsLinearized.getRhs()));
8086
}
8187
}
8288

@@ -87,7 +93,7 @@ public GroupOpExpr flatten(ExponentExpr exponent) {
8793
}
8894
else {
8995
BigInteger groupSize = getGroupOrderIfKnown();
90-
BigInteger exponentVal = groupSize == null ? exponent.evaluate() : exponent.evaluate(new Zn(groupSize)).getInteger();
96+
BigInteger exponentVal = groupSize == null ? exponent.evaluate() : exponent.evaluate(new Zn(groupSize)).asInteger();
9197
return new GroupOpExpr(evaluate().pow(exponentVal).expr(), new GroupEmptyExpr(map.getGT()));
9298
}
9399
}

src/main/java/org/cryptimeleon/math/hash/impl/VariableOutputLengthHashFunction.java

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.cryptimeleon.math.serialization.annotations.Represented;
88

99
import java.nio.ByteBuffer;
10+
import java.util.Objects;
1011

1112
/**
1213
* A hash function with variable output length.
@@ -53,7 +54,7 @@ public HashFunction getInnerHashFunction() {
5354
* Initializes this instance using a specific base hash function and output length.
5455
*
5556
* @param hashFunction the base hash function
56-
* @param outputLength thedesired output length of this hash function in number of bytes
57+
* @param outputLength the desired output length of this hash function in number of bytes
5758
*/
5859
public VariableOutputLengthHashFunction(HashFunction hashFunction, int outputLength) {
5960
innerFunction = hashFunction;
@@ -85,7 +86,6 @@ public byte[] hash(byte[] x) {
8586
// given a collision (x,x'), either innerFunction(0||x) = innerFunction(0||x')
8687
// or innerFunction(1 || innerFunction(0||x)) = innerFunction(1 || innerFunction(0||x')).
8788
// We have found a collision in both cases.
88-
8989
byte[] result = new byte[outputLength];
9090
int bytesFilled = 0;
9191
byte[] y = innerFunction.hash(prependInt(0, x));
@@ -121,11 +121,7 @@ public int getOutputLength() {
121121

122122
@Override
123123
public int hashCode() {
124-
final int prime = 31;
125-
int result = 1;
126-
result = prime * result + ((innerFunction == null) ? 0 : innerFunction.hashCode());
127-
result = prime * result + outputLength;
128-
return result;
124+
return Objects.hash(innerFunction, outputLength);
129125
}
130126

131127
@Override
@@ -136,15 +132,8 @@ public boolean equals(Object obj) {
136132
return false;
137133
if (getClass() != obj.getClass())
138134
return false;
139-
VariableOutputLengthHashFunction other = (VariableOutputLengthHashFunction) obj;
140-
if (innerFunction == null) {
141-
if (other.innerFunction != null)
142-
return false;
143-
} else if (!innerFunction.equals(other.innerFunction))
144-
return false;
145-
if (outputLength != other.outputLength)
146-
return false;
147-
return true;
135+
VariableOutputLengthHashFunction that = (VariableOutputLengthHashFunction) obj;
136+
return Objects.equals(innerFunction, that.innerFunction) &&
137+
Objects.equals(outputLength, that.outputLength);
148138
}
149-
150139
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package org.cryptimeleon.math.structures.groups.debug;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.LinkedList;
6+
import java.util.List;
7+
import java.util.concurrent.atomic.AtomicLong;
8+
import java.util.concurrent.locks.Lock;
9+
import java.util.concurrent.locks.ReentrantLock;
10+
11+
/**
12+
* Stores group operation data.
13+
* <p>
14+
* Operations are thread-safe, meaning that all increment and getter methods are implemented automically,
15+
* and the multi-exponentiation term number list is protected via a lock.
16+
*/
17+
public class CountingBucket {
18+
19+
/**
20+
* The counted number of inversions.
21+
*/
22+
final AtomicLong numInversions;
23+
24+
/**
25+
* The counted number of operations.
26+
* Squarings are not considered in the group operation counter.
27+
*/
28+
final AtomicLong numOps;
29+
30+
/**
31+
* The counted number of squarings.
32+
*/
33+
final AtomicLong numSquarings;
34+
35+
/**
36+
* The counted number of exponentiations.
37+
*/
38+
final AtomicLong numExps;
39+
40+
/**
41+
* Number of retrieved representations for elements of this group.
42+
*/
43+
final AtomicLong numRetrievedRepresentations;
44+
45+
/**
46+
* Contains number of terms for each multi-exponentiation performed.
47+
*/
48+
private final List<Integer> multiExpTermNumbers;
49+
50+
private final Lock multiExpTermNumbersLock;
51+
52+
public CountingBucket() {
53+
this.numInversions = new AtomicLong();
54+
this.numOps = new AtomicLong();
55+
this.numSquarings = new AtomicLong();
56+
this.numExps = new AtomicLong();
57+
this.numRetrievedRepresentations = new AtomicLong();
58+
this.multiExpTermNumbers = new ArrayList<>();
59+
this.multiExpTermNumbersLock = new ReentrantLock();
60+
}
61+
62+
public void incrementNumOps() {
63+
numOps.incrementAndGet();
64+
}
65+
66+
public void incrementNumInversions() {
67+
numInversions.incrementAndGet();
68+
}
69+
70+
public void incrementNumSquarings() {
71+
numSquarings.incrementAndGet();
72+
}
73+
74+
public void incrementNumExps() {
75+
numExps.incrementAndGet();
76+
}
77+
78+
/**
79+
* Tracks the fact that a multi-exponentiation with the given number of terms was done.
80+
* @param numTerms the number of terms (bases) in the multi-exponentiation
81+
*/
82+
public void addMultiExpBaseNumber(int numTerms) {
83+
multiExpTermNumbersLock.lock();
84+
try {
85+
if (numTerms > 1) {
86+
multiExpTermNumbers.add(numTerms);
87+
}
88+
} finally {
89+
multiExpTermNumbersLock.unlock();
90+
}
91+
}
92+
93+
/**
94+
* Adds the given list of multi-exponentiation term numbers to this bucket.
95+
* @param newTerms the new terms to add to this bucket
96+
*/
97+
public void addAllMultiExpBaseNumbers(List<Integer> newTerms) {
98+
multiExpTermNumbersLock.lock();
99+
try {
100+
multiExpTermNumbers.addAll(newTerms);
101+
} finally {
102+
multiExpTermNumbersLock.unlock();
103+
}
104+
}
105+
106+
void incrementNumRetrievedRepresentations() {
107+
numRetrievedRepresentations.incrementAndGet();
108+
}
109+
110+
public long getNumInversions() {
111+
return numInversions.get();
112+
}
113+
114+
public long getNumOps() {
115+
return numOps.get();
116+
}
117+
118+
public long getNumSquarings() {
119+
return numSquarings.get();
120+
}
121+
122+
public long getNumExps() {
123+
return numExps.get();
124+
}
125+
126+
public long getNumRetrievedRepresentations() {
127+
return numRetrievedRepresentations.get();
128+
}
129+
130+
/**
131+
* Returns an immutable copy of the list storing the multi-exponentiation term numbers.
132+
* This list contains the number of exponentiations in each multi-exponentiation that has been calculated.
133+
*/
134+
public List<Integer> getMultiExpTermNumbers() {
135+
return Collections.unmodifiableList(multiExpTermNumbers);
136+
}
137+
138+
/**
139+
* Resets all counters.
140+
*/
141+
public void resetCounters() {
142+
resetOpsCounter();
143+
resetInversionsCounter();
144+
resetSquaringsCounter();
145+
resetExpsCounter();
146+
resetMultiExpTermNumbers();
147+
resetRetrievedRepresentationsCounter();
148+
}
149+
150+
protected void resetOpsCounter() {
151+
numOps.set(0);
152+
}
153+
154+
protected void resetInversionsCounter() {
155+
numInversions.set(0);
156+
}
157+
158+
protected void resetSquaringsCounter() {
159+
numSquarings.set(0);
160+
}
161+
162+
protected void resetExpsCounter() { numExps.set(0); }
163+
164+
protected void resetMultiExpTermNumbers() {
165+
multiExpTermNumbersLock.lock();
166+
try {
167+
multiExpTermNumbers.clear();
168+
} finally {
169+
multiExpTermNumbersLock.unlock();
170+
}
171+
}
172+
173+
protected void resetRetrievedRepresentationsCounter() {
174+
numRetrievedRepresentations.set(0);
175+
}
176+
177+
protected boolean isEmpty() {
178+
return numOps.get() == 0 && numInversions.get() == 0 && numSquarings.get() == 0 && numExps.get() == 0
179+
&& getMultiExpTermNumbers().isEmpty() && numRetrievedRepresentations.get() == 0;
180+
}
181+
}

0 commit comments

Comments
 (0)