Skip to content

Commit

Permalink
Merge pull request #137 from cryptimeleon/develop
Browse files Browse the repository at this point in the history
Release v3.0.0
  • Loading branch information
feidens authored Sep 17, 2021
2 parents 2250b1a + 65d16d5 commit 462090c
Show file tree
Hide file tree
Showing 48 changed files with 2,754 additions and 713 deletions.
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]


## [3.0.0]

### Changed
- `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.
- Reduce collisions for `Zn#injectiveValueOf`

### Added
- Add lazy and naive wrappers around `Secp256k1` curve, and make curve implementation package-private

### Fixed
- Fixed [issue](https://github.com/cryptimeleon/math/pull/134) where exceptions during group computations could hang up the whole applications without surfacing the exception.

## [2.1.0]

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

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


[Unreleased]: https://github.com/cryptimeleon/math/compare/v2.1.0...HEAD
[Unreleased]: https://github.com/cryptimeleon/math/compare/v3.0.0...HEAD
[3.0.0]: https://github.com/cryptimeleon/math/compare/v2.1.0...v3.0.0
[2.1.0]: https://github.com/cryptimeleon/math/compare/v2.0.0...v2.1.0
[2.0.0]: https://github.com/cryptimeleon/math/compare/v1.0.0...v2.0.0
[1.0.0]: https://github.com/cryptimeleon/math/releases/tag/v1.0.0
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ To add the newest Math version as a dependency, add this to your project's POM:
<dependency>
<groupId>org.cryptimeleon</groupId>
<artifactId>math</artifactId>
<version>2.1.0</version>
<version>3.0.0</version>
</dependency>
```

### Installation With Gradle

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

For example:

Expand All @@ -85,7 +85,7 @@ repositories {
}
dependencies {
implementation group: 'org.cryptimeleon', name: 'math', version: '2.1.0'
implementation group: 'org.cryptimeleon', name: 'math', version: '3.0.0'
}
```

Expand Down
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
group = 'org.cryptimeleon'
archivesBaseName = project.name
boolean isRelease = project.hasProperty("release")
version = '2.1.0' + (isRelease ? "" : "-SNAPSHOT")
version = '3.0.0' + (isRelease ? "" : "-SNAPSHOT")

sourceCompatibility = 1.8
targetCompatibility = 1.8
Expand All @@ -31,12 +31,12 @@ dependencies {
'junit:junit:4.12'
)
testImplementation(
'org.junit.jupiter:junit-jupiter-api:5.1.0',
'org.junit.jupiter:junit-jupiter-params:5.1.0'
'org.junit.jupiter:junit-jupiter-api:5.7.2',
'org.junit.jupiter:junit-jupiter-params:5.7.2'
)
testRuntimeOnly(
'org.junit.jupiter:junit-jupiter-engine:5.1.0',
'org.junit.vintage:junit-vintage-engine:5.1.0'
'org.junit.jupiter:junit-jupiter-engine:5.7.2',
'org.junit.vintage:junit-vintage-engine:5.7.2'
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ExponentConstantExpr(BigInteger exponent) {
}

public ExponentConstantExpr(Zn.ZnElement exponent) {
this.exponent = exponent.getInteger();
this.exponent = exponent.asInteger();
}

public ExponentConstantExpr(long exponent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.cryptimeleon.math.expressions.Expression;
import org.cryptimeleon.math.expressions.Substitution;
import org.cryptimeleon.math.expressions.exponent.ExponentEmptyExpr;
import org.cryptimeleon.math.expressions.exponent.ExponentExpr;
import org.cryptimeleon.math.expressions.exponent.ExponentSumExpr;
import org.cryptimeleon.math.structures.groups.GroupElement;
Expand Down Expand Up @@ -74,10 +75,16 @@ public GroupOpExpr linearize() throws IllegalArgumentException {

if (baseHasVariables) { //hence exponent doesn't
GroupOpExpr baseLinear = base.linearize();
return new GroupOpExpr(baseLinear.getLhs().pow(exponent), baseLinear.getRhs().pow(exponent));
if (baseLinear.getLhs() instanceof GroupEmptyExpr) //base is linear already, hence this PowExpr is linear
return new GroupOpExpr(new GroupEmptyExpr(base.getGroup()), this);
else //split base into linear and constant part
return new GroupOpExpr(baseLinear.getLhs().pow(exponent), baseLinear.getRhs().pow(exponent));
} else { //exponent has variables, base doesn't.
ExponentSumExpr exponentLinear = exponent.linearize();
return new GroupOpExpr(base.pow(exponentLinear.getLhs()), base.pow(exponentLinear.getRhs()));
if (exponentLinear.getLhs() instanceof ExponentEmptyExpr) //exponent is linear already, hence this PowExpr is linear
return new GroupOpExpr(new GroupEmptyExpr(base.getGroup()), this);
else //split exponent into linear and constant part
return new GroupOpExpr(base.pow(exponentLinear.getLhs()), base.pow(exponentLinear.getRhs()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,16 @@ public GroupOpExpr linearize() throws IllegalArgumentException {

if (lhsHasVariables) { //hence rhs doesn't
GroupOpExpr lhsLinearized = lhs.linearize();
return new GroupOpExpr(new PairingExpr(map, lhsLinearized.getLhs(), rhs), new PairingExpr(map, lhsLinearized.getRhs(), rhs));
if (lhsLinearized.getLhs() instanceof GroupEmptyExpr) //lhs is already linearized, so this PairingExpr is already linear
return new GroupOpExpr(new GroupEmptyExpr(map.getGT()), this);
else
return new GroupOpExpr(new PairingExpr(map, lhsLinearized.getLhs(), rhs), new PairingExpr(map, lhsLinearized.getRhs(), rhs));
} else { //lhs is constant, rhs isn't
GroupOpExpr rhsLinearized = rhs.linearize();
return new GroupOpExpr(new PairingExpr(map, lhs, rhsLinearized.getLhs()), new PairingExpr(map, lhs, rhsLinearized.getRhs()));
if (rhsLinearized.getLhs() instanceof GroupEmptyExpr) //rhs is already linearized, so this PairingExpr is already linear
return new GroupOpExpr(new GroupEmptyExpr(map.getGT()), this);
else
return new GroupOpExpr(new PairingExpr(map, lhs, rhsLinearized.getLhs()), new PairingExpr(map, lhs, rhsLinearized.getRhs()));
}
}

Expand All @@ -87,7 +93,7 @@ public GroupOpExpr flatten(ExponentExpr exponent) {
}
else {
BigInteger groupSize = getGroupOrderIfKnown();
BigInteger exponentVal = groupSize == null ? exponent.evaluate() : exponent.evaluate(new Zn(groupSize)).getInteger();
BigInteger exponentVal = groupSize == null ? exponent.evaluate() : exponent.evaluate(new Zn(groupSize)).asInteger();
return new GroupOpExpr(evaluate().pow(exponentVal).expr(), new GroupEmptyExpr(map.getGT()));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.cryptimeleon.math.serialization.annotations.Represented;

import java.nio.ByteBuffer;
import java.util.Objects;

/**
* A hash function with variable output length.
Expand Down Expand Up @@ -53,7 +54,7 @@ public HashFunction getInnerHashFunction() {
* Initializes this instance using a specific base hash function and output length.
*
* @param hashFunction the base hash function
* @param outputLength thedesired output length of this hash function in number of bytes
* @param outputLength the desired output length of this hash function in number of bytes
*/
public VariableOutputLengthHashFunction(HashFunction hashFunction, int outputLength) {
innerFunction = hashFunction;
Expand Down Expand Up @@ -85,7 +86,6 @@ public byte[] hash(byte[] x) {
// given a collision (x,x'), either innerFunction(0||x) = innerFunction(0||x')
// or innerFunction(1 || innerFunction(0||x)) = innerFunction(1 || innerFunction(0||x')).
// We have found a collision in both cases.

byte[] result = new byte[outputLength];
int bytesFilled = 0;
byte[] y = innerFunction.hash(prependInt(0, x));
Expand Down Expand Up @@ -121,11 +121,7 @@ public int getOutputLength() {

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((innerFunction == null) ? 0 : innerFunction.hashCode());
result = prime * result + outputLength;
return result;
return Objects.hash(innerFunction, outputLength);
}

@Override
Expand All @@ -136,15 +132,8 @@ public boolean equals(Object obj) {
return false;
if (getClass() != obj.getClass())
return false;
VariableOutputLengthHashFunction other = (VariableOutputLengthHashFunction) obj;
if (innerFunction == null) {
if (other.innerFunction != null)
return false;
} else if (!innerFunction.equals(other.innerFunction))
return false;
if (outputLength != other.outputLength)
return false;
return true;
VariableOutputLengthHashFunction that = (VariableOutputLengthHashFunction) obj;
return Objects.equals(innerFunction, that.innerFunction) &&
Objects.equals(outputLength, that.outputLength);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package org.cryptimeleon.math.structures.groups.debug;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* Stores group operation data.
* <p>
* Operations are thread-safe, meaning that all increment and getter methods are implemented automically,
* and the multi-exponentiation term number list is protected via a lock.
*/
public class CountingBucket {

/**
* The counted number of inversions.
*/
final AtomicLong numInversions;

/**
* The counted number of operations.
* Squarings are not considered in the group operation counter.
*/
final AtomicLong numOps;

/**
* The counted number of squarings.
*/
final AtomicLong numSquarings;

/**
* The counted number of exponentiations.
*/
final AtomicLong numExps;

/**
* Number of retrieved representations for elements of this group.
*/
final AtomicLong numRetrievedRepresentations;

/**
* Contains number of terms for each multi-exponentiation performed.
*/
private final List<Integer> multiExpTermNumbers;

private final Lock multiExpTermNumbersLock;

public CountingBucket() {
this.numInversions = new AtomicLong();
this.numOps = new AtomicLong();
this.numSquarings = new AtomicLong();
this.numExps = new AtomicLong();
this.numRetrievedRepresentations = new AtomicLong();
this.multiExpTermNumbers = new ArrayList<>();
this.multiExpTermNumbersLock = new ReentrantLock();
}

public void incrementNumOps() {
numOps.incrementAndGet();
}

public void incrementNumInversions() {
numInversions.incrementAndGet();
}

public void incrementNumSquarings() {
numSquarings.incrementAndGet();
}

public void incrementNumExps() {
numExps.incrementAndGet();
}

/**
* Tracks the fact that a multi-exponentiation with the given number of terms was done.
* @param numTerms the number of terms (bases) in the multi-exponentiation
*/
public void addMultiExpBaseNumber(int numTerms) {
multiExpTermNumbersLock.lock();
try {
if (numTerms > 1) {
multiExpTermNumbers.add(numTerms);
}
} finally {
multiExpTermNumbersLock.unlock();
}
}

/**
* Adds the given list of multi-exponentiation term numbers to this bucket.
* @param newTerms the new terms to add to this bucket
*/
public void addAllMultiExpBaseNumbers(List<Integer> newTerms) {
multiExpTermNumbersLock.lock();
try {
multiExpTermNumbers.addAll(newTerms);
} finally {
multiExpTermNumbersLock.unlock();
}
}

void incrementNumRetrievedRepresentations() {
numRetrievedRepresentations.incrementAndGet();
}

public long getNumInversions() {
return numInversions.get();
}

public long getNumOps() {
return numOps.get();
}

public long getNumSquarings() {
return numSquarings.get();
}

public long getNumExps() {
return numExps.get();
}

public long getNumRetrievedRepresentations() {
return numRetrievedRepresentations.get();
}

/**
* Returns an immutable copy of the list storing the multi-exponentiation term numbers.
* This list contains the number of exponentiations in each multi-exponentiation that has been calculated.
*/
public List<Integer> getMultiExpTermNumbers() {
return Collections.unmodifiableList(multiExpTermNumbers);
}

/**
* Resets all counters.
*/
public void resetCounters() {
resetOpsCounter();
resetInversionsCounter();
resetSquaringsCounter();
resetExpsCounter();
resetMultiExpTermNumbers();
resetRetrievedRepresentationsCounter();
}

protected void resetOpsCounter() {
numOps.set(0);
}

protected void resetInversionsCounter() {
numInversions.set(0);
}

protected void resetSquaringsCounter() {
numSquarings.set(0);
}

protected void resetExpsCounter() { numExps.set(0); }

protected void resetMultiExpTermNumbers() {
multiExpTermNumbersLock.lock();
try {
multiExpTermNumbers.clear();
} finally {
multiExpTermNumbersLock.unlock();
}
}

protected void resetRetrievedRepresentationsCounter() {
numRetrievedRepresentations.set(0);
}

protected boolean isEmpty() {
return numOps.get() == 0 && numInversions.get() == 0 && numSquarings.get() == 0 && numExps.get() == 0
&& getMultiExpTermNumbers().isEmpty() && numRetrievedRepresentations.get() == 0;
}
}
Loading

0 comments on commit 462090c

Please sign in to comment.