diff --git a/.github/workflows/android.yaml b/.github/workflows/android.yaml new file mode 100644 index 00000000..f69a9076 --- /dev/null +++ b/.github/workflows/android.yaml @@ -0,0 +1,31 @@ +name: Android CI + +on: + push: + branches-ignore: + - main + - 'release/**' + # Nightly builds to ensure dependencies don't break anything + schedule: + - cron: '0 0 * * *' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Gradle + run: ./gradlew :build + android: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Run tests on emulator + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 28 + script: ./gradlew android-test:connectedAndroidTest -Pandroid.useAndroidX=true --info diff --git a/.github/workflows/ci.yaml b/.github/workflows/dev-ci.yaml similarity index 50% rename from .github/workflows/ci.yaml rename to .github/workflows/dev-ci.yaml index 67597e67..67e38963 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/dev-ci.yaml @@ -1,6 +1,13 @@ -name: Java CI +name: Development Java CI -on: push +on: + push: + branches-ignore: + - main + - 'release/**' + # Nightly builds to ensure dependencies don't break anything + schedule: + - cron: '0 0 * * *' jobs: build: @@ -12,4 +19,5 @@ jobs: with: java-version: 1.8 - name: Build with Gradle - run: ./gradlew build -PcheckoutIfCloned=true \ No newline at end of file + run: ./gradlew :build + diff --git a/.github/workflows/main-ci.yaml b/.github/workflows/main-ci.yaml new file mode 100644 index 00000000..ef708f41 --- /dev/null +++ b/.github/workflows/main-ci.yaml @@ -0,0 +1,28 @@ +name: Main Java CI + +on: + push: + branches: + - main + - 'release/**' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Gradle + run: ./gradlew :build -Prelease + android: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Run tests on emulator + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 28 + script: ./gradlew android-test:connectedAndroidTest -Prelease -Pandroid.useAndroidX=true --info diff --git a/.github/workflows/scheduled-main-java-ci.yaml b/.github/workflows/scheduled-main-java-ci.yaml new file mode 100644 index 00000000..3e173fa7 --- /dev/null +++ b/.github/workflows/scheduled-main-java-ci.yaml @@ -0,0 +1,20 @@ +name: Scheduled Main Java CI + +on: + # Nightly builds to ensure dependencies don't break anything + schedule: + - cron: '0 0 * * *' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: main # need to specify branch else it will check out develop + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Gradle + run: ./gradlew :build -Prelease diff --git a/.github/workflows/pub.yaml b/.github/workflows/tagget_release.yaml similarity index 77% rename from .github/workflows/pub.yaml rename to .github/workflows/tagget_release.yaml index 7932685b..69316824 100644 --- a/.github/workflows/pub.yaml +++ b/.github/workflows/tagget_release.yaml @@ -1,9 +1,7 @@ -name: Maven publishing +name: Tagget release on: push: - branches: - - main tags: - v[1-9]+.[0-9]+.[0-9]+ jobs: @@ -16,16 +14,19 @@ jobs: with: java-version: 1.8 - name: Publish to the Maven Central Repository - run: ./gradlew publish -PcheckoutIfCloned -Prelease + run: ./gradlew :publish -Prelease env: OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }} ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }} - - uses: "marvinpinto/action-automatic-releases@latest" + - name: Github release + uses: "marvinpinto/action-automatic-releases@latest" with: repo_token: "${{ secrets.GITHUB_TOKEN }}" prerelease: false + draft: false files: | LICENSE build/libs/*.jar + id: "automatic_releases" diff --git a/.gitignore b/.gitignore index d74445de..803c8efa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ build/** +android-test/build/** .gradle/** out/** .idea/** .composite-enable gradle.properties +local.properties \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d6637e04..4780b4c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- Additional operator overload methods added to `ExponentExpr` +- `BasicBilinearGroup` wrappers for the implemented bilinear groups +- Convenience methods for the vector classes +- `square`, `div` and `valueOf` convenience methods for `Zn` and `Zp` classes +- PRF classes from Craco now are part of Math +- `ByteArrayImpl`, a byte array implementation + +### Changed +- Renamed "counting" group classes and package to "debug" +- Made supersingular and Barreto-Naehrig implementation classes package-private (except those that are relevant to the user) +- Made internal lazy group classes package-private +- Adjusted some tests to work with the new package-private classes +- Made representation handler classes package-private and moved the classes up a package +- Made ring group impl classes package-private and moved inv and neg cost estimation to the `Ring` interface +- Improved performance of finite field multiplication + +### Fixed +- Fixed `decomposeIntoDigits` method of `IntegerRing` + +## [1.0.0] - 2021-03-01 + +### Added +- Initial release + + +[Unreleased]: https://github.com/cryptimeleon/math/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/cryptimeleon/math/releases/tag/v1.0.0 + diff --git a/DEVELOPER.md b/DEVELOPER.md new file mode 100644 index 00000000..31c0570e --- /dev/null +++ b/DEVELOPER.md @@ -0,0 +1,9 @@ +This Gradle project consists of two sub-projects. +The root project is the Math library itself. +The `android-test` sub-project is only used to run the library's tests on Android. +For that purpose it contains an Android-specific build file. + +Since there are multiple sub-projects, you will need to prefix Gradle commands with a colon (`:`) if you want them to run only for the Math library and not the Android sub-project. +For example, instead of `./gradlew build` use `./gradlew :build` to build the Math library. +The former will fail since the android sub-project is not configured to be actually buildable. +See [here](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html) for more information on how multi-project builds work. diff --git a/README.md b/README.md index f4e2d03c..a4b61e98 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ -![Build Status](https://github.com/cryptimeleon/math/workflows/Java%20CI/badge.svg) +![Build Status](https://github.com/cryptimeleon/math/workflows/Development%20Java%20CI/badge.svg) +![Build Status](https://github.com/cryptimeleon/math/workflows/Main%20Java%20CI/badge.svg) +![Build Status](https://github.com/cryptimeleon/math/workflows/Scheduled%20Main%20Java%20CI/badge.svg) +![Build Status](https://github.com/cryptimeleon/math/workflows/Android%20CI/badge.svg) ## Math The Cryptimeleon Math library provides the mathematical foundation for the other Cryptimeleon libraries. -It provides basics such as mathematical groups, rings and fields, e.g. Zn, as well as implementations of cryptographic pairings. -Furthermore, it provides serialization support for the implemented structures. +It implements basics such as mathematical groups, rings and fields, e.g. Zn, as well as implementations of cryptographic pairings. +Furthermore, it offers serialization support for the implemented structures. ## Security Disclaimer **WARNING: This library is meant to be used for prototyping and as a research tool *only*. It has not been sufficiently vetted for use in security-critical production environments. All implementations are to be considered experimental.** diff --git a/android-test/build.gradle b/android-test/build.gradle new file mode 100644 index 00000000..c4ee2d0e --- /dev/null +++ b/android-test/build.gradle @@ -0,0 +1,97 @@ +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.2.1' + classpath("de.mannodermaus.gradle.plugins:android-junit5:1.7.1.1") + } +} + +apply plugin: 'com.android.library' +apply plugin: "de.mannodermaus.android-junit5" + +android { + compileSdkVersion 30 + defaultConfig { + minSdkVersion 28 + targetSdkVersion 30 + + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + // JUnit 5 support for instrumentation tests + testInstrumentationRunnerArgument "runnerBuilder", "de.mannodermaus.junit5.AndroidJUnit5Builder" + } + + // make the android-test subproject just reuse the math stuff + sourceSets { + main { + java.srcDirs = ["../src/main/java"] + } + + // unit tests. Run via test task + test { + java.srcDirs = ["../src/test/java"] + } + + androidTest { + java.srcDirs = ["../src/test/java"] + } + } + + compileOptions { + setSourceCompatibility(JavaVersion.VERSION_1_8) + setTargetCompatibility(JavaVersion.VERSION_1_8) + } + + testOptions { + unitTests { + all { + useJUnitPlatform() + maxParallelForks 4 + //we want display the following test events + testLogging { + events "PASSED", "STARTED", "FAILED", "SKIPPED" + } + afterSuite { desc, result -> + if (!desc.parent) { // will match the outermost suite + def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" + def startItem = '| ', endItem = ' |' + def repeatLength = startItem.length() + output.length() + endItem.length() + println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength)) + } + } + } + } + } +} + +repositories { + mavenCentral() + google() +} + +dependencies { + implementation group: 'com.googlecode.json-simple', name: 'json-simple', version:'1.1' + implementation group: 'org.reflections', name: 'reflections', version:'0.9.10' + + // (Required) Writing and executing Unit Tests on the JUnit Platform + testImplementation "org.junit.jupiter:junit-jupiter-api:5.7.1" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.7.1" + + // (Optional) If you need "Parameterized Tests" + testImplementation "org.junit.jupiter:junit-jupiter-params:5.7.1" + + // (Optional) If you also have JUnit 4-based tests + testImplementation "junit:junit:4.13" + testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.7.1" + + // Instrumentation test stuff + androidTestImplementation "androidx.test:runner:1.3.0" + androidTestImplementation "org.junit.jupiter:junit-jupiter-api:5.7.1" + androidTestImplementation "org.junit.jupiter:junit-jupiter-params:5.7.1" + + androidTestImplementation "de.mannodermaus.junit5:android-test-core:1.2.2" + androidTestRuntimeOnly "de.mannodermaus.junit5:android-test-runner:1.2.2" +} diff --git a/android-test/src/main/AndroidManifest.xml b/android-test/src/main/AndroidManifest.xml new file mode 100644 index 00000000..fe2b49d6 --- /dev/null +++ b/android-test/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 01503d86..c9497d51 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,7 @@ plugins { group = 'org.cryptimeleon' archivesBaseName = project.name boolean isRelease = project.hasProperty("release") -version = '1.0.0' + (isRelease ? "" : "-SNAPSHOT") - +version = '2.0.0' + (isRelease ? "" : "-SNAPSHOT") sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -16,12 +15,9 @@ tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } - - repositories { mavenLocal() mavenCentral() - jcenter() } dependencies { @@ -44,7 +40,6 @@ dependencies { ) } - test { useJUnitPlatform() maxParallelForks 4 diff --git a/settings.gradle b/settings.gradle index fee1d5c8..4b8bc002 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,3 @@ rootProject.name = 'math' + +include 'android-test' diff --git a/src/main/java/org/cryptimeleon/math/expressions/bool/ExponentEqualityExpr.java b/src/main/java/org/cryptimeleon/math/expressions/bool/ExponentEqualityExpr.java index 2f9216ea..f19a6240 100644 --- a/src/main/java/org/cryptimeleon/math/expressions/bool/ExponentEqualityExpr.java +++ b/src/main/java/org/cryptimeleon/math/expressions/bool/ExponentEqualityExpr.java @@ -27,7 +27,7 @@ public ExponentEqualityExpr(ExponentExpr lhs, ExponentExpr rhs) { } @Override - public BooleanExpression substitute(Substitution substitutions) { + public ExponentEqualityExpr substitute(Substitution substitutions) { return lhs.substitute(substitutions).isEqualTo(rhs.substitute(substitutions)); } diff --git a/src/main/java/org/cryptimeleon/math/expressions/bool/GroupEqualityExpr.java b/src/main/java/org/cryptimeleon/math/expressions/bool/GroupEqualityExpr.java index d7f556a4..71fe7c08 100644 --- a/src/main/java/org/cryptimeleon/math/expressions/bool/GroupEqualityExpr.java +++ b/src/main/java/org/cryptimeleon/math/expressions/bool/GroupEqualityExpr.java @@ -46,7 +46,7 @@ public Group getGroup() { } @Override - public BooleanExpression substitute(Substitution substitutions) { + public GroupEqualityExpr substitute(Substitution substitutions) { return lhs.substitute(substitutions).isEqualTo(rhs.substitute(substitutions)); } diff --git a/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentExpr.java b/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentExpr.java index 3a4b1e73..4c162e83 100644 --- a/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentExpr.java +++ b/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentExpr.java @@ -77,6 +77,9 @@ default ExponentExpr add(ExponentExpr other) { return new ExponentSumExpr(this, other); } + /** + * Adds the given constant to this expression. + */ default ExponentExpr add(Zn.ZnElement other) { return add(other.asExponentExpression()); } @@ -90,6 +93,20 @@ default ExponentExpr add(String other) { return add(new BasicNamedExponentVariableExpr(other)); } + /** + * Adds the given constant to this expression. + */ + default ExponentExpr add(BigInteger other) { + return add(new ExponentConstantExpr(other)); + } + + /** + * Adds the given constant to this expression. + */ + default ExponentExpr add(long other) { + return add(BigInteger.valueOf(other)); + } + /** * Subtracts the given expression from this expression. * Realized by adding the negation. @@ -100,6 +117,9 @@ default ExponentExpr sub(ExponentExpr other) { return add(other.negate()); } + /** + * Subtracts the given constant from this expression. + */ default ExponentExpr sub(Zn.ZnElement other) { return sub(other.asExponentExpression()); } @@ -114,6 +134,20 @@ default ExponentExpr sub(String other) { return sub(new BasicNamedExponentVariableExpr(other)); } + /** + * Subtracts the given constant from this expression. + */ + default ExponentExpr sub(BigInteger other) { + return sub(new ExponentConstantExpr(other)); + } + + /** + * Adds the given constant to this expression. + */ + default ExponentExpr sub(long other) { + return sub(BigInteger.valueOf(other)); + } + /** * Multiplies this expression with the given expression. * @param other the factor @@ -132,6 +166,11 @@ default ExponentExpr mul(BigInteger other) { return mul(new ExponentConstantExpr(other)); } + /** + * Multiplies this expression with the given constant. + * @param other the factor + * @return the result of multiplication + */ default ExponentExpr mul(RingElement other) { return mul(other.asInteger()); } /** diff --git a/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentPowExpr.java b/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentPowExpr.java index d83c96f5..7ee011bf 100644 --- a/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentPowExpr.java +++ b/src/main/java/org/cryptimeleon/math/expressions/exponent/ExponentPowExpr.java @@ -2,6 +2,7 @@ import org.cryptimeleon.math.expressions.Expression; import org.cryptimeleon.math.expressions.Substitution; +import org.cryptimeleon.math.misc.BigIntegerTools; import org.cryptimeleon.math.structures.rings.zn.Zn; import java.math.BigInteger; @@ -42,7 +43,9 @@ public ExponentExpr getExponent() { @Override public BigInteger evaluate() { - return base.evaluate().pow(exponent.evaluate().intValueExact()); + return base.evaluate().pow( + BigIntegerTools.getExactInt(exponent.evaluate()) + ); } @Override diff --git a/src/main/java/org/cryptimeleon/math/misc/BigIntegerTools.java b/src/main/java/org/cryptimeleon/math/misc/BigIntegerTools.java new file mode 100644 index 00000000..2f40c4c4 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/misc/BigIntegerTools.java @@ -0,0 +1,23 @@ +package org.cryptimeleon.math.misc; + +import java.math.BigInteger; + +public abstract class BigIntegerTools { + + /** + * Returns the integer value corresponding to the given {@link BigInteger}, throwing a {@link ArithmeticException} + * if the value is out of bounds. + *

+ * Implements the {@code intValueExact} method of {@code BigInteger} that is missing in the Android Sdk. + * @param num the {@code BigInteger} to convert + * @return the integer with the same value as {@code num} + * + * @throws ArithmeticException if the value of {@code num} is outside the supported integer values + */ + public static Integer getExactInt(BigInteger num) { + if (num.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0 + || num.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0) + throw new ArithmeticException("Integer value of BigInteger " + num + " is out of integer range"); + return num.intValue(); + } +} diff --git a/src/main/java/org/cryptimeleon/math/misc/ByteArrayImpl.java b/src/main/java/org/cryptimeleon/math/misc/ByteArrayImpl.java new file mode 100644 index 00000000..3cb739f2 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/misc/ByteArrayImpl.java @@ -0,0 +1,134 @@ +package org.cryptimeleon.math.misc; + +import org.cryptimeleon.math.hash.ByteAccumulator; +import org.cryptimeleon.math.prf.PrfImage; +import org.cryptimeleon.math.prf.PrfKey; +import org.cryptimeleon.math.prf.PrfPreimage; +import org.cryptimeleon.math.random.RandomGenerator; +import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.serialization.annotations.ReprUtil; +import org.cryptimeleon.math.serialization.annotations.Represented; + +import java.util.Arrays; + +public class ByteArrayImpl implements PrfKey, PrfPreimage, PrfImage { + + @Represented + protected byte[] data; + + public ByteArrayImpl(byte[] bytes) { + this.data = bytes; + } + + public ByteArrayImpl(Representation repr) { + new ReprUtil(this).deserialize(repr); + } + + /** + * Creates a new {@code ByteArrayImpl} instance filled with {@code numberBytes} bytes of randomness + * + * @param numberBytes number of random bytes / length of resulting ByteArrayImplementation + */ + public static ByteArrayImpl fromRandom(int numberBytes) { + return new ByteArrayImpl(RandomGenerator.getRandomBytes(numberBytes)); + } + + public byte[] getData() { + return data; + } + + /** + * Create new byte array as concatenation of {@code this} with {@code a}. + * + * @param a the array to append + * @return the result of concatenation + */ + public ByteArrayImpl append(ByteArrayImpl a) { + byte[] result = new byte[data.length + a.getData().length]; + System.arraycopy(data, 0, result, 0, data.length); + System.arraycopy(a.data, 0, result, data.length, a.getData().length); + return new ByteArrayImpl(result); + } + + /** + * Returns an array containing the designated part of this byte array, meaning that + * {@code returned[i] = this[firstIndex+i]}. + * @param firstIndex first (byte) index that will be copied to the result + * @param length the number of bytes to be copied + * @return a {@linkplain ByteArrayImpl} of length {@code length} that is a substring of this original. + */ + public ByteArrayImpl substring(int firstIndex, int length) { + byte[] result = new byte[length]; + System.arraycopy(data, firstIndex, result, 0, length); + return new ByteArrayImpl(result); + } + + /** + * Returns the length of this byte array. + * + * @return the length of this byte array + */ + public int length() { + return data.length; + } + + /** + * Compute exclusive or of two byte arrays. + *

+ * Returns a new byte array where the i-th entry is the exclusive or of {@code this} + * byte array's i-th entry and {@code a}'s i-th entry. + * + * @param a the argument to XOR {@code this} with + * @return the result of XORing + */ + public ByteArrayImpl xor(ByteArrayImpl a) { + int min = Math.min(this.length(), a.length()); + int max = Math.max(this.length(), a.length()); + + byte[] result = new byte[max]; + for (int i = 0; i < min; i++) { + result[i] = (byte) (this.getData()[i] ^ a.getData()[i]); + } + return new ByteArrayImpl(result); + } + + @Override + public Representation getRepresentation() { + return ReprUtil.serialize(this); + } + + @Override + public int hashCode() { + return Arrays.hashCode(data); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ByteArrayImpl other = (ByteArrayImpl) obj; + return Arrays.equals(data, other.data); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("["); + for (int i = 0; i < this.getData().length; i++) { + result.append(String.format("%d", Byte.toUnsignedInt(this.getData()[i]))); + if (i < this.getData().length - 1) + result.append(","); + } + result.append("]"); + return result.toString(); + } + + @Override + public ByteAccumulator updateAccumulator(ByteAccumulator accumulator) { + accumulator.append(data); + return accumulator; + } +} diff --git a/src/main/java/org/cryptimeleon/math/prf/PrfImage.java b/src/main/java/org/cryptimeleon/math/prf/PrfImage.java new file mode 100644 index 00000000..1c482bdd --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/PrfImage.java @@ -0,0 +1,11 @@ +package org.cryptimeleon.math.prf; + +import org.cryptimeleon.math.hash.UniqueByteRepresentable; +import org.cryptimeleon.math.serialization.Representable; + +/** + * Output of a {@link PseudorandomFunction}. + */ +public interface PrfImage extends Representable, UniqueByteRepresentable { + +} diff --git a/src/main/java/org/cryptimeleon/math/prf/PrfKey.java b/src/main/java/org/cryptimeleon/math/prf/PrfKey.java new file mode 100644 index 00000000..77108b6f --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/PrfKey.java @@ -0,0 +1,12 @@ +package org.cryptimeleon.math.prf; + +import org.cryptimeleon.math.hash.UniqueByteRepresentable; +import org.cryptimeleon.math.serialization.Representable; + + +/** + * Key used to parameterize a {@link PseudorandomFunction}. + */ +public interface PrfKey extends Representable, UniqueByteRepresentable { + +} diff --git a/src/main/java/org/cryptimeleon/math/prf/PrfPreimage.java b/src/main/java/org/cryptimeleon/math/prf/PrfPreimage.java new file mode 100644 index 00000000..33d6c838 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/PrfPreimage.java @@ -0,0 +1,12 @@ +package org.cryptimeleon.math.prf; + +import org.cryptimeleon.math.hash.UniqueByteRepresentable; +import org.cryptimeleon.math.serialization.Representable; + + +/** + * Input for a {@link PseudorandomFunction}. + */ +public interface PrfPreimage extends Representable, UniqueByteRepresentable { + +} diff --git a/src/main/java/org/cryptimeleon/math/prf/PseudorandomFunction.java b/src/main/java/org/cryptimeleon/math/prf/PseudorandomFunction.java new file mode 100644 index 00000000..0175c44e --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/PseudorandomFunction.java @@ -0,0 +1,65 @@ +package org.cryptimeleon.math.prf; + +import org.cryptimeleon.math.prf.PrfImage; +import org.cryptimeleon.math.prf.PrfKey; +import org.cryptimeleon.math.prf.PrfPreimage; +import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.serialization.StandaloneRepresentable; +import org.cryptimeleon.math.serialization.annotations.RepresentationRestorer; + +import java.lang.reflect.Type; + +/** + * A pseudorandom function is a family of functions \((f_k)\) + * so that for random choice of the key k, \(f_k: X \rightarrow Y\) is computationally + * indistinguishable from a uniformly random function \(F: X \rightarrow Y\). + *

+ * The way to use this interface is: + *

    + *
  1. Generate a key k using {@link #generateKey()} + *
  2. Call {@link #evaluate(PrfKey, PrfPreimage)} using key k and input x to receive \(y = f_k(x)\) + *
+ */ +public interface PseudorandomFunction extends StandaloneRepresentable, RepresentationRestorer { + /** + * Generates a key k for use with this PRF. + */ + PrfKey generateKey(); + + /** + * Maps a preimage x to its image using key k. + * + * @return output of \(f_k(x)\) + */ + PrfImage evaluate(PrfKey k, PrfPreimage x); + + //below this, there are only serialization-related methods + + /** + * Restores a key k from its representation. + */ + PrfKey restoreKey(Representation repr); + + /** + * Restores a preimage x from its representation. + */ + PrfPreimage restorePreimage(Representation repr); + + /** + * Restores an image y from its representation. + */ + PrfImage restoreImage(Representation repr); + + default Object restoreFromRepresentation(Type type, Representation repr) { + if (type instanceof Class) { + if (PrfKey.class.isAssignableFrom((Class) type)) { + return this.restoreKey(repr); + } else if (PrfPreimage.class.isAssignableFrom((Class) type)) { + return this.restorePreimage(repr); + } else if (PrfImage.class.isAssignableFrom((Class) type)) { + return this.restoreImage(repr); + } + } + throw new IllegalArgumentException("Cannot restore object of type: " + type.getTypeName()); + } +} diff --git a/src/main/java/org/cryptimeleon/math/prf/aes/AesPseudorandomFunction.java b/src/main/java/org/cryptimeleon/math/prf/aes/AesPseudorandomFunction.java new file mode 100644 index 00000000..465aad5a --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/aes/AesPseudorandomFunction.java @@ -0,0 +1,111 @@ +package org.cryptimeleon.math.prf.aes; + +import org.cryptimeleon.math.misc.ByteArrayImpl; +import org.cryptimeleon.math.prf.PrfImage; +import org.cryptimeleon.math.prf.PrfKey; +import org.cryptimeleon.math.prf.PrfPreimage; +import org.cryptimeleon.math.prf.PseudorandomFunction; +import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.serialization.annotations.ReprUtil; +import org.cryptimeleon.math.serialization.annotations.Represented; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Objects; + +/** + * AES as a pseudorandom function (permutation) \(f_k : \{0,1\}^l \rightarrow \{0,1\}^l\) + * for \(k \in \{0,1\}^l\). Here, l is any valid AES keylength (e.g., 128, 256). + *

+ * {@link PrfKey}, {@link PrfPreimage}, and {@link PrfImage} are of type {@link ByteArrayImpl}. + */ +public class AesPseudorandomFunction implements PseudorandomFunction { + @Represented + protected Integer keylength; //length of keys in bit + + /** + * Instantiates the PRF with a given AES key length. + * + * @param keylength a valid AES key length in bit (e.g., 128 or 256) + */ + public AesPseudorandomFunction(int keylength) { + this.keylength = keylength; + } + + public AesPseudorandomFunction(Representation repr) { + new ReprUtil(this).deserialize(repr); + } + + @Override + public Representation getRepresentation() { + return ReprUtil.serialize(this); + } + + @Override + public PrfKey generateKey() { + return ByteArrayImpl.fromRandom(keylength / 8); + } + + @Override + public PrfImage evaluate(PrfKey k, PrfPreimage x) { + if (((ByteArrayImpl) k).length() != keylength / 8) + throw new IllegalArgumentException("key k in the AES PRF has invalid length"); + if (((ByteArrayImpl) x).length() != keylength / 8) + throw new IllegalArgumentException("preimage x in the AES PRF has invalid length"); + + try { + Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); + SecretKeySpec keySpec = new SecretKeySpec(((ByteArrayImpl) k).getData(), "AES"); + cipher.init(Cipher.ENCRYPT_MODE, keySpec); + return new ByteArrayImpl(cipher.doFinal(((ByteArrayImpl) x).getData())); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } catch (InvalidKeyException e) { + e.printStackTrace(); + throw new IllegalArgumentException("Input k to AES PRF must be of valid AES key length"); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + throw new IllegalArgumentException("Input x to AES PRF must be of valid AES key length"); + } + } + + @Override + public PrfKey restoreKey(Representation repr) { + return new ByteArrayImpl(repr); + } + + @Override + public PrfPreimage restorePreimage(Representation repr) { + return new ByteArrayImpl(repr); + } + + @Override + public PrfImage restoreImage(Representation repr) { + return new ByteArrayImpl(repr); + } + + @Override + public int hashCode() { + return keylength; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + AesPseudorandomFunction other = (AesPseudorandomFunction) o; + return Objects.equals(keylength, other.keylength); + } + + public Integer getKeylength() { + return keylength; + } +} diff --git a/src/main/java/org/cryptimeleon/math/prf/aes/LongAesPseudoRandomFunction.java b/src/main/java/org/cryptimeleon/math/prf/aes/LongAesPseudoRandomFunction.java new file mode 100644 index 00000000..30a1d641 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/aes/LongAesPseudoRandomFunction.java @@ -0,0 +1,112 @@ +package org.cryptimeleon.math.prf.aes; + +import org.cryptimeleon.math.misc.ByteArrayImpl; +import org.cryptimeleon.math.prf.PrfKey; +import org.cryptimeleon.math.prf.PrfPreimage; +import org.cryptimeleon.math.prf.PseudorandomFunction; +import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.serialization.annotations.ReprUtil; +import org.cryptimeleon.math.serialization.annotations.Represented; + +import java.util.Objects; + +/** + * AES based PRF with k key length and output length of the underlying AES key length. + * PRF_k(x) = AES_k1(x)||AES_k2(x)|..." with key k=(k1,k2,...) + *

+ * This is basically a wrapper around AesPseudorandomFunction. + **/ +public class LongAesPseudoRandomFunction implements PseudorandomFunction { + + @Represented + private AesPseudorandomFunction aesPseudorandomFunction; + @Represented + private Integer factor; + private int preimageLengthBytes; + private int keyLengthBytes; + + /** + * Instantiates the PRF with an AES instance and desired factor. + * + * @param k factor by which output and key size of AES is increased + * @param aesPseudorandomFunction AES instance to use k times + */ + public LongAesPseudoRandomFunction(AesPseudorandomFunction aesPseudorandomFunction, int k) { + this.aesPseudorandomFunction = aesPseudorandomFunction; + this.factor = k; + this.init(); + } + + public LongAesPseudoRandomFunction(Representation repr) { + new ReprUtil(this).deserialize(repr); + this.init(); + } + + private void init() { + this.preimageLengthBytes = aesPseudorandomFunction.getKeylength() / 8; + this.keyLengthBytes = preimageLengthBytes * factor; + } + + @Override + public ByteArrayImpl generateKey() { + return ByteArrayImpl.fromRandom(keyLengthBytes); + } + + @Override + public ByteArrayImpl evaluate(PrfKey k, PrfPreimage x) { + if (((ByteArrayImpl) k).length() != keyLengthBytes) + throw new IllegalArgumentException("key k in the AES PRF has invalid length"); + if (((ByteArrayImpl) x).length() != preimageLengthBytes) + throw new IllegalArgumentException("preimage x in the AES PRF has invalid length"); + + ByteArrayImpl result = new ByteArrayImpl(new byte[0]); + for (int i = 0; i < factor; i++) { + ByteArrayImpl ki = ((ByteArrayImpl) k).substring(i * preimageLengthBytes, preimageLengthBytes); + byte[] bytesToAppend = ((ByteArrayImpl) aesPseudorandomFunction.evaluate(ki, x)).getData(); + result = result.append(new ByteArrayImpl(bytesToAppend)); + } + return result; + } + + + @Override + public ByteArrayImpl restoreKey(Representation repr) { + return new ByteArrayImpl(repr); + } + + @Override + public ByteArrayImpl restorePreimage(Representation repr) { + return new ByteArrayImpl(repr); + } + + @Override + public ByteArrayImpl restoreImage(Representation repr) { + return new ByteArrayImpl(repr); + } + + @Override + public Representation getRepresentation() { + return ReprUtil.serialize(this); + } + + public int getPreimageLengthBytes() { + return preimageLengthBytes; + } + + public int getKeyLengthBytes() { + return keyLengthBytes; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LongAesPseudoRandomFunction that = (LongAesPseudoRandomFunction) o; + return factor.equals(that.factor) && Objects.equals(aesPseudorandomFunction, that.aesPseudorandomFunction); + } + + @Override + public int hashCode() { + return Objects.hash(aesPseudorandomFunction, factor); + } +} diff --git a/src/main/java/org/cryptimeleon/math/prf/aes/package-info.java b/src/main/java/org/cryptimeleon/math/prf/aes/package-info.java new file mode 100644 index 00000000..5b9c46df --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/aes/package-info.java @@ -0,0 +1,4 @@ +/** + * Contains an implementation of an AES-based pseudorandom function. + */ +package org.cryptimeleon.math.prf.aes; \ No newline at end of file diff --git a/src/main/java/org/cryptimeleon/math/prf/package-info.java b/src/main/java/org/cryptimeleon/math/prf/package-info.java new file mode 100644 index 00000000..ca9ad99c --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/package-info.java @@ -0,0 +1,4 @@ +/** + * Contains basic interfaces related to pseudorandom functions. + */ +package org.cryptimeleon.math.prf; \ No newline at end of file diff --git a/src/main/java/org/cryptimeleon/math/prf/zn/HashThenPrfToZn.java b/src/main/java/org/cryptimeleon/math/prf/zn/HashThenPrfToZn.java new file mode 100644 index 00000000..f2c84709 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/zn/HashThenPrfToZn.java @@ -0,0 +1,201 @@ +package org.cryptimeleon.math.prf.zn; + +import org.cryptimeleon.math.hash.HashFunction; +import org.cryptimeleon.math.hash.UniqueByteRepresentable; +import org.cryptimeleon.math.hash.impl.ByteArrayAccumulator; +import org.cryptimeleon.math.misc.ByteArrayImpl; +import org.cryptimeleon.math.prf.PrfKey; +import org.cryptimeleon.math.prf.aes.AesPseudorandomFunction; +import org.cryptimeleon.math.prf.aes.LongAesPseudoRandomFunction; +import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.serialization.StandaloneRepresentable; +import org.cryptimeleon.math.serialization.annotations.ReprUtil; +import org.cryptimeleon.math.serialization.annotations.Represented; +import org.cryptimeleon.math.structures.rings.RingElement; +import org.cryptimeleon.math.structures.rings.cartesian.RingElementVector; +import org.cryptimeleon.math.structures.rings.zn.Zn; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Objects; + +/** + * Get pseudorandom Zn Elements by a hash-then-prf construction. + *

+ * We use a PRF that outputs bitstrings and map these to Zp as follows: + * We divide the output interval of size 2^n (with elements in [0,2^n-1]) into a 'good' and a 'bad' interval, where the + * good interval is [0,x*p[ with x*p{@literal <}2^n chosen to be maximal and the bad interval [x*p,2^n-1]. + * Since x is maximal, the bad interval has size at most p-1. + *

+ * To get a ZnElement, we hash, use the PRF and get some output value o. + * If o is in the good interval, we output o mod p + * as our ZnElement. This is random for random bit strings, since the good interval's size is a multiple of p. + * If o is in the bad interval, we reject and throw an exception. We don't want this to happen, hence we increase the + * good interval by using a longer PRF, this can be influenced by the so called 'oversubscription'. Since the bad + * interval's size is bound by p, increasing the total interval reduces the probability of landing in the bad interval. + * More precisely, the reject rate is bound by (1/2)^oversubscription. + */ +public class HashThenPrfToZn implements StandaloneRepresentable { + @Represented + private LongAesPseudoRandomFunction longAesPseudoRandomFunction; + @Represented + private HashFunction hashFunction; + @Represented + private Zn zn; + + // Redundant parameter that we do not want to compute every time we use this + private BigInteger maxQuotient; // x from the description + + /** + * Instantiate HashThenPrfToZn + * + * @param aesKeyLength bit length of AES + * @param zn target ring + * @param hashFunction hash function to use, output size should be larger than AES input size + * @param oversubscription parameter that binds the probability of failing by (1/2)^oversubscription. Probability can be lower due to rounding + */ + public HashThenPrfToZn(int aesKeyLength, Zn zn, HashFunction hashFunction, int oversubscription) { + if (hashFunction.getOutputLength() * 8 < aesKeyLength) { + throw new IllegalArgumentException("Hash function output should be larger or equal to AES input size."); + } + + this.hashFunction = hashFunction; + this.zn = zn; + this.longAesPseudoRandomFunction = new LongAesPseudoRandomFunction( + new AesPseudorandomFunction(aesKeyLength), + (zn.getCharacteristic().bitLength() + aesKeyLength + oversubscription + 1) / aesKeyLength // Compute number of AES instances required to get desired output bit length + ); + this.init(); + } + + public HashThenPrfToZn(Representation repr) { + new ReprUtil(this).deserialize(repr); + this.init(); + } + + /** + * Initialization of HashTHenPrfToZn. + */ + private void init() { + BigInteger p = zn.getCharacteristic(); + + // Compute quotient of prf output all 1s divided by p + // We can use all remainders with quotients strictly smaller than that quotient to draw uniformly at random from Zp + byte[] bytes = new byte[longAesPseudoRandomFunction.getKeyLengthBytes()]; + Arrays.fill(bytes, (byte) 255); + + BigInteger[] dar = new BigInteger(1, bytes).divideAndRemainder(p); + this.maxQuotient = dar[0]; + } + + /** + * Generates a PRF key that can be used to hash-then-prf to Zn + * + * @return a PRF key + */ + public PrfKey generateKey() { + return longAesPseudoRandomFunction.generateKey(); + } + + + /** + * Generate pseudorandom ZnVectors of variable size using unique prefixes for the vectorSize and index. + * + * @param prfKey the PRF key + * @param hashInput input to hash + * @param vectorSize target vector size + * @param prefix prefix to allow using the same vectorSize and preImage several times + * @return a pseudorandom Vector of Zn elements + */ + public RingElementVector hashThenPrfToZnVector(PrfKey prfKey, UniqueByteRepresentable hashInput, int vectorSize, String prefix) { + RingElement[] result = new RingElement[vectorSize]; + + for (int i = 0; i < vectorSize; i++) { + ByteArrayAccumulator accumulator = new ByteArrayAccumulator(); + accumulator.append(vectorSize); // Ensure uniqueness for each vector size, allows using the same preimage for several, different sized vectors + accumulator.append(i); // Index to prevent having the same output for each element + accumulator.escapeAndSeparate(prefix); // Prefix to allow using the same preImage and vectorSize twice + accumulator.escapeAndAppend(hashInput); + Zn.ZnElement element = hashThenPrfToZn(prfKey, accumulator.extractBytes()); + result[i] = element; + } + + return new RingElementVector(result); + } + + /** + * Main method of Hash-then-PRF to Zn. + * Private to avoid accidentally mixing different hashInput formats. + * + * @param prfKey the PRF key + * @param hashInput input to hash + * @return a pseudorandom Zn element + */ + private Zn.ZnElement hashThenPrfToZn(PrfKey prfKey, byte[] hashInput) { + BigInteger p = zn.getCharacteristic(); + + // Compute hash value + byte[] hashOutput = hashFunction.hash(hashInput); + + // Truncate hash + byte[] prfInput = new byte[longAesPseudoRandomFunction.getPreimageLengthBytes()]; + System.arraycopy(hashOutput, 0, prfInput, 0, longAesPseudoRandomFunction.getPreimageLengthBytes()); + + // Compute prf(hash) + ByteArrayImpl prfOutput = longAesPseudoRandomFunction.evaluate(prfKey, new ByteArrayImpl(prfInput)); + + //Compute quotient and remainder of the prf output interpreted as a positive integer. Return remainder as + // ZnElement if quotient is smaller than largest quotient to ensurer elements are drawn uniformly at random + // from Zn + BigInteger[] quotientAndRemainder = new BigInteger(1, prfOutput.getData()).divideAndRemainder(p); + + if (quotientAndRemainder[0].compareTo(maxQuotient) >= 0) { + throw new RuntimeException("PRF output is in the reject interval!"); + } + + return zn.valueOf(quotientAndRemainder[1]); + } + + /* + * Some wrappers with different method signatures. + */ + + public RingElementVector hashThenPrfToZnVector(PrfKey prfKey, UniqueByteRepresentable hashInput, int vectorSize) { + return hashThenPrfToZnVector(prfKey, hashInput, vectorSize, ""); + } + + public Zn.ZnElement hashThenPrfToZn(PrfKey prfKey, UniqueByteRepresentable hashInput) { + return (Zn.ZnElement) hashThenPrfToZnVector(prfKey, hashInput, 1, "").get(0); + } + + public Zn.ZnElement hashThenPrfToZn(PrfKey prfKey, UniqueByteRepresentable hashInput, String prefix) { + return (Zn.ZnElement) hashThenPrfToZnVector(prfKey, hashInput, 1, prefix).get(0); + } + + + public LongAesPseudoRandomFunction getLongAesPseudoRandomFunction() { + return longAesPseudoRandomFunction; + } + + public HashFunction getHashFunction() { + return hashFunction; + } + + @Override + public Representation getRepresentation() { + return ReprUtil.serialize(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HashThenPrfToZn prfToZn = (HashThenPrfToZn) o; + return Objects.equals(longAesPseudoRandomFunction, prfToZn.longAesPseudoRandomFunction) && Objects.equals(hashFunction, prfToZn.hashFunction) && Objects.equals(zn, prfToZn.zn) && Objects.equals(maxQuotient, prfToZn.maxQuotient); + } + + @Override + public int hashCode() { + return Objects.hash(longAesPseudoRandomFunction, hashFunction, zn, maxQuotient); + } +} diff --git a/src/main/java/org/cryptimeleon/math/prf/zn/package-info.java b/src/main/java/org/cryptimeleon/math/prf/zn/package-info.java new file mode 100644 index 00000000..e1ac5da3 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/prf/zn/package-info.java @@ -0,0 +1,4 @@ +/** + * Contains an implementation of a Hash-then-Prf-to-Zn construction. + */ +package org.cryptimeleon.math.prf.zn; \ No newline at end of file diff --git a/src/main/java/org/cryptimeleon/math/serialization/ListRepresentation.java b/src/main/java/org/cryptimeleon/math/serialization/ListRepresentation.java index f27ef1b3..8e446b1f 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/ListRepresentation.java +++ b/src/main/java/org/cryptimeleon/math/serialization/ListRepresentation.java @@ -1,6 +1,7 @@ package org.cryptimeleon.math.serialization; import org.cryptimeleon.math.serialization.converter.JSONConverter; +import org.cryptimeleon.math.structures.cartesian.Vector; import java.util.*; import java.util.stream.Stream; @@ -22,7 +23,11 @@ public ListRepresentation() { } - public ListRepresentation(List list) { + public ListRepresentation(Vector vector) { + this(vector.toList()); + } + + public ListRepresentation(List list) { this.list.addAll(list); } diff --git a/src/main/java/org/cryptimeleon/math/serialization/RepresentableRepresentation.java b/src/main/java/org/cryptimeleon/math/serialization/RepresentableRepresentation.java index 2694a87a..b4b3dae2 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/RepresentableRepresentation.java +++ b/src/main/java/org/cryptimeleon/math/serialization/RepresentableRepresentation.java @@ -2,6 +2,7 @@ import org.cryptimeleon.math.serialization.converter.JSONConverter; +import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** @@ -67,12 +68,18 @@ public Object recreateRepresentable() { if (c.isEnum()) { return Enum.valueOf((Class) c, representation.str().get()); } - return c.getConstructor(Representation.class).newInstance(representation); - } catch (NoSuchMethodException e) { //no constructor with single Representation paramenter - if (representation == null) //no representation necessary. Try default constructor - return c.getConstructor(new Class[]{}).newInstance(); - else + Constructor constructor = c.getConstructor(Representation.class); + constructor.setAccessible(true); + return constructor.newInstance(representation); + } catch (NoSuchMethodException e) { //no constructor with single Representation parameter + if (representation == null) { + // no representation necessary. Try default constructor + Constructor constructor = c.getConstructor(new Class[]{}); + constructor.setAccessible(true); + return constructor.newInstance(); + } else { throw e; + } } } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Cannot find class " + representedTypeName, e); diff --git a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/ArrayRepresentationHandler.java b/src/main/java/org/cryptimeleon/math/serialization/annotations/ArrayRepresentationHandler.java similarity index 91% rename from src/main/java/org/cryptimeleon/math/serialization/annotations/internal/ArrayRepresentationHandler.java rename to src/main/java/org/cryptimeleon/math/serialization/annotations/ArrayRepresentationHandler.java index 8d78ae8a..02170ec6 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/ArrayRepresentationHandler.java +++ b/src/main/java/org/cryptimeleon/math/serialization/annotations/ArrayRepresentationHandler.java @@ -1,8 +1,7 @@ -package org.cryptimeleon.math.serialization.annotations.internal; +package org.cryptimeleon.math.serialization.annotations; import org.cryptimeleon.math.serialization.ListRepresentation; import org.cryptimeleon.math.serialization.Representation; -import org.cryptimeleon.math.serialization.annotations.RepresentationRestorer; import java.lang.reflect.Array; import java.lang.reflect.Type; @@ -11,7 +10,7 @@ /** * A handler for serializing/deserializing arrays. */ -public class ArrayRepresentationHandler implements RepresentationHandler { +class ArrayRepresentationHandler implements RepresentationHandler { /** * Handler for the array elements. */ diff --git a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/DependentRepresentationHandler.java b/src/main/java/org/cryptimeleon/math/serialization/annotations/DependentRepresentationHandler.java similarity index 87% rename from src/main/java/org/cryptimeleon/math/serialization/annotations/internal/DependentRepresentationHandler.java rename to src/main/java/org/cryptimeleon/math/serialization/annotations/DependentRepresentationHandler.java index f8eff2ec..5e09b21a 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/DependentRepresentationHandler.java +++ b/src/main/java/org/cryptimeleon/math/serialization/annotations/DependentRepresentationHandler.java @@ -1,8 +1,7 @@ -package org.cryptimeleon.math.serialization.annotations.internal; +package org.cryptimeleon.math.serialization.annotations; import org.cryptimeleon.math.serialization.Representable; import org.cryptimeleon.math.serialization.Representation; -import org.cryptimeleon.math.serialization.annotations.RepresentationRestorer; import java.lang.reflect.Type; import java.util.function.Function; @@ -10,7 +9,7 @@ /** * Handles representations that depend on some {@link RepresentationRestorer} in order to be recreated. */ -public class DependentRepresentationHandler implements RepresentationHandler { +class DependentRepresentationHandler implements RepresentationHandler { /** * Restorer string indicating the {@code RepresentationRestorer} to use. */ diff --git a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/ListAndSetRepresentationHandler.java b/src/main/java/org/cryptimeleon/math/serialization/annotations/ListAndSetRepresentationHandler.java similarity index 96% rename from src/main/java/org/cryptimeleon/math/serialization/annotations/internal/ListAndSetRepresentationHandler.java rename to src/main/java/org/cryptimeleon/math/serialization/annotations/ListAndSetRepresentationHandler.java index e6a77d5a..d6bff883 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/ListAndSetRepresentationHandler.java +++ b/src/main/java/org/cryptimeleon/math/serialization/annotations/ListAndSetRepresentationHandler.java @@ -1,8 +1,7 @@ -package org.cryptimeleon.math.serialization.annotations.internal; +package org.cryptimeleon.math.serialization.annotations; import org.cryptimeleon.math.serialization.ListRepresentation; import org.cryptimeleon.math.serialization.Representation; -import org.cryptimeleon.math.serialization.annotations.RepresentationRestorer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; @@ -13,7 +12,7 @@ /** * A handler for serializing/deserializing {@link List} and {@link Set} instances. */ -public class ListAndSetRepresentationHandler implements RepresentationHandler { +class ListAndSetRepresentationHandler implements RepresentationHandler { private static final Class[] supportedFallbackClasses = new Class[] {ArrayList.class, HashSet.class}; /** diff --git a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/MapRepresentationHandler.java b/src/main/java/org/cryptimeleon/math/serialization/annotations/MapRepresentationHandler.java similarity index 96% rename from src/main/java/org/cryptimeleon/math/serialization/annotations/internal/MapRepresentationHandler.java rename to src/main/java/org/cryptimeleon/math/serialization/annotations/MapRepresentationHandler.java index fcc25994..79a6a6bf 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/MapRepresentationHandler.java +++ b/src/main/java/org/cryptimeleon/math/serialization/annotations/MapRepresentationHandler.java @@ -1,8 +1,7 @@ -package org.cryptimeleon.math.serialization.annotations.internal; +package org.cryptimeleon.math.serialization.annotations; import org.cryptimeleon.math.serialization.MapRepresentation; import org.cryptimeleon.math.serialization.Representation; -import org.cryptimeleon.math.serialization.annotations.RepresentationRestorer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; @@ -14,7 +13,7 @@ /** * A handler for serializing/deserializing {@link Map} instances. */ -public class MapRepresentationHandler implements RepresentationHandler { +class MapRepresentationHandler implements RepresentationHandler { /** * Handler for the map's keys. */ diff --git a/src/main/java/org/cryptimeleon/math/serialization/annotations/ReprUtil.java b/src/main/java/org/cryptimeleon/math/serialization/annotations/ReprUtil.java index db32d4a7..f21d6534 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/annotations/ReprUtil.java +++ b/src/main/java/org/cryptimeleon/math/serialization/annotations/ReprUtil.java @@ -2,7 +2,6 @@ import org.cryptimeleon.math.serialization.ObjectRepresentation; import org.cryptimeleon.math.serialization.Representation; -import org.cryptimeleon.math.serialization.annotations.internal.*; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroup; import org.cryptimeleon.math.structures.groups.elliptic.BilinearMap; diff --git a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/RepresentationHandler.java b/src/main/java/org/cryptimeleon/math/serialization/annotations/RepresentationHandler.java similarity index 89% rename from src/main/java/org/cryptimeleon/math/serialization/annotations/internal/RepresentationHandler.java rename to src/main/java/org/cryptimeleon/math/serialization/annotations/RepresentationHandler.java index cec73a37..25304f4c 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/RepresentationHandler.java +++ b/src/main/java/org/cryptimeleon/math/serialization/annotations/RepresentationHandler.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.serialization.annotations.internal; +package org.cryptimeleon.math.serialization.annotations; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.serialization.annotations.RepresentationRestorer; @@ -8,7 +8,7 @@ /** * Interface for classes that can serialize and deserialize specific types of objects. */ -public interface RepresentationHandler { +interface RepresentationHandler { /** * Deserializes the given representation using the given representation restorers. * @param repr the representation to deserialize diff --git a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/StandaloneRepresentationHandler.java b/src/main/java/org/cryptimeleon/math/serialization/annotations/StandaloneRepresentationHandler.java similarity index 94% rename from src/main/java/org/cryptimeleon/math/serialization/annotations/internal/StandaloneRepresentationHandler.java rename to src/main/java/org/cryptimeleon/math/serialization/annotations/StandaloneRepresentationHandler.java index b918fd73..836a57fb 100644 --- a/src/main/java/org/cryptimeleon/math/serialization/annotations/internal/StandaloneRepresentationHandler.java +++ b/src/main/java/org/cryptimeleon/math/serialization/annotations/StandaloneRepresentationHandler.java @@ -1,7 +1,7 @@ -package org.cryptimeleon.math.serialization.annotations.internal; +package org.cryptimeleon.math.serialization.annotations; +import org.cryptimeleon.math.misc.BigIntegerTools; import org.cryptimeleon.math.serialization.*; -import org.cryptimeleon.math.serialization.annotations.RepresentationRestorer; import java.lang.reflect.Type; import java.math.BigInteger; @@ -11,7 +11,7 @@ * Handles serialization/deserialization of the representation of {@link StandaloneRepresentable} implementers * and some other simple types. */ -public class StandaloneRepresentationHandler implements RepresentationHandler { +class StandaloneRepresentationHandler implements RepresentationHandler { // it may be temping to add int.class etc. here, but it doesn't work because the ReprUtil assumes that everything // that's not null is already set (and int is auto-initialized with 0) @@ -64,7 +64,7 @@ public Object deserializeFromRepresentation(Representation repr, Function secondPart) { return new ExponentExpressionVector(super.concatenate(secondPart)); } + + @Override + public ExponentExpressionVector append(ExponentExpr valueToAppend) { + return new ExponentExpressionVector(super.append(valueToAppend)); + } + + @Override + public ExponentExpressionVector prepend(ExponentExpr valueToPrepend) { + return new ExponentExpressionVector(super.prepend(valueToPrepend)); + } } diff --git a/src/main/java/org/cryptimeleon/math/structures/cartesian/GroupElementExpressionVector.java b/src/main/java/org/cryptimeleon/math/structures/cartesian/GroupElementExpressionVector.java index a5a7619b..b15a692b 100644 --- a/src/main/java/org/cryptimeleon/math/structures/cartesian/GroupElementExpressionVector.java +++ b/src/main/java/org/cryptimeleon/math/structures/cartesian/GroupElementExpressionVector.java @@ -115,6 +115,16 @@ public GroupElementExpressionVector pad(GroupElementExpression valueToPadWith, i return new GroupElementExpressionVector(super.pad(valueToPadWith, desiredLength)); } + @Override + public GroupElementExpressionVector append(GroupElementExpression valueToAppend) { + return new GroupElementExpressionVector(super.append(valueToAppend)); + } + + @Override + public GroupElementExpressionVector prepend(GroupElementExpression valueToPrepend) { + return new GroupElementExpressionVector(super.prepend(valueToPrepend)); + } + @Override public GroupElementExpressionVector replace(int index, GroupElementExpression substitute) { return new GroupElementExpressionVector(super.replace(index, substitute)); diff --git a/src/main/java/org/cryptimeleon/math/structures/cartesian/Vector.java b/src/main/java/org/cryptimeleon/math/structures/cartesian/Vector.java index 5581b1d5..7d2b9a60 100644 --- a/src/main/java/org/cryptimeleon/math/structures/cartesian/Vector.java +++ b/src/main/java/org/cryptimeleon/math/structures/cartesian/Vector.java @@ -302,6 +302,19 @@ public Vector pad(X valueToPadWith, int desiredLength) { return instantiateWithSafeArray(result); } + public Vector append(X valueToAppend) { + ArrayList result = new ArrayList<>(values); + result.add(valueToAppend); + return instantiateWithSafeArray(result); + } + + public Vector prepend(X valueToPrepend) { + ArrayList result = new ArrayList<>(); + result.add(valueToPrepend); + result.addAll(values); + return instantiateWithSafeArray(result); + } + public Vector replace(int index, X substitute) { ArrayList result = new ArrayList<>(values); result.set(index, substitute); diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/GroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/GroupElement.java index 5cebf439..d4ed50a1 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/GroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/GroupElement.java @@ -1,5 +1,6 @@ package org.cryptimeleon.math.structures.groups; +import org.cryptimeleon.math.expressions.bool.GroupEqualityExpr; import org.cryptimeleon.math.expressions.exponent.ExponentExpr; import org.cryptimeleon.math.expressions.group.GroupElementConstantExpr; import org.cryptimeleon.math.expressions.group.GroupElementExpression; @@ -151,6 +152,42 @@ default GroupElementConstantExpr expr() { return new GroupElementConstantExpr(this); } + /** + * Returns an expression of the form "this == expr". + * This is meant to write down an expression, usually only useful if you want to express something that depends on variables that become known later. + * If you just want to compare two {@link GroupElement}s, just use {@link #equals(Object)}. + * + * @param expr an expression to compare this group element to + * @return an expression the evaluates to true (for some variable instantiation) if this is equal to expr. + */ + default GroupEqualityExpr isEqualTo(GroupElementExpression expr) { + return expr().isEqualTo(expr); + } + + /** + * Returns an expression of the form "this == expr". + * This is meant to write down an expression, usually only useful if you want to express something that depends on variables that become known later. + * If you just want to compare two {@link GroupElement}s, just use {@link #equals(Object)}. + * + * @param expr an expression to compare this group element to + * @return an expression the evaluates to true (for some variable instantiation) if this is equal to expr. + */ + default GroupEqualityExpr isEqualTo(String expr) { + return expr().isEqualTo(expr); + } + + /** + * Returns an expression of the form "this == other". + * This is meant to write down an expression, usually only useful if you want to express something that depends on variables that become known later. + * If you just want to compare two {@link GroupElement}s, just use {@link #equals(Object)}. + * + * @param other another group element to compare this group element to + * @return an expression the evaluates to true iff this.equals(other). + */ + default GroupEqualityExpr isEqualTo(GroupElement other) { + return expr().isEqualTo(other); + } + /** * Advises the {@code GroupElement} to prepare it for later {@code pow()} calls. * This will take some time and should only be done ahead of time. diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/GroupElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/GroupElementImpl.java index 7538957b..b3052a5a 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/GroupElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/GroupElementImpl.java @@ -6,9 +6,8 @@ import java.math.BigInteger; /** - * Immutable objects representing elements of a group. - *

- * Usually wrapped by a {@link GroupElement} to offer additional evaluation capabilities. + * Immutable objects representing elements of a group usually wrapped by a {@link GroupElement} to offer + * additional evaluation capabilities. *

* Implementations must properly implement {@code equals()} and {@code hashCode()}. */ diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/GroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/GroupImpl.java index b51f426b..d28f2232 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/GroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/GroupImpl.java @@ -13,9 +13,11 @@ import java.util.Optional; /** - * A Group. Operations are defined on its elements. - *

- * Usually wrapped by a {@link Group} to offer additional evaluation capabilities. + * An algebraic group implementation which can be wrapped by a {@link Group} to offer additional evaluation capabilities. + * Operations are defined on its elements. + * + * @see Group for the wrapper class + * @see GroupElementImpl for the element class */ public interface GroupImpl extends StandaloneRepresentable, RepresentationRestorer { /** diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/RingAdditiveGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/RingAdditiveGroupImpl.java index bb4ffb95..b087910f 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/RingAdditiveGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/RingAdditiveGroupImpl.java @@ -11,7 +11,7 @@ /** * Allows interpreting a ring as its additive group. */ -public class RingAdditiveGroupImpl extends RingGroupImpl { +class RingAdditiveGroupImpl extends RingGroupImpl { /** * Instantiates this ring additive group. @@ -37,9 +37,7 @@ public boolean hasPrimeSize() { @Override public double estimateCostInvPerOp() { - // Does not really work here since the numbers depend on the exact ring - // Used Zn(2^128) here - return 1; + return ring.estimateCostNegPerOp(); } @Override diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/RingGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/RingGroup.java index 4afbe1a0..a8219045 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/RingGroup.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/RingGroup.java @@ -7,7 +7,7 @@ import org.cryptimeleon.math.structures.rings.RingElement; /** - * Represents a group instantiated from either the additive or unit groups from a ring. + * Represents a group instantiated from either the additive or unit group of a ring. */ public class RingGroup extends BasicGroup { protected RingGroup(GroupImpl impl) { diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/RingGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/RingGroupImpl.java index 4c0cc201..6f8a357f 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/RingGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/RingGroupImpl.java @@ -8,7 +8,7 @@ /** * Common base class for ring subgroups (additive/unit groups). */ -public abstract class RingGroupImpl implements GroupImpl { +abstract class RingGroupImpl implements GroupImpl { protected final Ring ring; /** diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/RingUnitGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/RingUnitGroupImpl.java index 1f88932e..2e6c431a 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/RingUnitGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/RingUnitGroupImpl.java @@ -15,7 +15,7 @@ * The unit group consists of the set of elements with a multiplicative inverse. * The group operation is multiplication and the neutral element is called the one element. */ -public class RingUnitGroupImpl extends RingGroupImpl { +class RingUnitGroupImpl extends RingGroupImpl { public RingUnitGroupImpl(Ring ring) { super(ring); } @@ -41,9 +41,7 @@ public boolean hasPrimeSize() { @Override public double estimateCostInvPerOp() { - // Does not really work here since the numbers depend on the exact ring - // Used Zn(2^128) here - return 0.1; + return ring.estimateCostInvPerOp(); } @Override diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/cartesian/GroupElementVector.java b/src/main/java/org/cryptimeleon/math/structures/groups/cartesian/GroupElementVector.java index acdc6dc6..af70104e 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/cartesian/GroupElementVector.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/cartesian/GroupElementVector.java @@ -126,10 +126,21 @@ public GroupElementVector truncate(int newLength) { return new GroupElementVector(super.truncate(newLength)); } + @Override public GroupElementVector concatenate(Vector secondPart) { return new GroupElementVector(super.concatenate(secondPart)); } + @Override + public GroupElementVector append(GroupElement valueToAppend) { + return new GroupElementVector(super.append(valueToAppend)); + } + + @Override + public GroupElementVector prepend(GroupElement valueToPrepend) { + return new GroupElementVector(super.prepend(valueToPrepend)); + } + public static GroupElementVector fromStream(Stream stream) { return fromStreamPlain(stream, GroupElementVector::instantiateWithSafeArray); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/package-info.java b/src/main/java/org/cryptimeleon/math/structures/groups/counting/package-info.java deleted file mode 100644 index 815af43a..00000000 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Extends the debug pairing with group operation and pairing counting functionality. - */ -package org.cryptimeleon.math.structures.groups.counting; \ No newline at end of file diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearGroup.java similarity index 78% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearGroup.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearGroup.java index 43f7d88a..f1e9d1ab 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearGroup.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearGroup.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.random.RandomGenerator; import org.cryptimeleon.math.serialization.Representation; @@ -22,12 +22,12 @@ * group level. *

* The counting capability is implemented by wrapping two {@link LazyBilinearGroup}s which contain - * {@link CountingBilinearGroupImpl}s themselves. All operations are executed in both groups, + * {@link DebugBilinearGroupImpl}s themselves. All operations are executed in both groups, * one counts total group operations and one counts each (multi-)exponentiation as one unit. * This allows for tracking both kinds of data. * */ -public class CountingBilinearGroup implements BilinearGroup { +public class DebugBilinearGroup implements BilinearGroup { /** * The security level offered by this bilinear group in number of bits. @@ -56,7 +56,7 @@ public class CountingBilinearGroup implements BilinearGroup { /** * The underlying bilinear map used for applying the pairing function and counting it. */ - protected CountingBilinearMap bilMap; + protected DebugBilinearMap bilMap; /** * Initializes this bilinear group with the given security level, pairing type, and group order factoring @@ -66,7 +66,7 @@ public class CountingBilinearGroup implements BilinearGroup { * @param pairingType the type of pairing that should be offered by this bilinear group * @param numPrimeFactors the number of prime factors the group order should have */ - public CountingBilinearGroup(int securityParameter, BilinearGroup.Type pairingType, int numPrimeFactors) { + public DebugBilinearGroup(int securityParameter, BilinearGroup.Type pairingType, int numPrimeFactors) { this.securityParameter = securityParameter; this.pairingType = pairingType; @@ -75,10 +75,10 @@ public CountingBilinearGroup(int securityParameter, BilinearGroup.Type pairingTy primeFactors.add(RandomGenerator.getRandomPrime(securityParameter)); BigInteger size = primeFactors.stream().reduce(BigInteger.ONE, BigInteger::multiply); - totalBilGroup = new LazyBilinearGroup(new CountingBilinearGroupImpl( + totalBilGroup = new LazyBilinearGroup(new DebugBilinearGroupImpl( securityParameter, pairingType, size, false, false )); - expMultiExpBilGroup = new LazyBilinearGroup(new CountingBilinearGroupImpl( + expMultiExpBilGroup = new LazyBilinearGroup(new DebugBilinearGroupImpl( securityParameter, pairingType, size, true, true )); init(); @@ -91,7 +91,7 @@ public CountingBilinearGroup(int securityParameter, BilinearGroup.Type pairingTy * @param securityParameter the security level in number of bits * @param pairingType the type of pairing that should be offered by this bilinear group */ - public CountingBilinearGroup(int securityParameter, BilinearGroup.Type pairingType) { + public DebugBilinearGroup(int securityParameter, BilinearGroup.Type pairingType) { this(securityParameter, pairingType, 1); } @@ -101,11 +101,11 @@ public CountingBilinearGroup(int securityParameter, BilinearGroup.Type pairingTy * * @param pairingType the type of pairing that should be offered by this bilinear group */ - public CountingBilinearGroup(BilinearGroup.Type pairingType) { + public DebugBilinearGroup(BilinearGroup.Type pairingType) { this(128, pairingType); } - public CountingBilinearGroup(Representation repr) { + public DebugBilinearGroup(Representation repr) { ReprUtil.deserialize(this, repr); init(); } @@ -114,22 +114,22 @@ public CountingBilinearGroup(Representation repr) { * Initializes the underlying bilinear map {@link #bilMap}. */ protected void init() { - bilMap = new CountingBilinearMap(totalBilGroup.getBilinearMap(), expMultiExpBilGroup.getBilinearMap()); + bilMap = new DebugBilinearMap(totalBilGroup.getBilinearMap(), expMultiExpBilGroup.getBilinearMap()); } @Override public Group getG1() { - return new CountingGroup(totalBilGroup.getG1(), expMultiExpBilGroup.getG1()); + return new DebugGroup(totalBilGroup.getG1(), expMultiExpBilGroup.getG1()); } @Override public Group getG2() { - return new CountingGroup(totalBilGroup.getG2(), expMultiExpBilGroup.getG2()); + return new DebugGroup(totalBilGroup.getG2(), expMultiExpBilGroup.getG2()); } @Override public Group getGT() { - return new CountingGroup(totalBilGroup.getGT(), expMultiExpBilGroup.getGT()); + return new DebugGroup(totalBilGroup.getGT(), expMultiExpBilGroup.getGT()); } @Override @@ -141,7 +141,7 @@ public BilinearMap getBilinearMap() { public GroupHomomorphism getHomomorphismG2toG1() throws UnsupportedOperationException { if (pairingType != Type.TYPE_1 && pairingType != Type.TYPE_2) throw new UnsupportedOperationException("Didn't require existence of a group homomorphism"); - return new CountingHomomorphism( + return new DebugHomomorphism( totalBilGroup.getHomomorphismG2toG1(), expMultiExpBilGroup.getHomomorphismG2toG1() ); @@ -149,18 +149,18 @@ public GroupHomomorphism getHomomorphismG2toG1() throws UnsupportedOperationExce @Override public HashIntoGroup getHashIntoG1() throws UnsupportedOperationException { - return new HashIntoCountingGroup(totalBilGroup.getHashIntoG1(), expMultiExpBilGroup.getHashIntoG1()); + return new HashIntoDebugGroup(totalBilGroup.getHashIntoG1(), expMultiExpBilGroup.getHashIntoG1()); } @Override public HashIntoGroup getHashIntoG2() throws UnsupportedOperationException { - return new HashIntoCountingGroup(totalBilGroup.getHashIntoG2(), expMultiExpBilGroup.getHashIntoG2()); + return new HashIntoDebugGroup(totalBilGroup.getHashIntoG2(), expMultiExpBilGroup.getHashIntoG2()); } @Override public HashIntoGroup getHashIntoGT() throws UnsupportedOperationException { - return new HashIntoCountingGroup(totalBilGroup.getHashIntoGT(), expMultiExpBilGroup.getHashIntoGT()); + return new HashIntoDebugGroup(totalBilGroup.getHashIntoGT(), expMultiExpBilGroup.getHashIntoGT()); } @@ -183,7 +183,7 @@ public Representation getRepresentation() { public boolean equals(Object other) { if (this == other) return true; if (other == null || this.getClass() != other.getClass()) return false; - CountingBilinearGroup that = (CountingBilinearGroup) other; + DebugBilinearGroup that = (DebugBilinearGroup) other; return Objects.equals(totalBilGroup, that.totalBilGroup) && Objects.equals(expMultiExpBilGroup, that.expMultiExpBilGroup) && Objects.equals(bilMap, that.bilMap); @@ -213,9 +213,9 @@ public void resetNumPairings() { */ public void resetCounters() { resetNumPairings(); - ((CountingGroup) getG1()).resetCounters(); - ((CountingGroup) getG2()).resetCounters(); - ((CountingGroup) getGT()).resetCounters(); + ((DebugGroup) getG1()).resetCounters(); + ((DebugGroup) getG2()).resetCounters(); + ((DebugGroup) getGT()).resetCounters(); } /** diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearGroupImpl.java similarity index 76% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearGroupImpl.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearGroupImpl.java index a96e7442..2edbf345 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearGroupImpl.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.random.RandomGenerator; import org.cryptimeleon.math.serialization.Representation; @@ -20,12 +20,12 @@ * Allows for selecting between counting total group operations, or (multi-)exponentiations plus group operations * outside of (multi-)exponentiations. *

- * Usually, you should be using {@link CountingBilinearGroup} instead of this class as it provides pairing counting + * Usually, you should be using {@link DebugBilinearGroup} instead of this class as it provides pairing counting * capabilities and allows for tracking both kinds of group operation data at once. * - * @see CountingBilinearGroup + * @see DebugBilinearGroup */ -public class CountingBilinearGroupImpl implements BilinearGroupImpl { +public class DebugBilinearGroupImpl implements BilinearGroupImpl { /** * The security level offered by this bilinear group in number of bits. @@ -62,10 +62,10 @@ public class CountingBilinearGroupImpl implements BilinearGroupImpl { /** * The underlying bilinear map used for applying the pairing function and counting it. */ - CountingBilinearMapImpl bilinearMapImpl; + DebugBilinearMapImpl bilinearMapImpl; - public CountingBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType, int numPrimeFactors, - boolean enableExpCounting, boolean enableMultiExpCounting) { + public DebugBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType, int numPrimeFactors, + boolean enableExpCounting, boolean enableMultiExpCounting) { this.securityParameter = securityParameter; this.pairingType = pairingType; this.enableExpCounting = enableExpCounting; @@ -79,16 +79,16 @@ public CountingBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairi init(); } - public CountingBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType, int numPrimeFactors) { + public DebugBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType, int numPrimeFactors) { this(securityParameter, pairingType, numPrimeFactors, false, false); } - public CountingBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType) { + public DebugBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType) { this(securityParameter, pairingType, 1); } - public CountingBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType, BigInteger size, - boolean enableExpCounting, boolean enableMultiExpCounting) { + public DebugBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairingType, BigInteger size, + boolean enableExpCounting, boolean enableMultiExpCounting) { this.securityParameter = securityParameter; this.pairingType = pairingType; this.enableExpCounting = enableExpCounting; @@ -98,10 +98,10 @@ public CountingBilinearGroupImpl(int securityParameter, BilinearGroup.Type pairi } protected void init() { - bilinearMapImpl = new CountingBilinearMapImpl(pairingType, size, enableExpCounting, enableMultiExpCounting); + bilinearMapImpl = new DebugBilinearMapImpl(pairingType, size, enableExpCounting, enableMultiExpCounting); } - public CountingBilinearGroupImpl(Representation repr) { + public DebugBilinearGroupImpl(Representation repr) { ReprUtil.deserialize(this, repr); init(); } @@ -110,7 +110,7 @@ public CountingBilinearGroupImpl(Representation repr) { public boolean equals(Object other) { if (this == other) return true; if (other == null || this.getClass() != other.getClass()) return false; - CountingBilinearGroupImpl that = (CountingBilinearGroupImpl) other; + DebugBilinearGroupImpl that = (DebugBilinearGroupImpl) other; return Objects.equals(pairingType, that.pairingType) && Objects.equals(size, that.size) && Objects.equals(enableExpCounting, that.enableExpCounting) @@ -128,17 +128,17 @@ public Representation getRepresentation() { } @Override - public CountingGroupImpl getG1() { + public DebugGroupImpl getG1() { return bilinearMapImpl.g1; } @Override - public CountingGroupImpl getG2() { + public DebugGroupImpl getG2() { return bilinearMapImpl.g2; } @Override - public CountingGroupImpl getGT() { + public DebugGroupImpl getGT() { return bilinearMapImpl.gt; } @@ -151,22 +151,22 @@ public BilinearMapImpl getBilinearMap() { public GroupHomomorphismImpl getHomomorphismG2toG1() throws UnsupportedOperationException { if (pairingType != BilinearGroup.Type.TYPE_1 && pairingType != BilinearGroup.Type.TYPE_2) throw new UnsupportedOperationException("Didn't require existence of a group homomorphism"); - return new CountingIsomorphismImpl(getG2(), getG1()); + return new DebugIsomorphismImpl(getG2(), getG1()); } @Override public HashIntoGroupImpl getHashIntoG1() throws UnsupportedOperationException { - return new HashIntoCountingGroupImpl(getG1()); + return new HashIntoDebugGroupImpl(getG1()); } @Override public HashIntoGroupImpl getHashIntoG2() throws UnsupportedOperationException { - return new HashIntoCountingGroupImpl(getG2()); + return new HashIntoDebugGroupImpl(getG2()); } @Override public HashIntoGroupImpl getHashIntoGT() throws UnsupportedOperationException { - return new HashIntoCountingGroupImpl(getGT()); + return new HashIntoDebugGroupImpl(getGT()); } /** diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearMap.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearMap.java similarity index 68% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearMap.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearMap.java index d0164316..03fbaea5 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearMap.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearMap.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.serialization.annotations.ReprUtil; @@ -24,52 +24,52 @@ * It is insecure since DLOG is trivial in Zn. *

* The counting capability is implemented by wrapping two {@link LazyBilinearMap}s which contain - * {@link CountingBilinearGroupImpl}s themselves. All operations are executed in both groups, + * {@link DebugBilinearGroupImpl}s themselves. All operations are executed in both groups, * one counts total group operations and one counts each (multi-)exponentiation as one unit. * This allows for tracking both kinds of data. * - * @see CountingBilinearGroup + * @see DebugBilinearGroup */ -public class CountingBilinearMap implements BilinearMap { +public class DebugBilinearMap implements BilinearMap { @Represented LazyBilinearMap totalBilMap; @Represented LazyBilinearMap expMultiExpBilMap; - public CountingBilinearMap(LazyBilinearMap totalBilMap, LazyBilinearMap expMultiExpBilMap) { + public DebugBilinearMap(LazyBilinearMap totalBilMap, LazyBilinearMap expMultiExpBilMap) { this.totalBilMap = totalBilMap; this.expMultiExpBilMap = expMultiExpBilMap; } - public CountingBilinearMap(Representation repr) { + public DebugBilinearMap(Representation repr) { ReprUtil.deserialize(this, repr); } @Override public Group getG1() { - return new CountingGroup((LazyGroup) totalBilMap.getG1(), (LazyGroup) expMultiExpBilMap.getG1()); + return new DebugGroup((LazyGroup) totalBilMap.getG1(), (LazyGroup) expMultiExpBilMap.getG1()); } @Override public Group getG2() { - return new CountingGroup((LazyGroup) totalBilMap.getG2(), (LazyGroup) expMultiExpBilMap.getG2()); + return new DebugGroup((LazyGroup) totalBilMap.getG2(), (LazyGroup) expMultiExpBilMap.getG2()); } @Override public Group getGT() { - return new CountingGroup((LazyGroup) totalBilMap.getGT(), (LazyGroup) expMultiExpBilMap.getGT()); + return new DebugGroup((LazyGroup) totalBilMap.getGT(), (LazyGroup) expMultiExpBilMap.getGT()); } @Override public GroupElement apply(GroupElement g1, GroupElement g2, BigInteger exponent) { - CountingGroupElement g1Cast = (CountingGroupElement) g1; - CountingGroupElement g2Cast = (CountingGroupElement) g2; + DebugGroupElement g1Cast = (DebugGroupElement) g1; + DebugGroupElement g2Cast = (DebugGroupElement) g2; LazyGroupElement g1Result = (LazyGroupElement) totalBilMap.apply(g1Cast.elemTotal, g2Cast.elemTotal, exponent); LazyGroupElement g2Result = (LazyGroupElement) expMultiExpBilMap.apply(g1Cast.elemExpMultiExp, g2Cast.elemExpMultiExp, exponent); - return new CountingGroupElement( - (CountingGroup) getGT(), + return new DebugGroupElement( + (DebugGroup) getGT(), g1Result, g2Result ); @@ -79,13 +79,13 @@ public GroupElement apply(GroupElement g1, GroupElement g2, BigInteger exponent) public GroupElement apply(GroupElement g1, GroupElement g2) { // We overwrite this to prevent the default method from BilinearMap to be used which would // execute an exponentiation with exponent one. This introduces an unnecessary exponentiation into the counting. - CountingGroupElement g1Cast = (CountingGroupElement) g1; - CountingGroupElement g2Cast = (CountingGroupElement) g2; + DebugGroupElement g1Cast = (DebugGroupElement) g1; + DebugGroupElement g2Cast = (DebugGroupElement) g2; LazyGroupElement g1Result = (LazyGroupElement) totalBilMap.apply(g1Cast.elemTotal, g2Cast.elemTotal); LazyGroupElement g2Result = (LazyGroupElement) expMultiExpBilMap.apply(g1Cast.elemExpMultiExp, g2Cast.elemExpMultiExp); - return new CountingGroupElement( - (CountingGroup) getGT(), + return new DebugGroupElement( + (DebugGroup) getGT(), g1Result, g2Result ); @@ -100,7 +100,7 @@ public boolean isSymmetric() { public boolean equals(Object other) { if (this == other) return true; if (other == null || this.getClass() != other.getClass()) return false; - CountingBilinearMap that = (CountingBilinearMap) other; + DebugBilinearMap that = (DebugBilinearMap) other; return Objects.equals(totalBilMap, that.totalBilMap) && Objects.equals(expMultiExpBilMap, that.expMultiExpBilMap); } @@ -115,31 +115,31 @@ public int hashCode() { */ public long getNumPairings() { // one of them suffices since both count - return ((CountingBilinearMapImpl) totalBilMap.getImpl()).getNumPairings(); + return ((DebugBilinearMapImpl) totalBilMap.getImpl()).getNumPairings(); } /** * Resets pairing counter. */ public void resetNumPairings() { - ((CountingBilinearMapImpl) totalBilMap.getImpl()).resetNumPairings(); - ((CountingBilinearMapImpl) expMultiExpBilMap.getImpl()).resetNumPairings(); + ((DebugBilinearMapImpl) totalBilMap.getImpl()).resetNumPairings(); + ((DebugBilinearMapImpl) expMultiExpBilMap.getImpl()).resetNumPairings(); } @Override public String toString() { if (isSymmetric()) { - return "Symmetric CountingBilinearMap(" + totalBilMap + ";" + expMultiExpBilMap + ")"; + return "Symmetric " + this.getClass().getSimpleName() + "(" + totalBilMap + ";" + expMultiExpBilMap + ")"; } else { - return "Asymmetric CountingBilinearMap(" + totalBilMap + ";" + expMultiExpBilMap + ")"; + return "Asymmetric " + this.getClass().getSimpleName() + "(" + totalBilMap + ";" + expMultiExpBilMap + ")"; } } public String formatCounterData() { return "---------- Operation data for " + toString() + "----------\n" - + ((CountingGroup) getG1()).formatCounterData() - + ((isSymmetric()) ? "" : ((CountingGroup) getG2()).formatCounterData()) - + ((CountingGroup) getGT()).formatCounterData() + + ((DebugGroup) getG1()).formatCounterData() + + ((isSymmetric()) ? "" : ((DebugGroup) getG2()).formatCounterData()) + + ((DebugGroup) getGT()).formatCounterData() + "------- Number of pairings: " + getNumPairings() + " -------"; } } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearMapImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearMapImpl.java similarity index 73% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearMapImpl.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearMapImpl.java index 49177ae0..f828b40f 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingBilinearMapImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugBilinearMapImpl.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.structures.groups.GroupElementImpl; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroup; @@ -16,11 +16,11 @@ * (multiplication in Zn). * It is insecure since DLOG is trivial in Zn. */ -public class CountingBilinearMapImpl implements BilinearMapImpl { +public class DebugBilinearMapImpl implements BilinearMapImpl { /** * The groups underlying the bilinear group. */ - protected CountingGroupImpl g1, g2, gt; + protected DebugGroupImpl g1, g2, gt; /** * Zn of order the bilinear group's size. @@ -55,17 +55,17 @@ public class CountingBilinearMapImpl implements BilinearMapImpl { * the former is not done and group operations within multi-exponentiations * are added to the total count */ - public CountingBilinearMapImpl(BilinearGroup.Type type, BigInteger groupSize, boolean enableExpCounting, - boolean enableMultiExpCounting) { + public DebugBilinearMapImpl(BilinearGroup.Type type, BigInteger groupSize, boolean enableExpCounting, + boolean enableMultiExpCounting) { this.size = groupSize; this.zn = new Zn(groupSize); this.pairingType = type; - g1 = new CountingGroupImpl("G1", groupSize, enableExpCounting, enableMultiExpCounting); + g1 = new DebugGroupImpl("G1", groupSize, enableExpCounting, enableMultiExpCounting); if (type == BilinearGroup.Type.TYPE_1) g2 = g1; else - g2 = new CountingGroupImpl("G2", groupSize, enableExpCounting, enableMultiExpCounting); - gt = new CountingGroupImpl("GT", groupSize, enableExpCounting, enableMultiExpCounting); + g2 = new DebugGroupImpl("G2", groupSize, enableExpCounting, enableMultiExpCounting); + gt = new DebugGroupImpl("GT", groupSize, enableExpCounting, enableMultiExpCounting); numPairings = 0; } @@ -76,14 +76,14 @@ public GroupElementImpl apply(GroupElementImpl g1, GroupElementImpl g2, BigInteg @Override public GroupElementImpl apply(GroupElementImpl g1, GroupElementImpl g2) { - if (!(g1 instanceof CountingGroupElementImpl) || !((CountingGroupElementImpl) g1).group.equals(this.g1)) + if (!(g1 instanceof DebugGroupElementImpl) || !((DebugGroupElementImpl) g1).group.equals(this.g1)) throw new IllegalArgumentException("first pairing argument is not in " + this.g1.name + ". It's in " - + (!(g1 instanceof CountingGroupElementImpl) ? g1.getStructure() : g1 == null ? null : ((CountingGroupElementImpl) g1).group.name)); - if (!(g2 instanceof CountingGroupElementImpl) || !((CountingGroupElementImpl) g2).group.equals(this.g2)) + + (!(g1 instanceof DebugGroupElementImpl) ? g1.getStructure() : g1 == null ? null : ((DebugGroupElementImpl) g1).group.name)); + if (!(g2 instanceof DebugGroupElementImpl) || !((DebugGroupElementImpl) g2).group.equals(this.g2)) throw new IllegalArgumentException("first pairing argument is not in " + this.g2.name + ". It's in " - + (!(g2 instanceof CountingGroupElementImpl) ? g2.getStructure() : g2 == null ? null : ((CountingGroupElementImpl) g2).group.name)); + + (!(g2 instanceof DebugGroupElementImpl) ? g2.getStructure() : g2 == null ? null : ((DebugGroupElementImpl) g2).group.name)); - GroupElementImpl result = gt.wrap(((CountingGroupElementImpl) g1).elem.mul(((CountingGroupElementImpl) g2).elem)); + GroupElementImpl result = gt.wrap(((DebugGroupElementImpl) g1).elem.mul(((DebugGroupElementImpl) g2).elem)); incrementNumPairings(); return result; } @@ -102,7 +102,7 @@ public boolean isSymmetric() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - CountingBilinearMapImpl that = (CountingBilinearMapImpl) o; + DebugBilinearMapImpl that = (DebugBilinearMapImpl) o; return pairingType == that.pairingType && Objects.equals(size, that.size); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroup.java similarity index 76% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroup.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroup.java index b30151c0..5ae8c655 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroup.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroup.java @@ -1,11 +1,10 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.serialization.annotations.ReprUtil; import org.cryptimeleon.math.serialization.annotations.Represented; import org.cryptimeleon.math.structures.groups.Group; import org.cryptimeleon.math.structures.groups.GroupElement; -import org.cryptimeleon.math.structures.groups.lazy.ConstLazyGroupElement; import org.cryptimeleon.math.structures.groups.lazy.LazyGroup; import org.cryptimeleon.math.structures.groups.lazy.LazyGroupElement; import org.cryptimeleon.math.structures.rings.zn.Zn; @@ -19,11 +18,11 @@ * Zn-based group that supports counting group operations, inversions, squarings and exponentiations as well as * number of terms in each multi-exponentiation. *

- * This counting capability is realized by using two {@link LazyGroup}s that each wrap a {@link CountingGroupImpl}. + * This counting capability is realized by using two {@link LazyGroup}s that each wrap a {@link DebugGroupImpl}. * One counts total group operations and squarings, and the other counts (multi-)exponentiations as a single unit * (not including group operations and squarings done inside (multi-)exponentiations). */ -public class CountingGroup implements Group { +public class DebugGroup implements Group { /** * Tracks total numbers, meaning that group operations done in (multi-)exp algorithms are also tracked. @@ -45,32 +44,32 @@ public class CountingGroup implements Group { * @param name the name of the group * @param n the desired size of the group */ - public CountingGroup(String name, BigInteger n) { - groupTotal = new LazyGroup(new CountingGroupImpl(name, n, false, false)); - groupExpMultiExp = new LazyGroup(new CountingGroupImpl(name, n, true, true)); + public DebugGroup(String name, BigInteger n) { + groupTotal = new LazyGroup(new DebugGroupImpl(name, n, false, false)); + groupExpMultiExp = new LazyGroup(new DebugGroupImpl(name, n, true, true)); } - public CountingGroup(String name, long n) { + public DebugGroup(String name, long n) { this(name, BigInteger.valueOf(n)); } /** - * This constructor allows instantiating the {@link CountingGroup} with specific {@link LazyGroup} instances. + * This constructor allows instantiating the {@link DebugGroup} with specific {@link LazyGroup} instances. * This can, for example, be used to change the choice of (multi-)exponentiation algorithm by configuring * the {@link LazyGroup} instances to use a different (multi-)exponentiation algorithm. */ - public CountingGroup(LazyGroup groupTotal, LazyGroup groupExpMultiExp) { + public DebugGroup(LazyGroup groupTotal, LazyGroup groupExpMultiExp) { this.groupTotal = groupTotal; this.groupExpMultiExp = groupExpMultiExp; } - public CountingGroup(Representation repr) { + public DebugGroup(Representation repr) { new ReprUtil(this).deserialize(repr); } @Override public GroupElement getNeutralElement() { - return new CountingGroupElement( + return new DebugGroupElement( this, (LazyGroupElement) groupTotal.getNeutralElement(), (LazyGroupElement) groupExpMultiExp.getNeutralElement() @@ -89,7 +88,7 @@ public Zn getZn() { @Override public GroupElement getUniformlyRandomElement() throws UnsupportedOperationException { - return new CountingGroupElement( + return new DebugGroupElement( this, (LazyGroupElement) groupTotal.getUniformlyRandomElement(), (LazyGroupElement) groupExpMultiExp.getUniformlyRandomElement() @@ -98,14 +97,14 @@ public GroupElement getUniformlyRandomElement() throws UnsupportedOperationExcep @Override public GroupElement restoreElement(Representation repr) { - return new CountingGroupElement(this, repr); + return new DebugGroupElement(this, repr); } - public CountingGroupElement wrap(Zn.ZnElement elem) { - return new CountingGroupElement( + public DebugGroupElement wrap(Zn.ZnElement elem) { + return new DebugGroupElement( this, - new ConstLazyGroupElement(groupTotal, ((CountingGroupImpl) groupTotal.getImpl()).wrap(elem)), - new ConstLazyGroupElement(groupExpMultiExp, ((CountingGroupImpl) groupExpMultiExp.getImpl()).wrap(elem)) + groupTotal.wrap(((DebugGroupImpl) groupTotal.getImpl()).wrap(elem)), + groupExpMultiExp.wrap(((DebugGroupImpl) groupExpMultiExp.getImpl()).wrap(elem)) ); } @@ -134,14 +133,14 @@ public Representation getRepresentation() { * Retrieves number of group squarings including ones done in (multi-)exponentiation algorithms. */ public long getNumSquaringsTotal() { - return ((CountingGroupImpl) groupTotal.getImpl()).getNumSquarings(); + return ((DebugGroupImpl) groupTotal.getImpl()).getNumSquarings(); } /** * Retrieves number of group inversions including ones done in (multi-)exponentiation algorithms. */ public long getNumInversionsTotal() { - return ((CountingGroupImpl) groupTotal.getImpl()).getNumInversions(); + return ((DebugGroupImpl) groupTotal.getImpl()).getNumInversions(); } /** @@ -149,21 +148,21 @@ public long getNumInversionsTotal() { * Does not include squarings. */ public long getNumOpsTotal() { - return ((CountingGroupImpl) groupTotal.getImpl()).getNumOps(); + return ((DebugGroupImpl) groupTotal.getImpl()).getNumOps(); } /** * Retrieves number of group squarings not including ones done in (multi-)exponentiation algorithms. */ public long getNumSquaringsNoExpMultiExp() { - return ((CountingGroupImpl) groupExpMultiExp.getImpl()).getNumSquarings(); + return ((DebugGroupImpl) groupExpMultiExp.getImpl()).getNumSquarings(); } /** * Retrieves number of group inversions not including ones done in (multi-)exponentiation algorithms. */ public long getNumInversionsNoExpMultiExp() { - return ((CountingGroupImpl) groupExpMultiExp.getImpl()).getNumInversions(); + return ((DebugGroupImpl) groupExpMultiExp.getImpl()).getNumInversions(); } /** @@ -171,21 +170,21 @@ public long getNumInversionsNoExpMultiExp() { * Does not include squarings. */ public long getNumOpsNoExpMultiExp() { - return((CountingGroupImpl) groupExpMultiExp.getImpl()).getNumOps(); + return((DebugGroupImpl) groupExpMultiExp.getImpl()).getNumOps(); } /** * Retrieves number of group exponentiations done. */ public long getNumExps() { - return ((CountingGroupImpl) groupExpMultiExp.getImpl()).getNumExps(); + return ((DebugGroupImpl) groupExpMultiExp.getImpl()).getNumExps(); } /** * Retrieves number of terms of each multi-exponentiation done. */ public List getMultiExpTermNumbers() { - return ((CountingGroupImpl) groupExpMultiExp.getImpl()).getMultiExpTermNumbers(); + return ((DebugGroupImpl) groupExpMultiExp.getImpl()).getMultiExpTermNumbers(); } /** @@ -193,15 +192,15 @@ public List getMultiExpTermNumbers() { */ public long getNumRetrievedRepresentations() { // one of the groups suffices since we represent both elements - return ((CountingGroupImpl) groupTotal.getImpl()).getNumRetrievedRepresentations(); + return ((DebugGroupImpl) groupTotal.getImpl()).getNumRetrievedRepresentations(); } /** * Resets all counters. */ public void resetCounters() { - ((CountingGroupImpl) groupTotal.getImpl()).resetCounters(); - ((CountingGroupImpl) groupExpMultiExp.getImpl()).resetCounters(); + ((DebugGroupImpl) groupTotal.getImpl()).resetCounters(); + ((DebugGroupImpl) groupExpMultiExp.getImpl()).resetCounters(); } /** @@ -229,7 +228,7 @@ public String formatCounterData() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - CountingGroup other = (CountingGroup) o; + DebugGroup other = (DebugGroup) o; return Objects.equals(groupTotal, other.groupTotal) && Objects.equals(groupExpMultiExp, other.groupExpMultiExp); } @@ -241,6 +240,6 @@ public int hashCode() { @Override public String toString() { - return "CountingGroup(" + groupTotal + ";" + groupExpMultiExp + ")"; + return this.getClass().getSimpleName() + "(" + groupTotal + ";" + groupExpMultiExp + ")"; } } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupElement.java similarity index 84% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupElement.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupElement.java index f5110265..46412156 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupElement.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.hash.ByteAccumulator; import org.cryptimeleon.math.serialization.ObjectRepresentation; @@ -13,19 +13,19 @@ import java.util.Objects; /** - * An element of {@link CountingGroup}. + * An element of {@link DebugGroup}. *

- * As {@code CountingGroup} itself consists of two nested groups, {@code CountingGroupElement} also essentially + * As {@code DebugGroup} itself consists of two nested groups, {@code DebugGroupElement} also essentially * wraps two group elements, one for each nested group. Group operations are done for both. * - * @see CountingGroup + * @see DebugGroup */ -public class CountingGroupElement implements GroupElement { +public class DebugGroupElement implements GroupElement { /** * The group this element belongs to. */ - protected CountingGroup group; + protected DebugGroup group; /** * This element as a member of the group responsible for counting total group operations. @@ -44,13 +44,13 @@ public class CountingGroupElement implements GroupElement { * @param elemTotal the version of this group element belonging to the group counting total group operations * @param elemExpMultiExp the version of this group element belonging to the group counting (multi)-exponentiations */ - public CountingGroupElement(CountingGroup group, LazyGroupElement elemTotal, LazyGroupElement elemExpMultiExp) { + public DebugGroupElement(DebugGroup group, LazyGroupElement elemTotal, LazyGroupElement elemExpMultiExp) { this.group = group; this.elemTotal = elemTotal; this.elemExpMultiExp = elemExpMultiExp; } - public CountingGroupElement(CountingGroup group, Representation repr) { + public DebugGroupElement(DebugGroup group, Representation repr) { ObjectRepresentation objRepr = repr.obj(); this.group = group; elemTotal = (LazyGroupElement) group.groupTotal.restoreElement(objRepr.get("elemTotal")); @@ -67,7 +67,7 @@ public Representation getRepresentation() { @Override public Group getStructure() { - return new CountingGroup( + return new DebugGroup( (LazyGroup) elemTotal.getStructure(), (LazyGroup) elemExpMultiExp.getStructure() ); @@ -75,7 +75,7 @@ public Group getStructure() { @Override public GroupElement inv() { - return new CountingGroupElement( + return new DebugGroupElement( group, (LazyGroupElement) elemTotal.inv(), (LazyGroupElement) elemExpMultiExp.inv() @@ -88,8 +88,8 @@ public GroupElement op(Element e) throws IllegalArgumentException { throw new IllegalArgumentException("Argument element is null"); if (e.getClass() != this.getClass()) throw new IllegalArgumentException("Argument element is not a CountingGroupElement"); - CountingGroupElement other = (CountingGroupElement) e; - return new CountingGroupElement( + DebugGroupElement other = (DebugGroupElement) e; + return new DebugGroupElement( group, (LazyGroupElement) elemTotal.op(other.elemTotal), (LazyGroupElement) elemExpMultiExp.op(other.elemExpMultiExp) @@ -98,7 +98,7 @@ public GroupElement op(Element e) throws IllegalArgumentException { @Override public GroupElement pow(BigInteger exponent) { - return new CountingGroupElement( + return new DebugGroupElement( group, (LazyGroupElement) elemTotal.pow(exponent), (LazyGroupElement) elemExpMultiExp.pow(exponent) @@ -107,7 +107,7 @@ public GroupElement pow(BigInteger exponent) { @Override public GroupElement precomputePow() { - return new CountingGroupElement( + return new DebugGroupElement( group, (LazyGroupElement) elemTotal.precomputePow(), (LazyGroupElement) elemExpMultiExp.precomputePow() @@ -116,7 +116,7 @@ public GroupElement precomputePow() { @Override public GroupElement precomputePow(int windowSize) { - return new CountingGroupElement( + return new DebugGroupElement( group, (LazyGroupElement) elemTotal.precomputePow(windowSize), (LazyGroupElement) elemExpMultiExp.precomputePow(windowSize) @@ -131,7 +131,7 @@ public GroupElement precomputePow(int windowSize) { @Override public GroupElement compute() { // counting requires synchronization so we always do computeSync - return new CountingGroupElement( + return new DebugGroupElement( group, (LazyGroupElement) elemTotal.computeSync(), (LazyGroupElement) elemExpMultiExp.computeSync() @@ -140,7 +140,7 @@ public GroupElement compute() { @Override public GroupElement computeSync() { - return new CountingGroupElement( + return new DebugGroupElement( group, (LazyGroupElement) elemTotal.computeSync(), (LazyGroupElement) elemExpMultiExp.computeSync() @@ -161,7 +161,7 @@ public ByteAccumulator updateAccumulator(ByteAccumulator accumulator) { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - CountingGroupElement other = (CountingGroupElement) o; + DebugGroupElement other = (DebugGroupElement) o; return Objects.equals(group, other.group) && Objects.equals(elemTotal, other.elemTotal) && Objects.equals(elemExpMultiExp, other.elemExpMultiExp); diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupElementImpl.java similarity index 77% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupElementImpl.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupElementImpl.java index 242c1334..3e1618c8 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupElementImpl.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.hash.ByteAccumulator; import org.cryptimeleon.math.serialization.Representation; @@ -11,14 +11,14 @@ import java.util.Objects; /** - * An element of {@link CountingGroupImpl} able to count group operations, inversions and squarings + * An element of {@link DebugGroupImpl} able to count group operations, inversions and squarings * it is involved with. * The actual group operations are realized via a Zn element. * - * @see CountingGroupElement - * @see CountingGroupImpl + * @see DebugGroupElement + * @see DebugGroupImpl */ -public class CountingGroupElementImpl implements GroupElementImpl { +public class DebugGroupElementImpl implements GroupElementImpl { /** * The underlying Zn element that realizes the actual group operations. */ @@ -27,7 +27,7 @@ public class CountingGroupElementImpl implements GroupElementImpl { /** * The group this element belongs to. */ - protected CountingGroupImpl group; + protected DebugGroupImpl group; /** * Initializes this element as belonging to the given group and using the given Zn element for its group operations. @@ -35,7 +35,7 @@ public class CountingGroupElementImpl implements GroupElementImpl { * @param group The group this element belongs to. * @param elem The Zn element through which the group operations are done. */ - public CountingGroupElementImpl(CountingGroupImpl group, Zn.ZnElement elem) { + public DebugGroupElementImpl(DebugGroupImpl group, Zn.ZnElement elem) { this.elem = elem; this.group = group; } @@ -54,19 +54,19 @@ public GroupElementImpl inv() { /** * Allows to configure whether to count this operation. - * Helpful for the {@link CountingGroupImpl#multiexp(Multiexponentiation)} method. + * Helpful for the {@link DebugGroupImpl#multiexp(Multiexponentiation)} method. * @param count {@code true} if we want to count the operation, {@code false} otherwise */ protected GroupElementImpl op(GroupElementImpl e, boolean count) { - if (!(e instanceof CountingGroupElementImpl) || !((CountingGroupElementImpl) e).group.equals(group)) + if (!(e instanceof DebugGroupElementImpl) || !((DebugGroupElementImpl) e).group.equals(group)) throw new IllegalArgumentException("Incompatible groups. LHS: " + group.name + "(" + group.size() + "), RHS: " - + (e instanceof CountingGroupElementImpl ? ((CountingGroupElementImpl) e).group.name + "(" + ((CountingGroupElementImpl) e).group.size() + ")" + + (e instanceof DebugGroupElementImpl ? ((DebugGroupElementImpl) e).group.name + "(" + ((DebugGroupElementImpl) e).group.size() + ")" : e == null ? "null" : e.getStructure()) ); - GroupElementImpl result = group.wrap(elem.add(((CountingGroupElementImpl) e).elem)); + GroupElementImpl result = group.wrap(elem.add(((DebugGroupElementImpl) e).elem)); if (count) { if (this.equals(e)) { group.incrementNumSquarings(); @@ -84,7 +84,7 @@ public GroupElementImpl op(GroupElementImpl e) throws IllegalArgumentException { /** * Allows to configure whether to count this exponentiation. - * Helpful for the {@link CountingGroupImpl#multiexp(Multiexponentiation)} method. + * Helpful for the {@link DebugGroupImpl#multiexp(Multiexponentiation)} method. * @param k exponent * @param count {@code true} if we want to count the exponentiation, {@code false} otherwise */ @@ -126,7 +126,7 @@ public Representation getRepresentation() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - CountingGroupElementImpl that = (CountingGroupElementImpl) o; + DebugGroupElementImpl that = (DebugGroupElementImpl) o; return Objects.equals(elem, that.elem) && Objects.equals(group, that.group); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupImpl.java similarity index 92% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupImpl.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupImpl.java index 43d67dc3..e8ec6406 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugGroupImpl.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.serialization.annotations.ReprUtil; @@ -20,7 +20,7 @@ * Zn-based group that supports counting group operations, inversions, squarings and exponentiations as well as * number of terms in each multi-exponentiation. */ -public class CountingGroupImpl implements GroupImpl { +public class DebugGroupImpl implements GroupImpl { /** * Name of this group. Group elements between {@code CountingGroupElementImpl} instances only allow for group @@ -87,7 +87,7 @@ public class CountingGroupImpl implements GroupImpl { * and n * @param n the size of this group */ - public CountingGroupImpl(String name, BigInteger n) { + public DebugGroupImpl(String name, BigInteger n) { this(name, n, false, false); } @@ -105,7 +105,7 @@ public CountingGroupImpl(String name, BigInteger n) { * the former is not done and group operations within multi-exponentiations * are added to the total count */ - public CountingGroupImpl(String name, BigInteger n, boolean enableExpCounting, boolean enableMultiExpCounting) { + public DebugGroupImpl(String name, BigInteger n, boolean enableExpCounting, boolean enableMultiExpCounting) { zn = new Zn(n); this.name = name; this.enableExpCounting = enableExpCounting; @@ -118,7 +118,7 @@ public CountingGroupImpl(String name, BigInteger n, boolean enableExpCounting, b numRetrievedRepresentations = 0; } - public CountingGroupImpl(Representation repr) { + public DebugGroupImpl(Representation repr) { new ReprUtil(this).deserialize(repr); numInversions = 0; numOps = 0; @@ -172,7 +172,7 @@ public int hashCode() { public boolean equals(Object other) { if (this == other) return true; if (other == null || this.getClass() != other.getClass()) return false; - CountingGroupImpl that = (CountingGroupImpl) other; + DebugGroupImpl that = (DebugGroupImpl) other; return Objects.equals(name, that.name) && Objects.equals(zn, that.zn) && Objects.equals(enableExpCounting, that.enableExpCounting) @@ -218,11 +218,11 @@ public boolean implementsOwnMultiExp() { public GroupElementImpl multiexp(Multiexponentiation mexp) { // This method is only used if enableMultiExpCounting is set to true; hence, we count // the multi-exponentiation done. - CountingGroupElementImpl result = (CountingGroupElementImpl) mexp.getConstantFactor().orElse(getNeutralElement()); + DebugGroupElementImpl result = (DebugGroupElementImpl) mexp.getConstantFactor().orElse(getNeutralElement()); for (MultiExpTerm term : mexp.getTerms()) { // Use methods where we can disable counting since we only want to count the multi-exponentiation here - result = (CountingGroupElementImpl) result - .op(((CountingGroupElementImpl) term.getBase()).pow(term.getExponent(),false), false); + result = (DebugGroupElementImpl) result + .op(((DebugGroupElementImpl) term.getBase()).pow(term.getExponent(),false), false); } addMultiExpBaseNumber(mexp.getTerms().size()); return result; @@ -231,8 +231,8 @@ public GroupElementImpl multiexp(Multiexponentiation mexp) { /** * Wraps a {@code ZnElement} in a {@code CountingGroupElementImpl} belonging to this group. */ - public CountingGroupElementImpl wrap(Zn.ZnElement elem) { - return new CountingGroupElementImpl(this, elem); + public DebugGroupElementImpl wrap(Zn.ZnElement elem) { + return new DebugGroupElementImpl(this, elem); } @Override diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingHomomorphism.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugHomomorphism.java similarity index 64% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingHomomorphism.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugHomomorphism.java index 7fc198f6..bc3fec10 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingHomomorphism.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugHomomorphism.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.serialization.annotations.ReprUtil; @@ -10,21 +10,21 @@ import java.util.Objects; /** - * A homomorphism between two {@link CountingGroup}s. + * A homomorphism between two {@link DebugGroup}s. */ -public class CountingHomomorphism implements GroupHomomorphism { +public class DebugHomomorphism implements GroupHomomorphism { @Represented private LazyGroupHomomorphism totalHom; @Represented private LazyGroupHomomorphism expMultiExpHom; - public CountingHomomorphism(LazyGroupHomomorphism totalHom, LazyGroupHomomorphism expMultiExpHom) { + public DebugHomomorphism(LazyGroupHomomorphism totalHom, LazyGroupHomomorphism expMultiExpHom) { this.totalHom = totalHom; this.expMultiExpHom = expMultiExpHom; } - public CountingHomomorphism(Representation repr) { + public DebugHomomorphism(Representation repr) { new ReprUtil(this).deserialize(repr); } @@ -35,10 +35,10 @@ public Representation getRepresentation() { @Override public GroupElement apply(GroupElement groupElement) { - return new CountingGroupElement( - new CountingGroup(totalHom.getTargetGroup(), expMultiExpHom.getTargetGroup()), - totalHom.apply(((CountingGroupElement) groupElement).elemTotal), - expMultiExpHom.apply(((CountingGroupElement) groupElement).elemExpMultiExp) + return new DebugGroupElement( + new DebugGroup(totalHom.getTargetGroup(), expMultiExpHom.getTargetGroup()), + totalHom.apply(((DebugGroupElement) groupElement).elemTotal), + expMultiExpHom.apply(((DebugGroupElement) groupElement).elemExpMultiExp) ); } @@ -46,7 +46,7 @@ public GroupElement apply(GroupElement groupElement) { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - CountingHomomorphism that = (CountingHomomorphism) o; + DebugHomomorphism that = (DebugHomomorphism) o; return Objects.equals(totalHom, that.totalHom) && Objects.equals(expMultiExpHom, that.expMultiExpHom); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingIsomorphismImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugIsomorphismImpl.java similarity index 68% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingIsomorphismImpl.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugIsomorphismImpl.java index 4ff543e7..0adab5cd 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/CountingIsomorphismImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/DebugIsomorphismImpl.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.serialization.annotations.ReprUtil; @@ -9,20 +9,20 @@ import java.util.Objects; /** - * Implements an isomorphism between two {@link CountingGroupImpl}s. + * Implements an isomorphism between two {@link DebugGroupImpl}s. */ -public class CountingIsomorphismImpl implements GroupHomomorphismImpl { +public class DebugIsomorphismImpl implements GroupHomomorphismImpl { @Represented - private CountingGroupImpl src; + private DebugGroupImpl src; @Represented - private CountingGroupImpl target; + private DebugGroupImpl target; - public CountingIsomorphismImpl(CountingGroupImpl src, CountingGroupImpl target) { + public DebugIsomorphismImpl(DebugGroupImpl src, DebugGroupImpl target) { this.src = src; this.target = target; } - public CountingIsomorphismImpl(Representation repr) { + public DebugIsomorphismImpl(Representation repr) { new ReprUtil(this).deserialize(repr); } @@ -35,14 +35,14 @@ public Representation getRepresentation() { public GroupElementImpl apply(GroupElementImpl groupElement) { if (!groupElement.getStructure().equals(src)) throw new IllegalArgumentException("Tried to apply isomorphism on wrong group (argument was from " + groupElement.getStructure() + ")"); - return new CountingGroupElementImpl(target, ((CountingGroupElementImpl) groupElement).elem); + return new DebugGroupElementImpl(target, ((DebugGroupElementImpl) groupElement).elem); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - CountingIsomorphismImpl that = (CountingIsomorphismImpl) o; + DebugIsomorphismImpl that = (DebugIsomorphismImpl) o; return Objects.equals(src, that.src) && Objects.equals(target, that.target); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/HashIntoCountingGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/HashIntoDebugGroup.java similarity index 71% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/HashIntoCountingGroup.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/HashIntoDebugGroup.java index bbf63a49..2697eef8 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/HashIntoCountingGroup.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/HashIntoDebugGroup.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.serialization.annotations.ReprUtil; @@ -10,29 +10,29 @@ import java.util.Objects; /** - * Allows hashing a byte array to {@link CountingGroup}. + * Allows hashing a byte array to {@link DebugGroup}. */ -public class HashIntoCountingGroup implements HashIntoGroup { +public class HashIntoDebugGroup implements HashIntoGroup { @Represented private HashIntoLazyGroup totalHashIntoGroup; @Represented private HashIntoLazyGroup expMultiExpHashIntoGroup; - public HashIntoCountingGroup(HashIntoLazyGroup totalHashIntoStructure, - HashIntoLazyGroup expMultiExpHashIntoStructure) { + public HashIntoDebugGroup(HashIntoLazyGroup totalHashIntoStructure, + HashIntoLazyGroup expMultiExpHashIntoStructure) { this.totalHashIntoGroup = totalHashIntoStructure; this.expMultiExpHashIntoGroup = expMultiExpHashIntoStructure; } - public HashIntoCountingGroup(Representation repr) { + public HashIntoDebugGroup(Representation repr) { new ReprUtil(this).deserialize(repr); } @Override public GroupElement hash(byte[] x) { - return new CountingGroupElement( - new CountingGroup(totalHashIntoGroup.getTarget(), expMultiExpHashIntoGroup.getTarget()), + return new DebugGroupElement( + new DebugGroup(totalHashIntoGroup.getTarget(), expMultiExpHashIntoGroup.getTarget()), totalHashIntoGroup.hash(x), expMultiExpHashIntoGroup.hash(x) ); @@ -47,7 +47,7 @@ public Representation getRepresentation() { public boolean equals(Object other) { if (this == other) return true; if (other == null || this.getClass() != other.getClass()) return false; - HashIntoCountingGroup that = (HashIntoCountingGroup) other; + HashIntoDebugGroup that = (HashIntoDebugGroup) other; return Objects.equals(totalHashIntoGroup, that.totalHashIntoGroup) && Objects.equals(expMultiExpHashIntoGroup, that.expMultiExpHashIntoGroup); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/counting/HashIntoCountingGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/HashIntoDebugGroupImpl.java similarity index 65% rename from src/main/java/org/cryptimeleon/math/structures/groups/counting/HashIntoCountingGroupImpl.java rename to src/main/java/org/cryptimeleon/math/structures/groups/debug/HashIntoDebugGroupImpl.java index a39e25ee..5108b58d 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/counting/HashIntoCountingGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/HashIntoDebugGroupImpl.java @@ -1,4 +1,4 @@ -package org.cryptimeleon.math.structures.groups.counting; +package org.cryptimeleon.math.structures.groups.debug; import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.structures.groups.GroupElementImpl; @@ -8,19 +8,19 @@ import java.util.Objects; /** - * Allows hashing a byte array to a {@link CountingGroupImpl} via {@link HashIntoZn}. + * Allows hashing a byte array to a {@link DebugGroupImpl} via {@link HashIntoZn}. */ -public class HashIntoCountingGroupImpl implements HashIntoGroupImpl { - protected CountingGroupImpl group; +public class HashIntoDebugGroupImpl implements HashIntoGroupImpl { + protected DebugGroupImpl group; protected HashIntoZn hash; - public HashIntoCountingGroupImpl(CountingGroupImpl group) { + public HashIntoDebugGroupImpl(DebugGroupImpl group) { this.group = group; this.hash = new HashIntoZn(group.size()); } - public HashIntoCountingGroupImpl(Representation repr) { - this(new CountingGroupImpl(repr)); + public HashIntoDebugGroupImpl(Representation repr) { + this(new DebugGroupImpl(repr)); } @Override @@ -32,7 +32,7 @@ public Representation getRepresentation() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - HashIntoCountingGroupImpl that = (HashIntoCountingGroupImpl) o; + HashIntoDebugGroupImpl that = (HashIntoDebugGroupImpl) o; return Objects.equals(group, that.group); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/debug/package-info.java b/src/main/java/org/cryptimeleon/math/structures/groups/debug/package-info.java new file mode 100644 index 00000000..d1edc370 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/structures/groups/debug/package-info.java @@ -0,0 +1,8 @@ +/** + * Contains an implementation of a fast, but insecure, bilinear pairing. + * Also allows for counting group operations and pairings. + *

+ * The non-impl classes should be preferred unless you specifically need the impl class, + * e.g. for testing a specific {@link org.cryptimeleon.math.structures.groups.Group}. + */ +package org.cryptimeleon.math.structures.groups.debug; \ No newline at end of file diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/AbstractPairing.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/AbstractPairing.java index 08e1ce16..76e5fc3d 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/AbstractPairing.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/AbstractPairing.java @@ -1,8 +1,5 @@ package org.cryptimeleon.math.structures.groups.elliptic; -import org.cryptimeleon.math.serialization.ObjectRepresentation; -import org.cryptimeleon.math.serialization.RepresentableRepresentation; -import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.structures.groups.GroupElementImpl; import org.cryptimeleon.math.structures.rings.FieldElement; import org.cryptimeleon.math.structures.rings.extfield.ExtensionField; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/nopairing/Secp256k1.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/nopairing/Secp256k1.java index 47c5af5f..5b11e56e 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/nopairing/Secp256k1.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/nopairing/Secp256k1.java @@ -165,7 +165,7 @@ public int hashCode() { } /** - * A hash function mapping bit strings into the group such that + * A hash function mapping bit strings into Secp256k1. */ public static class HashIntoSecp256k1 implements HashIntoGroupImpl { private final HashIntoZp hash; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularBasicBilinearGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularBasicBilinearGroup.java new file mode 100644 index 00000000..09a1f9dc --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularBasicBilinearGroup.java @@ -0,0 +1,20 @@ +package org.cryptimeleon.math.structures.groups.elliptic.type1.supersingular; + +import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.structures.groups.basic.BasicBilinearGroup; + +/** + * A type 1 supersingular bilinear group where operations are evaluated naively, that is, not lazily. + * + * @see SupersingularBilinearGroup for the version with lazy evaluation + */ +public class SupersingularBasicBilinearGroup extends BasicBilinearGroup { + + public SupersingularBasicBilinearGroup(int securityParameter) { + super(new SupersingularTateGroupImpl(securityParameter)); + } + + public SupersingularBasicBilinearGroup(Representation repr) { + super(repr); + } +} diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularBilinearGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularBilinearGroup.java index 01a445ea..f7049ebf 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularBilinearGroup.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularBilinearGroup.java @@ -4,11 +4,12 @@ import org.cryptimeleon.math.structures.groups.lazy.LazyBilinearGroup; /** - * Offers a less verbose way to instantiate a Supersingular bilinear group which uses lazy evaluation. + * A type 1 supersingular bilinear group where operations are evaluated lazily. *

- * Essentially just a {@link LazyBilinearGroup} wrapper around {@link SupersingularTateGroupImpl}. + * Due to lazy evaluation, this group is more efficient than its non-lazy counterpart + * {@link SupersingularBasicBilinearGroup}. * - * @see SupersingularTateGroupImpl + * @see SupersingularBasicBilinearGroup for the version without lazy evaluation */ public class SupersingularBilinearGroup extends LazyBilinearGroup { diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupElementImpl.java index a1e04125..1a24d417 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupElementImpl.java @@ -8,7 +8,7 @@ * * @see SupersingularSourceGroupImpl */ -public class SupersingularSourceGroupElementImpl extends PairingSourceGroupElement { +class SupersingularSourceGroupElementImpl extends PairingSourceGroupElement { public SupersingularSourceGroupElementImpl(SupersingularSourceGroupImpl curve, FieldElement x, FieldElement y) { super(curve, x, y); diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupImpl.java index 90abb50c..18195bff 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceGroupImpl.java @@ -17,7 +17,7 @@ * Let \(E := {(x,y) \in \mathbb{F}_q \times \mathbb{F}_q | y^2 = x^3 - 3x}\) (\(q\) prime and \(q = 3 \mod 4\)). * Then this class represents E[getSize()], i.e. the subgroup of size getSize(). */ -public class SupersingularSourceGroupImpl extends PairingSourceGroupImpl { +class SupersingularSourceGroupImpl extends PairingSourceGroupImpl { /** * Instantiates the group. diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceHash.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceHash.java index 478398e2..74c077b7 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceHash.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularSourceHash.java @@ -9,7 +9,7 @@ import org.cryptimeleon.math.structures.rings.extfield.ExtensionFieldElement; import org.cryptimeleon.math.structures.rings.zn.HashIntoZn; -public class SupersingularSourceHash implements HashIntoGroupImpl { +class SupersingularSourceHash implements HashIntoGroupImpl { private SupersingularSourceGroupImpl codomain; public SupersingularSourceHash(SupersingularSourceGroupImpl codomain) { diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupElementImpl.java index febf658b..abbcc30f 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupElementImpl.java @@ -7,7 +7,7 @@ /** * @see PairingTargetGroupElementImpl */ -public class SupersingularTargetGroupElementImpl extends PairingTargetGroupElementImpl { +class SupersingularTargetGroupElementImpl extends PairingTargetGroupElementImpl { public SupersingularTargetGroupElementImpl(PairingTargetGroupImpl g, ExtensionFieldElement fe) { super(g, fe); diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupImpl.java index d843ad06..719e47d9 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTargetGroupImpl.java @@ -11,7 +11,7 @@ /** * @see PairingTargetGroupImpl */ -public class SupersingularTargetGroupImpl extends PairingTargetGroupImpl { +class SupersingularTargetGroupImpl extends PairingTargetGroupImpl { public SupersingularTargetGroupImpl(ExtensionField f, BigInteger size) { super(f, size); diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTateGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTateGroupImpl.java index 81eca2c4..79a94530 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTateGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTateGroupImpl.java @@ -20,7 +20,7 @@ /** * The implementation of our supersingular bilinear group. */ -public class SupersingularTateGroupImpl implements BilinearGroupImpl { +class SupersingularTateGroupImpl implements BilinearGroupImpl { @Represented private Integer securityParameter; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTatePairing.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTatePairing.java index 236d760c..0ef478c0 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTatePairing.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type1/supersingular/SupersingularTatePairing.java @@ -1,6 +1,5 @@ package org.cryptimeleon.math.structures.groups.elliptic.type1.supersingular; -import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.structures.groups.elliptic.AbstractPairing; import org.cryptimeleon.math.structures.groups.elliptic.PairingSourceGroupElement; import org.cryptimeleon.math.structures.rings.FieldElement; @@ -10,7 +9,7 @@ /** * Tate-pairing implementation for the supersingular bilinear group. */ -public class SupersingularTatePairing extends AbstractPairing { +class SupersingularTatePairing extends AbstractPairing { //SupersingularTypeADistortionMap distortionMap; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBasicBilinearGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBasicBilinearGroup.java new file mode 100644 index 00000000..f6f8ddd1 --- /dev/null +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBasicBilinearGroup.java @@ -0,0 +1,28 @@ +package org.cryptimeleon.math.structures.groups.elliptic.type3.bn; + +import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.structures.groups.basic.BasicBilinearGroup; + +/** + * A type 1 supersingular bilinear group where operations are evaluated naively, that is, not lazily. + * + * @see BarretoNaehrigBilinearGroup for the version with lazy evaluation + */ +public class BarretoNaehrigBasicBilinearGroup extends BasicBilinearGroup { + + public BarretoNaehrigBasicBilinearGroup(int securityParameter) { + super(new BarretoNaehrigBilinearGroupImpl(securityParameter)); + } + + public BarretoNaehrigBasicBilinearGroup(String spec) { + super(new BarretoNaehrigBilinearGroupImpl(spec)); + } + + public BarretoNaehrigBasicBilinearGroup(BarretoNaehrigParameterSpec spec) { + super(new BarretoNaehrigBilinearGroupImpl(spec)); + } + + public BarretoNaehrigBasicBilinearGroup(Representation repr) { + super(repr); + } +} diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroup.java index 310df113..2eb6f0d4 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroup.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroup.java @@ -4,11 +4,9 @@ import org.cryptimeleon.math.structures.groups.lazy.LazyBilinearGroup; /** - * Offers a less verbose way to instantiate a Barreto-Naehrig bilinear group which uses lazy evaluation. - *

- * Essentially just a {@link LazyBilinearGroup} wrapper around {@link BarretoNaehrigBilinearGroupImpl}. + * A type 1 supersingular bilinear group where operations are evaluated lazily. * - * @see BarretoNaehrigTargetGroupImpl + * @see BarretoNaehrigBasicBilinearGroup for the version without lazy evaluation */ public class BarretoNaehrigBilinearGroup extends LazyBilinearGroup { diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroupImpl.java index 0bb78928..5a6680bf 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigBilinearGroupImpl.java @@ -34,7 +34,7 @@ * with \(\mathbb{G}_2\) a subgroup of size \(n\) in \(E':y^2=x^3+b'\) * */ -public class BarretoNaehrigBilinearGroupImpl implements BilinearGroupImpl { +class BarretoNaehrigBilinearGroupImpl implements BilinearGroupImpl { @Represented private Integer securityParameter; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1ElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1ElementImpl.java index 89f75484..a65a61e3 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1ElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1ElementImpl.java @@ -5,7 +5,7 @@ /** * Element of G1. */ -public class BarretoNaehrigGroup1ElementImpl extends BarretoNaehrigSourceGroupElementImpl { +class BarretoNaehrigGroup1ElementImpl extends BarretoNaehrigSourceGroupElementImpl { /** * Construct point on given curve with given x- and y-coordinates. diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1Impl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1Impl.java index df3f6335..5b377187 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1Impl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup1Impl.java @@ -9,7 +9,7 @@ /** * G1 in the Barreto-Naehrig bilinear group. */ -public class BarretoNaehrigGroup1Impl extends BarretoNaehrigSourceGroupImpl { +class BarretoNaehrigGroup1Impl extends BarretoNaehrigSourceGroupImpl { /** * Construct subgroup of E:y^2=x^3+a6 using given parameters. * diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2ElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2ElementImpl.java index e3a0cb24..8ab9180b 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2ElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2ElementImpl.java @@ -5,7 +5,7 @@ /** * Element of G2. */ -public class BarretoNaehrigGroup2ElementImpl extends BarretoNaehrigSourceGroupElementImpl { +class BarretoNaehrigGroup2ElementImpl extends BarretoNaehrigSourceGroupElementImpl { /** * Construct point on given curve with given x- and y-coordinates. * diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2Impl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2Impl.java index a007bbb4..0d7a6200 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2Impl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigGroup2Impl.java @@ -10,7 +10,7 @@ /** * G2 in the Barreto-Naehrig bilinear group. */ -public class BarretoNaehrigGroup2Impl extends BarretoNaehrigSourceGroupImpl { +class BarretoNaehrigGroup2Impl extends BarretoNaehrigSourceGroupImpl { /** * Construct subgroup of E:y^2=x^3+a6 using given parameters. diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigParameterSpec.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigParameterSpec.java index bedaf7ee..7b5fcae8 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigParameterSpec.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigParameterSpec.java @@ -4,6 +4,11 @@ /** * Represents a fixed parametrization of a Barreto-Naehrig bilinear group. + * + * @see BarretoNaehrigBilinearGroup#BarretoNaehrigBilinearGroup(BarretoNaehrigParameterSpec) + * @see BarretoNaehrigBilinearGroup#BarretoNaehrigBilinearGroup(String) + * @see BarretoNaehrigBasicBilinearGroup#BarretoNaehrigBasicBilinearGroup(BarretoNaehrigParameterSpec) + * @see BarretoNaehrigBasicBilinearGroup#BarretoNaehrigBasicBilinearGroup(String) */ public class BarretoNaehrigParameterSpec { public final BigInteger u; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigPointEncoding.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigPointEncoding.java index fdf975a2..810b5a55 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigPointEncoding.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigPointEncoding.java @@ -20,7 +20,7 @@ /** * Hash function into G1 and G2. */ -public class BarretoNaehrigPointEncoding implements HashIntoGroupImpl { +class BarretoNaehrigPointEncoding implements HashIntoGroupImpl { @Represented private BarretoNaehrigSourceGroupImpl codomain; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupElementImpl.java index c314ab5a..7a996108 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupElementImpl.java @@ -8,7 +8,7 @@ /** * Abstract class for elements of both G1 and G2. */ -public abstract class BarretoNaehrigSourceGroupElementImpl extends PairingSourceGroupElement { +abstract class BarretoNaehrigSourceGroupElementImpl extends PairingSourceGroupElement { public BarretoNaehrigSourceGroupElementImpl(BarretoNaehrigSourceGroupImpl curve, FieldElement x, FieldElement y) { super(curve, x, y); diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupImpl.java index 971fd2dc..8c67f475 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigSourceGroupImpl.java @@ -15,7 +15,7 @@ *

* This class implements a subgroup of \(E:y^2=x^3+b\). */ -public abstract class BarretoNaehrigSourceGroupImpl extends PairingSourceGroupImpl { +abstract class BarretoNaehrigSourceGroupImpl extends PairingSourceGroupImpl { public BarretoNaehrigSourceGroupImpl(BigInteger size, BigInteger cofactor, ExtensionFieldElement a6) { super(size, cofactor, a6.getStructure().getZeroElement(), a6); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupElementImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupElementImpl.java index e509eb04..091241bf 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupElementImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupElementImpl.java @@ -8,7 +8,7 @@ /** * Element of target group GT. */ -public class BarretoNaehrigTargetGroupElementImpl extends PairingTargetGroupElementImpl { +class BarretoNaehrigTargetGroupElementImpl extends PairingTargetGroupElementImpl { public BarretoNaehrigTargetGroupElementImpl(BarretoNaehrigTargetGroupImpl g, ExtensionFieldElement fe) { super(g, fe); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupImpl.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupImpl.java index d32fda42..65182ed7 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupImpl.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTargetGroupImpl.java @@ -11,7 +11,7 @@ /** * Target group GT. */ -public class BarretoNaehrigTargetGroupImpl extends PairingTargetGroupImpl { +class BarretoNaehrigTargetGroupImpl extends PairingTargetGroupImpl { /** * Constructs a subgroup of given size in F12 where F12=F(v)=F[x]/(x^6+v). * diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTatePairing.java b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTatePairing.java index d00ef273..b6db3b9e 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTatePairing.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/elliptic/type3/bn/BarretoNaehrigTatePairing.java @@ -1,6 +1,5 @@ package org.cryptimeleon.math.structures.groups.elliptic.type3.bn; -import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.structures.groups.elliptic.AbstractPairing; import org.cryptimeleon.math.structures.groups.elliptic.PairingSourceGroupElement; import org.cryptimeleon.math.structures.groups.elliptic.PairingTargetGroupElementImpl; @@ -13,7 +12,7 @@ /** * Tate-pairing specific implementation of BN based pairings. */ -public class BarretoNaehrigTatePairing extends AbstractPairing { +class BarretoNaehrigTatePairing extends AbstractPairing { BigInteger lambda2, lambda1, lambda0; /** diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ConstLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ConstLazyGroupElement.java index 6680c20f..8e14408c 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ConstLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ConstLazyGroupElement.java @@ -5,7 +5,7 @@ /** * Represents a constant value. */ -public class ConstLazyGroupElement extends LazyGroupElement { +class ConstLazyGroupElement extends LazyGroupElement { public ConstLazyGroupElement(LazyGroup group, GroupElementImpl concreteValue) { super(group, concreteValue); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ExpLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ExpLazyGroupElement.java index f6220f5e..ebd24860 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ExpLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/ExpLazyGroupElement.java @@ -8,7 +8,7 @@ /** * Represents an exponentiation with a base and exponent. */ -public class ExpLazyGroupElement extends LazyGroupElement { +class ExpLazyGroupElement extends LazyGroupElement { LazyGroupElement base; BigInteger exponent; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HashResultLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HashResultLazyGroupElement.java index 4d53eb56..1fdda301 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HashResultLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HashResultLazyGroupElement.java @@ -3,7 +3,7 @@ /** * Represents the result of hashing a byte array to some structure. */ -public class HashResultLazyGroupElement extends LazyGroupElement { +class HashResultLazyGroupElement extends LazyGroupElement { protected byte[] preimage; protected HashIntoLazyGroup hash; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HomomorphismResultLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HomomorphismResultLazyGroupElement.java index 09b6033b..a476a0d9 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HomomorphismResultLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/HomomorphismResultLazyGroupElement.java @@ -3,7 +3,7 @@ /** * Represents the result of applying a group homomorphism to some group element. */ -public class HomomorphismResultLazyGroupElement extends LazyGroupElement { +class HomomorphismResultLazyGroupElement extends LazyGroupElement { protected LazyGroupElement preimage; protected LazyGroupHomomorphism homomorphism; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/InvLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/InvLazyGroupElement.java index a2701fb4..e46ca855 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/InvLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/InvLazyGroupElement.java @@ -3,7 +3,7 @@ /** * Represents the result of inverting a group element. */ -public class InvLazyGroupElement extends LazyGroupElement { +class InvLazyGroupElement extends LazyGroupElement { protected LazyGroupElement base; public InvLazyGroupElement(LazyGroup group, LazyGroupElement base) { diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/LazyGroup.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/LazyGroup.java index 8b711d6a..fc81681a 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/LazyGroup.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/LazyGroup.java @@ -86,7 +86,7 @@ public LazyGroup(Representation repr, int exponentiationWindowSize, int precompu init(); } - protected LazyGroupElement wrap(GroupElementImpl impl) { + public LazyGroupElement wrap(GroupElementImpl impl) { return new ConstLazyGroupElement(this, impl); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/NeutralLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/NeutralLazyGroupElement.java index aae09856..c96bbc8d 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/NeutralLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/NeutralLazyGroupElement.java @@ -6,7 +6,7 @@ /** * Represents the neutral group element in the lazy evaluation framework. */ -public class NeutralLazyGroupElement extends LazyGroupElement { +class NeutralLazyGroupElement extends LazyGroupElement { public NeutralLazyGroupElement(LazyGroup group) { super(group, group.impl.getNeutralElement()); } diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/OpLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/OpLazyGroupElement.java index f4105051..327fee19 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/OpLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/OpLazyGroupElement.java @@ -9,7 +9,7 @@ /** * Represents the result of a group operation. */ -public class OpLazyGroupElement extends LazyGroupElement { +class OpLazyGroupElement extends LazyGroupElement { LazyGroupElement lhs, rhs; GroupElementImpl accumulatedConstant = null; List terms = null; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/PairingResultLazyGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/PairingResultLazyGroupElement.java index ac82f1d8..0289c6fb 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/PairingResultLazyGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/PairingResultLazyGroupElement.java @@ -5,7 +5,7 @@ /** * Represents the result of a pairing evaluation. */ -public class PairingResultLazyGroupElement extends LazyGroupElement { +class PairingResultLazyGroupElement extends LazyGroupElement { protected LazyGroupElement lhs, rhs; protected LazyBilinearMap bilMap; diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomGroupElement.java index 7f443f8c..7c9f17a2 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomGroupElement.java @@ -5,7 +5,7 @@ /** * Represents the result of generating a group element unformly at random. */ -public class RandomGroupElement extends LazyGroupElement { +class RandomGroupElement extends LazyGroupElement { private GroupElementImpl value = null; public RandomGroupElement(LazyGroup group) { diff --git a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomNonNeutralGroupElement.java b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomNonNeutralGroupElement.java index 3140a45a..84b6e8aa 100644 --- a/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomNonNeutralGroupElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/groups/lazy/RandomNonNeutralGroupElement.java @@ -5,7 +5,7 @@ /** * Represents the result of generating a non-neutral group element uniformly at random. */ -public class RandomNonNeutralGroupElement extends LazyGroupElement { +class RandomNonNeutralGroupElement extends LazyGroupElement { private GroupElementImpl value = null; public RandomNonNeutralGroupElement(LazyGroup group) { diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/Ring.java b/src/main/java/org/cryptimeleon/math/structures/rings/Ring.java index 67bf0644..06ecfa5e 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/Ring.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/Ring.java @@ -14,7 +14,7 @@ import java.util.List; /** - * A algebraic ring with 1. + * An algebraic ring with 1. */ public interface Ring extends Structure, RepresentationRestorer { /** @@ -262,6 +262,20 @@ default ArrayList extendedEuclideanAlgorithm(List elem return result; } + /** + * Estimates the number of inversions that can be done per group operation for the same cost. + * For example, {@code 2} would mean that an inversion costs half as much as a group operation, on average. + * @return estimated number of inversions that can be done per group operation for the same cost + */ + double estimateCostInvPerOp(); + + /** + * Estimates the number of negations (additive inversions) that can be done per group operation for the same cost. + * For example, {@code 2} would mean that a negation costs half as much as a group operation, on average. + * @return estimated number of inversions that can be done per group operation for the same cost + */ + double estimateCostNegPerOp(); + /** * Returns true if this ring is known to be commutative. */ diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/bool/BooleanStructure.java b/src/main/java/org/cryptimeleon/math/structures/rings/bool/BooleanStructure.java index c2e2623d..7ff6e9d9 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/bool/BooleanStructure.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/bool/BooleanStructure.java @@ -64,6 +64,16 @@ public RingElement getElement(BigInteger i) { return i.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO) ? BooleanElement.FALSE : BooleanElement.TRUE; } + @Override + public double estimateCostInvPerOp() { + return 1; + } + + @Override + public double estimateCostNegPerOp() { + return 1; + } + @Override public boolean isCommutative() { return true; diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/ProductRing.java b/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/ProductRing.java index 7f308f28..fc150edf 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/ProductRing.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/ProductRing.java @@ -50,6 +50,18 @@ public RingElement getElement(BigInteger i) { return new ProductRingElement(Arrays.stream(rings).map(ring -> ring.getElement(i)).toArray(RingElement[]::new)); } + @Override + public double estimateCostInvPerOp() { + // Calculate average inversion cost + return Arrays.stream(rings).map(Ring::estimateCostInvPerOp).reduce(0.0, Double::sum) / rings.length; + } + + @Override + public double estimateCostNegPerOp() { + // Calculate average negation cost + return Arrays.stream(rings).map(Ring::estimateCostNegPerOp).reduce(0.0, Double::sum) / rings.length; + } + @Override public BigInteger sizeUnitGroup() throws UnsupportedOperationException { return Arrays.stream(rings).map(Ring::sizeUnitGroup).reduce(BigInteger.ONE, BigInteger::multiply); diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/RingElementVector.java b/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/RingElementVector.java index b9a6b5f7..6f97a13b 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/RingElementVector.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/cartesian/RingElementVector.java @@ -126,10 +126,21 @@ public RingElementVector truncate(int newLength) { return new RingElementVector(super.truncate(newLength)); } + @Override public RingElementVector concatenate(Vector secondPart) { return new RingElementVector(super.concatenate(secondPart)); } + @Override + public RingElementVector append(RingElement valueToAppend) { + return new RingElementVector(super.append(valueToAppend)); + } + + @Override + public RingElementVector prepend(RingElement valueToPrepend) { + return new RingElementVector(super.prepend(valueToPrepend)); + } + public ProductRingElement asElementInProductRing() { return new ProductRingElement(values); } diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionField.java b/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionField.java index 6d38bab3..2b22a8bc 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionField.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionField.java @@ -1,5 +1,6 @@ package org.cryptimeleon.math.structures.rings.extfield; +import org.cryptimeleon.math.misc.BigIntegerTools; import org.cryptimeleon.math.serialization.*; import org.cryptimeleon.math.structures.rings.Field; import org.cryptimeleon.math.structures.rings.FieldElement; @@ -24,8 +25,8 @@ public class ExtensionField implements Field { protected int extensionDegree; protected PolynomialRing.Polynomial definingPolynomial; /** - * frobeniusOfXPowers[i] = (x^p)^i mod (x^extensionDegree + constant) - * for i <= extensionDegree + * \(\text{frobeniusOfXPowers}[i] = (x^p)^i \mod (x^\text{extensionDegree} + \text{constant})\) + * for \(i \leq extensionDegree\) */ protected ExtensionFieldElement[] frobeniusOfXPowers; @@ -103,7 +104,10 @@ public ExtensionField(Representation r) { Field baseField = (Field) ((RepresentableRepresentation) o.get("baseField")).recreateRepresentable(); - init(baseField.restoreElement(o.get("constant")), o.get("extensionDegree").bigInt().get().intValueExact()); + init(baseField.restoreElement( + o.get("constant")), + BigIntegerTools.getExactInt(o.get("extensionDegree").bigInt().get()) + ); if (o.get("cubeRoot") != null) this.setCubeRoot(this.restoreElement(o.get("cubeRoot"))); @@ -205,6 +209,17 @@ public ExtensionFieldElement getElement(long i) { return getElement(BigInteger.valueOf(i)); } + @Override + public double estimateCostInvPerOp() { + // Tested with base field Zp(741618179) + return 0.3; + } + + @Override + public double estimateCostNegPerOp() { + return constant.getStructure().estimateCostNegPerOp(); + } + /** * Map an integer b to an element in this field. *

diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionFieldElement.java b/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionFieldElement.java index 83ffe8ab..99583a5f 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionFieldElement.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/extfield/ExtensionFieldElement.java @@ -8,10 +8,8 @@ import org.cryptimeleon.math.structures.rings.FieldElement; import org.cryptimeleon.math.structures.rings.RingElement; import org.cryptimeleon.math.structures.rings.polynomial.PolynomialRing; -import org.cryptimeleon.math.structures.rings.zn.Zn.ZnElement; import java.math.BigInteger; -import java.util.ArrayList; import java.util.Arrays; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -83,19 +81,23 @@ public ExtensionFieldElement neg() { @Override public ExtensionFieldElement mul(Element e) { - ExtensionFieldElement bne = (ExtensionFieldElement) e; + ExtensionFieldElement other = (ExtensionFieldElement) e; - FieldElement[] result = new FieldElement[this.coefficients.length + bne.coefficients.length]; + FieldElement[] result = new FieldElement[field.extensionDegree]; + Arrays.fill(result, field.getBaseField().getZeroElement()); - for (int i = 0; i < result.length; i++) - result[i] = this.getStructure().getBaseField().getZeroElement(); - - for (int i = 0; i < this.coefficients.length; i++) - for (int j = 0; j < bne.coefficients.length; j++) { - result[i + j] = result[i + j].add(this.coefficients[i].mul(bne.coefficients[j])); + for (int i = 0; i < this.coefficients.length; i++) { + FieldElement coefficient = this.coefficients[i]; + for (int j=0; j < other.coefficients.length; j++) { + if (i+j < field.extensionDegree) { + result[i+j] = result[i+j].add(coefficient.mul(other.coefficients[j])); + } else { //using that x^extensionDegree = -constant, so we write this as this[i]*other[j] * x^{i+j} = this[i]*other[j]*(-constant)*x^{i+j-extensionDegree} + result[i+j-field.extensionDegree] = result[i+j-field.extensionDegree].sub(coefficient.mul(other.coefficients[j]).mul(field.constant)); + } } + } - return this.getStructure().createElement(result); + return field.createElement(result); } /** diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/integers/IntegerRing.java b/src/main/java/org/cryptimeleon/math/structures/rings/integers/IntegerRing.java index 99ad4265..ff8e030a 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/integers/IntegerRing.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/integers/IntegerRing.java @@ -51,6 +51,16 @@ public IntegerElement getElement(BigInteger i) { return new IntegerElement(i); } + @Override + public double estimateCostInvPerOp() { + return 6; + } + + @Override + public double estimateCostNegPerOp() { + return 2; + } + @Override public IntegerElement restoreElement(Representation repr) { return new IntegerElement(repr.bigInt().get()); @@ -97,14 +107,14 @@ public boolean isCommutative() { * For example, for base = 2, this does bit decomposition. * * @return an array {@code A} containing values {@code A[i] < base} such that - * \(\sum_i{ \text{A}[i] \cdot \text{base}^i} = \text{number}\) + * \(\sum_i{ \text{A}[i] \cdot \text{base}^i} = \text{number}\) */ public static BigInteger[] decomposeIntoDigits(BigInteger number, BigInteger base) { int power = 0; - BigInteger numberPowered = BigInteger.ONE; - // as soon as number is smaller than number^power, it can be decomposed into power digits. - while (numberPowered.compareTo(number) < 0) { - numberPowered = numberPowered.multiply(number); + BigInteger basePower = BigInteger.ONE; + // as soon as number is smaller than base^power, it can be decomposed into power digits. + while (basePower.compareTo(number) < 0) { + basePower = basePower.multiply(base); power++; } return decomposeIntoDigits(number, base, power); @@ -116,7 +126,7 @@ public static BigInteger[] decomposeIntoDigits(BigInteger number, BigInteger bas * For example, for base = 2, this does bit decomposition. * * @return an array {@code A} containing values {@code A[i] < base} such that - * \(\sum_i{ \text{A}[i] \cdot \text{base}^i} = \text{number}\) + * \(\sum_i{ \text{A}[i] \cdot \text{base}^i} = \text{number}\) * @throws IllegalArgumentException if {@code numDigits} is not enough to represent the given number */ public static BigInteger[] decomposeIntoDigits(BigInteger number, BigInteger base, int numDigits) { @@ -139,4 +149,29 @@ public static BigInteger[] decomposeIntoDigits(BigInteger number, BigInteger bas return result; } + + /** + * Decomposes a given number into digits with the given base. + *

+ * For example, for base = 2, this does bit decomposition. + * + * @return an array {@code A} containing values {@code A[i] < base} such that + * \(\sum_i{ \text{A}[i] \cdot \text{base}^i} = \text{number}\) + */ + public static BigInteger[] decomposeIntoDigits(BigInteger number, long base) { + return decomposeIntoDigits(number, BigInteger.valueOf(base)); + } + + /** + * Decomposes a given number into the given number of digits with the given base. + *

+ * For example, for base = 2, this does bit decomposition. + * + * @return an array {@code A} containing values {@code A[i] < base} such that + * \(\sum_i{ \text{A}[i] \cdot \text{base}^i} = \text{number}\) + * @throws IllegalArgumentException if {@code numDigits} is not enough to represent the given number + */ + public static BigInteger[] decomposeIntoDigits(BigInteger number, long base, int numDigits) { + return decomposeIntoDigits(number, BigInteger.valueOf(base), numDigits); + } } diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/polynomial/PolynomialRing.java b/src/main/java/org/cryptimeleon/math/structures/rings/polynomial/PolynomialRing.java index 1856ae55..968873e2 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/polynomial/PolynomialRing.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/polynomial/PolynomialRing.java @@ -74,6 +74,17 @@ public Polynomial getElement(BigInteger i) { return new Polynomial(baseRing.getElement(i)); } + @Override + public double estimateCostInvPerOp() { + // Can only invert polynomials of degree zero + return baseRing.estimateCostInvPerOp(); + } + + @Override + public double estimateCostNegPerOp() { + return baseRing.estimateCostNegPerOp(); + } + /** * Returns the base ring. */ diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zn.java b/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zn.java index c157b530..daf94821 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zn.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zn.java @@ -1,6 +1,9 @@ package org.cryptimeleon.math.structures.rings.zn; +import org.cryptimeleon.math.expressions.bool.BooleanExpression; +import org.cryptimeleon.math.expressions.bool.ExponentEqualityExpr; import org.cryptimeleon.math.expressions.exponent.ExponentConstantExpr; +import org.cryptimeleon.math.expressions.exponent.ExponentExpr; import org.cryptimeleon.math.hash.ByteAccumulator; import org.cryptimeleon.math.hash.UniqueByteRepresentable; import org.cryptimeleon.math.random.RandomGenerator; @@ -169,6 +172,10 @@ public ZnElement add(Element e) { return createZnElementUnsafe(result); } + public ExponentExpr add(ExponentExpr e) { + return asExponentExpression().add(e); + } + @Override public ZnElement neg() { return v.equals(BigInteger.ZERO) ? this : createZnElementUnsafe(n.subtract(v)); @@ -183,6 +190,10 @@ public ZnElement sub(Element e) { return createZnElementUnsafe(result); } + public ExponentExpr sub(ExponentExpr e) { + return asExponentExpression().sub(e); + } + @Override public ZnElement mul(Element e) { checkSameModulus(e); @@ -199,6 +210,10 @@ public ZnElement mul(long k) { return mul(BigInteger.valueOf(k)); } + public ExponentExpr mul(ExponentExpr e) { + return asExponentExpression().mul(e); + } + @Override public ZnElement pow(BigInteger k) { return createZnElementUnsafe(v.modPow(k, n)); @@ -209,6 +224,10 @@ public ZnElement pow(long k) { return pow(BigInteger.valueOf(k)); } + public ExponentExpr pow(ExponentExpr e) { + return asExponentExpression().pow(e); + } + @Override public ZnElement inv() throws UnsupportedOperationException { try { @@ -218,6 +237,16 @@ public ZnElement inv() throws UnsupportedOperationException { } } + @Override + public ZnElement square() { + return mul(this); + } + + @Override + public ZnElement div(Element e) throws IllegalArgumentException { + return (ZnElement) RingElement.super.div(e); + } + @Override public boolean divides(RingElement e) throws UnsupportedOperationException { // this divides e over Zn iff gcd(this, n) divides e over the integers (http://shoup.net/ntb/ntb-v2.pdf, Theorem 2.5 (i)) @@ -295,6 +324,42 @@ public ExponentConstantExpr asExponentExpression() { return new ExponentConstantExpr(this); } + /** + * Returns an expression "this = other". + * This is for building expressions, i.e. only useful if unknown variables are involved. + * To compare two {@linkplain ZnElement}s normally, just use {@link #equals(Object)}. + */ + public ExponentEqualityExpr isEqualTo(ExponentExpr other) { + return asExponentExpression().isEqualTo(other); + } + + /** + * Returns an expression "this = other". + * This is for building expressions, i.e. only useful if unknown variables are involved. + * To compare two {@linkplain ZnElement}s normally, just use {@link #equals(Object)}. + */ + public ExponentEqualityExpr isEqualTo(ZnElement other) { + return isEqualTo(other.asExponentExpression()); + } + + /** + * Returns an expression "this = other mod n". + * This is for building expressions, i.e. only useful if unknown variables are involved. + * To compare two {@linkplain ZnElement}s normally, just use {@link #equals(Object)}. + */ + public ExponentEqualityExpr isEqualTo(BigInteger other) { + return isEqualTo(valueOf(other)); + } + + /** + * Returns an expression "this = other mod n". + * This is for building expressions, i.e. only useful if unknown variables are involved. + * To compare two {@linkplain ZnElement}s normally, just use {@link #equals(Object)}. + */ + public ExponentEqualityExpr isEqualTo(long other) { + return isEqualTo(valueOf(other)); + } + @Override public BigInteger asInteger() throws UnsupportedOperationException { return v; @@ -375,6 +440,7 @@ public ZnElement injectiveValueOf(byte[] bytes) throws IllegalArgumentException if (bytes.length > (n.bitLength() - 1) / 8) throw new IllegalArgumentException("Too many bytes to map injectively to Zn " + "(allowed are byte arrays of length " + (n.bitLength() - 1) / 8 + ")"); + // Normalize to make the most significant byte 0 (includes the sign bit). // This ensures that the resulting BigInteger number is nonnegative. byte[] normalized = new byte[bytes.length + 1]; @@ -386,6 +452,13 @@ public ZnElement injectiveValueOf(byte[] bytes) throws IllegalArgumentException return createZnElement(result); } + /** + * Interprets given bytes as an integer and projects that number into Zn. For short byte[], this map is injective. + */ + public ZnElement valueOf(byte[] bytes) { + return createZnElement(new BigInteger(1, bytes)); + } + @Override public BigInteger getCharacteristic() { return this.size(); @@ -426,6 +499,18 @@ public ZnElement getElement(BigInteger i) { return createZnElement(i); } + @Override + public double estimateCostInvPerOp() { + // Used Zn(2^128) here + return 0.1; + } + + @Override + public double estimateCostNegPerOp() { + // Used Zn(2^128) here + return 1; + } + @Override public boolean isCommutative() { return true; diff --git a/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zp.java b/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zp.java index a02b847e..a98edc7d 100644 --- a/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zp.java +++ b/src/main/java/org/cryptimeleon/math/structures/rings/zn/Zp.java @@ -134,6 +134,16 @@ public ZpElement inv() throws UnsupportedOperationException { return (ZpElement) super.inv(); } + @Override + public ZpElement square() { + return (ZpElement) super.square(); + } + + @Override + public ZpElement div(Element e) throws IllegalArgumentException { + return (ZpElement) super.div(e); + } + @Override public ZpElement pow(BigInteger k) { return (ZpElement) super.pow(k); diff --git a/src/test/java/org/cryptimeleon/math/pairings/PairingTests.java b/src/test/java/org/cryptimeleon/math/pairings/PairingTests.java index b9594a1e..c7d6d25a 100644 --- a/src/test/java/org/cryptimeleon/math/pairings/PairingTests.java +++ b/src/test/java/org/cryptimeleon/math/pairings/PairingTests.java @@ -1,22 +1,17 @@ package org.cryptimeleon.math.pairings; -import org.cryptimeleon.math.expressions.group.GroupElementExpression; import org.cryptimeleon.math.structures.groups.GroupElement; -import org.cryptimeleon.math.structures.groups.counting.CountingBilinearGroup; +import org.cryptimeleon.math.structures.groups.debug.DebugBilinearGroup;; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroup; import org.cryptimeleon.math.structures.groups.elliptic.BilinearMap; -import org.cryptimeleon.math.structures.groups.elliptic.type1.supersingular.SupersingularTateGroupImpl; -import org.cryptimeleon.math.structures.groups.elliptic.type3.bn.BarretoNaehrigBilinearGroupImpl; -import org.cryptimeleon.math.structures.groups.basic.BasicBilinearGroup; +import org.cryptimeleon.math.structures.groups.elliptic.type1.supersingular.SupersingularBasicBilinearGroup; +import org.cryptimeleon.math.structures.groups.elliptic.type3.bn.BarretoNaehrigBilinearGroup; import org.cryptimeleon.math.structures.rings.zn.Zn; -import org.cryptimeleon.math.structures.rings.zn.Zp; import org.junit.Test; -import org.junit.jupiter.api.Disabled; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; -import java.math.BigInteger; import java.util.Arrays; import java.util.Collection; @@ -92,18 +87,18 @@ public void testBasicProperties() { public static Collection data() { // Counting curves BilinearGroup countingGroup1 = - new CountingBilinearGroup(128, BilinearGroup.Type.TYPE_1); + new DebugBilinearGroup(128, BilinearGroup.Type.TYPE_1); BilinearGroup countingGroup2 = - new CountingBilinearGroup(128, BilinearGroup.Type.TYPE_2); + new DebugBilinearGroup(128, BilinearGroup.Type.TYPE_2); BilinearGroup countingGroup3 = - new CountingBilinearGroup(128, BilinearGroup.Type.TYPE_3); + new DebugBilinearGroup(128, BilinearGroup.Type.TYPE_3); // Supersingular curve groups - BilinearGroup supsingGroup = new BasicBilinearGroup(new SupersingularTateGroupImpl(80)); + BilinearGroup supsingGroup = new SupersingularBasicBilinearGroup(80); // BN curves - BilinearGroup bnGroup = new BasicBilinearGroup(new BarretoNaehrigBilinearGroupImpl(80)); - BilinearGroup sfcBn = new BasicBilinearGroup(new BarretoNaehrigBilinearGroupImpl("SFC-256")); + BilinearGroup bnGroup = new BarretoNaehrigBilinearGroup(80); + BilinearGroup sfcBn = new BarretoNaehrigBilinearGroup("SFC-256"); // Collect parameters BilinearMap[][] params = new BilinearMap[][] { diff --git a/src/test/java/org/cryptimeleon/math/prf/HashThenPrfTest.java b/src/test/java/org/cryptimeleon/math/prf/HashThenPrfTest.java new file mode 100644 index 00000000..b11b3b8b --- /dev/null +++ b/src/test/java/org/cryptimeleon/math/prf/HashThenPrfTest.java @@ -0,0 +1,105 @@ +package org.cryptimeleon.math.prf; + +import org.cryptimeleon.math.hash.HashFunction; +import org.cryptimeleon.math.hash.UniqueByteRepresentable; +import org.cryptimeleon.math.hash.impl.SHA256HashFunction; +import org.cryptimeleon.math.hash.impl.SHA512HashFunction; +import org.cryptimeleon.math.misc.ByteArrayImpl; +import org.cryptimeleon.math.prf.zn.HashThenPrfToZn; +import org.cryptimeleon.math.structures.rings.zn.Zn; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collection; +import java.util.Random; +import java.util.function.Supplier; + +import static org.junit.Assert.*; + +/** + * Tests the hash-then-prf-to-Zn construction. + */ +@RunWith(Parameterized.class) +public class HashThenPrfTest { + private HashThenPrfToZn hashThenPrfToZn; + private Supplier hashPreimageSupplier; + + + public HashThenPrfTest(TestParams params) { + hashThenPrfToZn = params.hashThenPrfToZn; + hashPreimageSupplier = params.hashPreimageSupplier; + } + + @org.junit.Test + public void testRun() { + PrfKey k = hashThenPrfToZn.generateKey(); + assertNotNull(hashThenPrfToZn.hashThenPrfToZn(k, hashPreimageSupplier.get())); + } + + @org.junit.Test + public void testVector() { + PrfKey k = hashThenPrfToZn.generateKey(); + UniqueByteRepresentable preimage = hashPreimageSupplier.get(); + + assertNotNull(hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 13)); + assertNotEquals( + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 12, "preimage1"), + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 12, "preimage2") + ); + assertNotEquals( + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 12, "preimage2"), + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 12, "") + ); + assertNotEquals( + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 7), + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 12).truncate(7) + ); // Different size vectors should have different elements + assertEquals( + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 7, "samePreimage"), + hashThenPrfToZn.hashThenPrfToZnVector(k, preimage, 7, "samePreimage") + ); + } + + // Some test configurations + @Parameterized.Parameters(name = "Test: {0}") // add (name="Test: {0}") for jUnit 4.12+ to print ring's name to test + public static Collection data() { + return Arrays.asList(new TestParams[][]{ + {new TestParams(128, new SHA256HashFunction(), 30, () -> ByteArrayImpl.fromRandom(1024))}, + {new TestParams(128, new SHA256HashFunction(), 470, () -> ByteArrayImpl.fromRandom(1024))}, + {new TestParams(128, new SHA256HashFunction(), 1330, () -> ByteArrayImpl.fromRandom(1024))}, + {new TestParams(128, new SHA512HashFunction(), 470, () -> ByteArrayImpl.fromRandom(1024))}, + {new TestParams(256, new SHA256HashFunction(), 30, () -> ByteArrayImpl.fromRandom(1024))}, + {new TestParams(256, new SHA256HashFunction(), 470, () -> ByteArrayImpl.fromRandom(1024))}, + {new TestParams(256, new SHA256HashFunction(), 1330, () -> ByteArrayImpl.fromRandom(1024))}, + {new TestParams(256, new SHA512HashFunction(), 470, () -> ByteArrayImpl.fromRandom(1024))}, + }); + } + + /** + * Simple data class for test parameters. + */ + private static class TestParams { + private int aesKeyLength; + private HashFunction hashFunction; + private Zn zn; + private Supplier hashPreimageSupplier; + private HashThenPrfToZn hashThenPrfToZn; + private int znBitLength; + + public TestParams(int aesKeyLength, HashFunction hashFunction, int znBitLength, Supplier hashPreimageSupplier) { + this.aesKeyLength = aesKeyLength; + this.hashFunction = hashFunction; + this.hashPreimageSupplier = hashPreimageSupplier; + this.zn = new Zn(new BigInteger(znBitLength, 64, new Random())); + this.hashThenPrfToZn = new HashThenPrfToZn(aesKeyLength, zn, hashFunction, 128); + this.znBitLength = znBitLength; + } + + @Override + public String toString() { + return aesKeyLength + "bit AES with " + hashFunction.getClass().getName() + ", Zn of size " + znBitLength; + } + } +} diff --git a/src/test/java/org/cryptimeleon/math/prf/PrfTest.java b/src/test/java/org/cryptimeleon/math/prf/PrfTest.java new file mode 100644 index 00000000..a9ae571f --- /dev/null +++ b/src/test/java/org/cryptimeleon/math/prf/PrfTest.java @@ -0,0 +1,78 @@ +package org.cryptimeleon.math.prf; + +import org.cryptimeleon.math.misc.ByteArrayImpl; +import org.cryptimeleon.math.prf.aes.AesPseudorandomFunction; +import org.cryptimeleon.math.prf.aes.LongAesPseudoRandomFunction; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Supplier; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Does generic testing of rings + */ +@RunWith(Parameterized.class) +public class PrfTest { + private PseudorandomFunction prf; + private Supplier preimageSupplier; + + public PrfTest(TestParams params) { + this.prf = params.prf; + this.preimageSupplier = params.preimageSupplier; + } + + @Test + public void testRun() { + PrfKey k = prf.generateKey(); + assertNotNull(prf.evaluate(k, preimageSupplier.get())); + } + + @Test + public void testSerialization() { + PrfKey k = prf.generateKey(); + assertEquals(k, prf.restoreKey(k.getRepresentation())); + + PrfPreimage x = preimageSupplier.get(); + assertEquals(x, prf.restorePreimage(x.getRepresentation())); + + PrfImage y = prf.evaluate(k, x); + assertEquals(y, prf.restoreImage(y.getRepresentation())); + } + + @Parameters(name = "Test: {0}") // add (name="Test: {0}") for jUnit 4.12+ to print ring's name to test + public static Collection data() { + // AES + AesPseudorandomFunction aes = new AesPseudorandomFunction(128); + // Long + LongAesPseudoRandomFunction longAes = new LongAesPseudoRandomFunction(aes, 7); + + // Collect parameters + TestParams params[][] = new TestParams[][]{ + {new TestParams(aes, () -> ByteArrayImpl.fromRandom(128 / 8))}, + {new TestParams(longAes, () -> ByteArrayImpl.fromRandom(128 / 8))} + }; + return Arrays.asList(params); + } + + private static class TestParams { + private PseudorandomFunction prf; + private Supplier preimageSupplier; + + public TestParams(PseudorandomFunction prf, Supplier preimageSupplier) { + this.prf = prf; + this.preimageSupplier = preimageSupplier; + } + + @Override + public String toString() { + return prf.getClass().getName() + " - " + prf.toString(); + } + } +} diff --git a/src/test/java/org/cryptimeleon/math/serialization/converter/ConverterTest.java b/src/test/java/org/cryptimeleon/math/serialization/converter/ConverterTest.java index 5e404dbd..95351fac 100644 --- a/src/test/java/org/cryptimeleon/math/serialization/converter/ConverterTest.java +++ b/src/test/java/org/cryptimeleon/math/serialization/converter/ConverterTest.java @@ -1,6 +1,5 @@ package org.cryptimeleon.math.serialization.converter; -import org.cryptimeleon.math.serialization.*; import org.cryptimeleon.math.serialization.*; import org.cryptimeleon.math.structures.rings.zn.Zn; import org.junit.Assert; diff --git a/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprSubTest.java b/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprSubTest.java index c0f0c386..498103c9 100644 --- a/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprSubTest.java +++ b/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprSubTest.java @@ -26,7 +26,6 @@ public abstract class StandaloneReprSubTest { protected final void test(StandaloneRepresentable object) { Class clazz = object.getClass(); testedClasses.add(clazz); - //Test for constructor with single Representation parameter try { Constructor constructor = clazz.getConstructor(Representation.class); diff --git a/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprTest.java b/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprTest.java index ba8824a6..4fcdf497 100644 --- a/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprTest.java +++ b/src/test/java/org/cryptimeleon/math/serialization/standalone/StandaloneReprTest.java @@ -87,6 +87,7 @@ public void testClassesWithTrivialConstructor() { reflection.getSubTypesOf(StandaloneRepresentable.class).stream() .filter(clazz -> clazz.getPackage().getName().startsWith(packageToTest)) //only use those that belong to the desired package .filter(clazz -> Arrays.stream(clazz.getConstructors()).anyMatch(constr -> constr.getParameterCount() == 0)) + .filter(clazz -> Modifier.isPublic(clazz.getModifiers())) .forEach(clazz -> { try { test(clazz.getConstructor().newInstance()); @@ -105,8 +106,9 @@ public void checkForUntestedClasses() { Set> classesToTest = reflection.getSubTypesOf(StandaloneRepresentable.class); classesToTest.removeAll(testedClasses); - //Remove interfaces and stuff from other packages - classesToTest.removeIf(c -> c.isInterface() || Modifier.isAbstract(c.getModifiers()) || !c.getPackage().getName().startsWith(packageToTest)); + // Remove interfaces and stuff from other packages, and classes that are not public + classesToTest.removeIf(c -> c.isInterface() || Modifier.isAbstract(c.getModifiers()) + || !c.getPackage().getName().startsWith(packageToTest) || !Modifier.isPublic(c.getModifiers())); for (Class notTestedClass : classesToTest) { System.err.println(notTestedClass.getName() + " implements StandaloneRepresentable but was not tested by StandaloneTest (or the test failed). You need to define a StandaloneReprSubTest for it."); diff --git a/src/test/java/org/cryptimeleon/math/serialization/standalone/params/PrfStandaloneReprTests.java b/src/test/java/org/cryptimeleon/math/serialization/standalone/params/PrfStandaloneReprTests.java new file mode 100644 index 00000000..73b66332 --- /dev/null +++ b/src/test/java/org/cryptimeleon/math/serialization/standalone/params/PrfStandaloneReprTests.java @@ -0,0 +1,27 @@ +package org.cryptimeleon.math.serialization.standalone.params; + +import org.cryptimeleon.math.hash.impl.SHA256HashFunction; +import org.cryptimeleon.math.prf.aes.AesPseudorandomFunction; +import org.cryptimeleon.math.prf.zn.HashThenPrfToZn; +import org.cryptimeleon.math.prf.aes.LongAesPseudoRandomFunction; +import org.cryptimeleon.math.serialization.standalone.StandaloneReprSubTest; +import org.cryptimeleon.math.structures.rings.zn.Zn; + +import java.math.BigInteger; +import java.util.Random; + +public class PrfStandaloneReprTests extends StandaloneReprSubTest { + public void testAes() { + test(new AesPseudorandomFunction(128)); + } + + public void testLongAes() { + test(new LongAesPseudoRandomFunction(new AesPseudorandomFunction(128), 9)); + } + + public void testAesToZn() { + BigInteger p = BigInteger.probablePrime(400, new Random()); + Zn zn = new Zn(p); + test(new HashThenPrfToZn(128, zn, new SHA256HashFunction(), 64)); + } +} diff --git a/src/test/java/org/cryptimeleon/math/serialization/standalone/params/StructureStandaloneReprTest.java b/src/test/java/org/cryptimeleon/math/serialization/standalone/params/StructureStandaloneReprTest.java index da6440a2..940a3129 100644 --- a/src/test/java/org/cryptimeleon/math/serialization/standalone/params/StructureStandaloneReprTest.java +++ b/src/test/java/org/cryptimeleon/math/serialization/standalone/params/StructureStandaloneReprTest.java @@ -1,18 +1,16 @@ package org.cryptimeleon.math.serialization.standalone.params; import org.cryptimeleon.math.serialization.standalone.StandaloneReprSubTest; -import org.cryptimeleon.math.structures.groups.RingAdditiveGroupImpl; -import org.cryptimeleon.math.structures.groups.RingUnitGroupImpl; import org.cryptimeleon.math.structures.groups.basic.BasicBilinearGroup; import org.cryptimeleon.math.structures.groups.cartesian.ProductGroup; -import org.cryptimeleon.math.structures.groups.counting.CountingBilinearGroup; -import org.cryptimeleon.math.structures.groups.counting.CountingBilinearGroupImpl; +import org.cryptimeleon.math.structures.groups.debug.DebugBilinearGroup; +import org.cryptimeleon.math.structures.groups.debug.DebugBilinearGroupImpl; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroup; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroupImpl; +import org.cryptimeleon.math.structures.groups.elliptic.type1.supersingular.SupersingularBasicBilinearGroup; import org.cryptimeleon.math.structures.groups.elliptic.type1.supersingular.SupersingularBilinearGroup; -import org.cryptimeleon.math.structures.groups.elliptic.type1.supersingular.SupersingularTateGroupImpl; +import org.cryptimeleon.math.structures.groups.elliptic.type3.bn.BarretoNaehrigBasicBilinearGroup; import org.cryptimeleon.math.structures.groups.elliptic.type3.bn.BarretoNaehrigBilinearGroup; -import org.cryptimeleon.math.structures.groups.elliptic.type3.bn.BarretoNaehrigBilinearGroupImpl; import org.cryptimeleon.math.structures.groups.lazy.LazyBilinearGroup; import org.cryptimeleon.math.structures.groups.sn.Sn; import org.cryptimeleon.math.structures.rings.cartesian.ProductRing; @@ -65,25 +63,25 @@ public void testBilinearGroupImpl(BilinearGroupImpl bilGroup) { } public void testBarretoNaehrig() { + testBilinearGroup(new BarretoNaehrigBasicBilinearGroup(80)); testBilinearGroup(new BarretoNaehrigBilinearGroup(80)); - testBilinearGroupImpl(new BarretoNaehrigBilinearGroupImpl(80)); } public void testSupersingular() { - testBilinearGroupImpl(new SupersingularTateGroupImpl(80)); + testBilinearGroup(new SupersingularBasicBilinearGroup(80)); testBilinearGroup(new SupersingularBilinearGroup(80)); } public void testLazyAndBasicGroup() { - BilinearGroupImpl debugGroupImpl = new CountingBilinearGroupImpl(128, BilinearGroup.Type.TYPE_1); + BilinearGroupImpl bilGroupImpl = new DebugBilinearGroupImpl(60, BilinearGroup.Type.TYPE_3); - testBilinearGroup(new LazyBilinearGroup(debugGroupImpl)); - testBilinearGroup(new BasicBilinearGroup(debugGroupImpl)); + testBilinearGroup(new LazyBilinearGroup(bilGroupImpl)); + testBilinearGroup(new BasicBilinearGroup(bilGroupImpl)); } - public void testCountingGroup() { - testBilinearGroup(new CountingBilinearGroup(128, BilinearGroup.Type.TYPE_1)); - testBilinearGroupImpl(new CountingBilinearGroupImpl(128, BilinearGroup.Type.TYPE_1)); + public void testDebugGroup() { + testBilinearGroup(new DebugBilinearGroup(128, BilinearGroup.Type.TYPE_1)); + testBilinearGroupImpl(new DebugBilinearGroupImpl(128, BilinearGroup.Type.TYPE_1)); } public void testExtensionField() { @@ -106,8 +104,6 @@ public void testProductStructures() { public void testRingGroups() { test(zp.asUnitGroup()); test(zp.asAdditiveGroup()); - test(new RingUnitGroupImpl(zp)); - test(new RingAdditiveGroupImpl(zp)); } public void testRings() { diff --git a/src/test/java/org/cryptimeleon/math/structures/CountingTest.java b/src/test/java/org/cryptimeleon/math/structures/CountingTest.java index d8b1df0c..78cd65ee 100644 --- a/src/test/java/org/cryptimeleon/math/structures/CountingTest.java +++ b/src/test/java/org/cryptimeleon/math/structures/CountingTest.java @@ -1,8 +1,8 @@ package org.cryptimeleon.math.structures; import org.cryptimeleon.math.structures.groups.GroupElement; -import org.cryptimeleon.math.structures.groups.counting.CountingBilinearGroup; -import org.cryptimeleon.math.structures.groups.counting.CountingGroup; +import org.cryptimeleon.math.structures.groups.debug.DebugBilinearGroup;; +import org.cryptimeleon.math.structures.groups.debug.DebugGroup; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroup; import org.junit.Before; import org.junit.Test; @@ -14,68 +14,68 @@ public class CountingTest { - CountingBilinearGroup bilGroup; + DebugBilinearGroup bilGroup; @Before public void setUp() { - bilGroup = new CountingBilinearGroup(128, BilinearGroup.Type.TYPE_2); + bilGroup = new DebugBilinearGroup(128, BilinearGroup.Type.TYPE_2); } @Test public void testNullInstantiation() { - CountingGroup countingGroup = (CountingGroup) bilGroup.getG1(); - assertEquals(0, countingGroup.getNumRetrievedRepresentations()); - assertEquals(0, countingGroup.getNumExps()); - assertEquals(0, countingGroup.getNumOpsTotal()); - assertEquals(0, countingGroup.getNumSquaringsTotal()); - assertEquals(0, countingGroup.getNumInversionsTotal()); - assertEquals(0, countingGroup.getNumOpsNoExpMultiExp()); - assertEquals(0, countingGroup.getNumSquaringsNoExpMultiExp()); - assertEquals(0, countingGroup.getNumInversionsNoExpMultiExp()); - assertArrayEquals(new Integer[] {}, countingGroup.getMultiExpTermNumbers().toArray(new Integer[] {})); + DebugGroup debugGroup = (DebugGroup) bilGroup.getG1(); + assertEquals(0, debugGroup.getNumRetrievedRepresentations()); + assertEquals(0, debugGroup.getNumExps()); + assertEquals(0, debugGroup.getNumOpsTotal()); + assertEquals(0, debugGroup.getNumSquaringsTotal()); + assertEquals(0, debugGroup.getNumInversionsTotal()); + assertEquals(0, debugGroup.getNumOpsNoExpMultiExp()); + assertEquals(0, debugGroup.getNumSquaringsNoExpMultiExp()); + assertEquals(0, debugGroup.getNumInversionsNoExpMultiExp()); + assertArrayEquals(new Integer[] {}, debugGroup.getMultiExpTermNumbers().toArray(new Integer[] {})); } @Test public void testBasicOperationCounting() { - CountingGroup countingGroup = (CountingGroup) bilGroup.getG1(); - GroupElement elem = countingGroup.getUniformlyRandomNonNeutral(); - GroupElement elem2 = countingGroup.getUniformlyRandomNonNeutral(); + DebugGroup debugGroup = (DebugGroup) bilGroup.getG1(); + GroupElement elem = debugGroup.getUniformlyRandomNonNeutral(); + GroupElement elem2 = debugGroup.getUniformlyRandomNonNeutral(); elem.op(elem).inv().computeSync(); elem.op(elem2).computeSync(); - assertEquals(1, countingGroup.getNumOpsNoExpMultiExp()); - assertEquals(1, countingGroup.getNumOpsTotal()); - assertEquals(1, countingGroup.getNumInversionsNoExpMultiExp()); - assertEquals(1, countingGroup.getNumInversionsTotal()); - assertEquals(1, countingGroup.getNumSquaringsNoExpMultiExp()); - assertEquals(1, countingGroup.getNumSquaringsTotal()); + assertEquals(1, debugGroup.getNumOpsNoExpMultiExp()); + assertEquals(1, debugGroup.getNumOpsTotal()); + assertEquals(1, debugGroup.getNumInversionsNoExpMultiExp()); + assertEquals(1, debugGroup.getNumInversionsTotal()); + assertEquals(1, debugGroup.getNumSquaringsNoExpMultiExp()); + assertEquals(1, debugGroup.getNumSquaringsTotal()); } @Test public void testPowCounting() { - CountingGroup countingGroup = (CountingGroup) bilGroup.getG1(); - GroupElement elem = countingGroup.getUniformlyRandomNonNeutral(); + DebugGroup debugGroup = (DebugGroup) bilGroup.getG1(); + GroupElement elem = debugGroup.getUniformlyRandomNonNeutral(); elem.pow(10).computeSync(); // tested with WNAF exponentiation algorithm - assertEquals(8, countingGroup.getNumOpsTotal()); - assertEquals(2, countingGroup.getNumSquaringsTotal()); - assertEquals(1, countingGroup.getNumExps()); + assertEquals(8, debugGroup.getNumOpsTotal()); + assertEquals(2, debugGroup.getNumSquaringsTotal()); + assertEquals(1, debugGroup.getNumExps()); } @Test public void testRepresentationCounting() { - CountingGroup countingGroup = (CountingGroup) bilGroup.getG1(); - GroupElement elem = countingGroup.getUniformlyRandomNonNeutral(); + DebugGroup debugGroup = (DebugGroup) bilGroup.getG1(); + GroupElement elem = debugGroup.getUniformlyRandomNonNeutral(); elem.getRepresentation(); elem.getRepresentation(); - assertEquals(2, countingGroup.getNumRetrievedRepresentations()); + assertEquals(2, debugGroup.getNumRetrievedRepresentations()); } @Test public void testPairingCounting() { - CountingGroup groupG1 = (CountingGroup) bilGroup.getG1(); - CountingGroup groupG2 = (CountingGroup) bilGroup.getG2(); - CountingGroup groupGT = (CountingGroup) bilGroup.getGT(); + DebugGroup groupG1 = (DebugGroup) bilGroup.getG1(); + DebugGroup groupG2 = (DebugGroup) bilGroup.getG2(); + DebugGroup groupGT = (DebugGroup) bilGroup.getGT(); GroupElement elemG1 = groupG1.getUniformlyRandomNonNeutral(); GroupElement elemG2 = groupG2.getUniformlyRandomNonNeutral(); bilGroup.getBilinearMap().apply(elemG1, elemG2).computeSync(); @@ -95,38 +95,38 @@ public void testPairingCounting() { @Test public void testMultiExpCounting() { - CountingGroup countingGroup = (CountingGroup) bilGroup.getG1(); + DebugGroup debugGroup = (DebugGroup) bilGroup.getG1(); GroupElement elem1, elem2, elem3; do { - elem1 = countingGroup.getUniformlyRandomNonNeutral(); - elem2 = countingGroup.getUniformlyRandomNonNeutral(); - elem3 = countingGroup.getUniformlyRandomNonNeutral(); + elem1 = debugGroup.getUniformlyRandomNonNeutral(); + elem2 = debugGroup.getUniformlyRandomNonNeutral(); + elem3 = debugGroup.getUniformlyRandomNonNeutral(); // Cannot equal each other, else the operations will be different since we don't // need to do as many precomputations } while (elem1.equals(elem2) || elem2.equals(elem3) || elem3.equals(elem1)); // will be computed as (G1_5 * G2_5 * G3_5)^2 where Gi_5 = elemi^5 is precomputed (WNAF multiexp) elem1.pow(10).op(elem2.pow(10)).op(elem3.pow(10)).computeSync(); - System.out.println(countingGroup.formatCounterData()); - assertArrayEquals(new Integer[] {3}, countingGroup.getMultiExpTermNumbers().toArray(new Integer[1])); + System.out.println(debugGroup.formatCounterData()); + assertArrayEquals(new Integer[] {3}, debugGroup.getMultiExpTermNumbers().toArray(new Integer[1])); // 8 ops per element for precomputation - assertEquals(24, countingGroup.getNumOpsTotal()); + assertEquals(24, debugGroup.getNumOpsTotal()); // 1 squaring per element for precomputation plus one for multi-exponentiation - assertEquals(4, countingGroup.getNumSquaringsTotal()); + assertEquals(4, debugGroup.getNumSquaringsTotal()); } @Test public void testComputeWorksSynchronously() { - CountingGroup countingGroup = (CountingGroup) bilGroup.getG1(); - GroupElement elem = countingGroup.getUniformlyRandomNonNeutral(); + DebugGroup debugGroup = (DebugGroup) bilGroup.getG1(); + GroupElement elem = debugGroup.getUniformlyRandomNonNeutral(); elem.op(elem).inv().compute(); // compute is implemented synchronously for the counting group - assertEquals(1, countingGroup.getNumSquaringsNoExpMultiExp()); // would be 0 if asynchronous + assertEquals(1, debugGroup.getNumSquaringsNoExpMultiExp()); // would be 0 if asynchronous } @Test public void testResetCounters() { - CountingGroup groupG1 = (CountingGroup) bilGroup.getG1(); - CountingGroup groupG2 = (CountingGroup) bilGroup.getG2(); + DebugGroup groupG1 = (DebugGroup) bilGroup.getG1(); + DebugGroup groupG2 = (DebugGroup) bilGroup.getG2(); GroupElement elem1 = groupG1.getUniformlyRandomNonNeutral(); GroupElement elem2 = groupG1.getUniformlyRandomNonNeutral(); GroupElement elem3 = groupG1.getUniformlyRandomNonNeutral(); @@ -158,8 +158,8 @@ public void testResetCounters() { @Test public void testCountingHomomorphism() { - CountingGroup groupG1 = (CountingGroup) bilGroup.getG1(); - CountingGroup groupG2 = (CountingGroup) bilGroup.getG2(); + DebugGroup groupG1 = (DebugGroup) bilGroup.getG1(); + DebugGroup groupG2 = (DebugGroup) bilGroup.getG2(); GroupElement elemG1; GroupElement elemG2 = groupG2.getUniformlyRandomNonNeutral(); diff --git a/src/test/java/org/cryptimeleon/math/structures/ExpTests.java b/src/test/java/org/cryptimeleon/math/structures/ExpTests.java index 48337d0b..b6a65f10 100644 --- a/src/test/java/org/cryptimeleon/math/structures/ExpTests.java +++ b/src/test/java/org/cryptimeleon/math/structures/ExpTests.java @@ -3,7 +3,7 @@ import org.cryptimeleon.math.random.RandomGenerator; import org.cryptimeleon.math.structures.groups.GroupElementImpl; import org.cryptimeleon.math.structures.groups.GroupImpl; -import org.cryptimeleon.math.structures.groups.counting.CountingBilinearGroupImpl; +import org.cryptimeleon.math.structures.groups.debug.DebugBilinearGroupImpl; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroup; import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroupImpl; import org.cryptimeleon.math.structures.groups.exp.ExponentiationAlgorithms; @@ -17,10 +17,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class ExpTests { - public static final BilinearGroupImpl bilGroup = new CountingBilinearGroupImpl(60, BilinearGroup.Type.TYPE_3); @Test public void testMultiExpAlgs() { + BilinearGroupImpl bilGroup = new DebugBilinearGroupImpl(60, BilinearGroup.Type.TYPE_3); for (int i = 0; i < 10; ++i) { Multiexponentiation multiexponentiation = genMultiExp(bilGroup.getG1(), 10); System.out.println(multiexponentiation); @@ -57,6 +57,7 @@ private static GroupElementImpl naiveEval(Multiexponentiation multiexp) { @Test public void testExpAlgs() { + BilinearGroupImpl bilGroup = new DebugBilinearGroupImpl(60, BilinearGroup.Type.TYPE_3); for (int i = 0; i < 4; ++i) { GroupElementImpl elem = bilGroup.getG1().getUniformlyRandomNonNeutral(); BigInteger exponent = RandomGenerator.getRandomNumber(BigInteger.valueOf(Integer.MAX_VALUE)); diff --git a/src/test/java/org/cryptimeleon/math/structures/GroupImplTests.java b/src/test/java/org/cryptimeleon/math/structures/GroupImplTests.java index 9d4bf336..959fd98d 100644 --- a/src/test/java/org/cryptimeleon/math/structures/GroupImplTests.java +++ b/src/test/java/org/cryptimeleon/math/structures/GroupImplTests.java @@ -5,15 +5,6 @@ import org.cryptimeleon.math.serialization.Representation; import org.cryptimeleon.math.structures.groups.GroupElementImpl; import org.cryptimeleon.math.structures.groups.GroupImpl; -import org.cryptimeleon.math.structures.groups.RingAdditiveGroupImpl; -import org.cryptimeleon.math.structures.groups.RingUnitGroupImpl; -import org.cryptimeleon.math.structures.groups.counting.CountingGroupImpl; -import org.cryptimeleon.math.structures.groups.elliptic.BilinearGroupImpl; -import org.cryptimeleon.math.structures.groups.elliptic.nopairing.Secp256k1; -import org.cryptimeleon.math.structures.groups.elliptic.type3.bn.BarretoNaehrigBilinearGroupImpl; -import org.cryptimeleon.math.structures.groups.sn.Sn; -import org.cryptimeleon.math.structures.rings.integers.IntegerElement; -import org.cryptimeleon.math.structures.rings.integers.IntegerRing; import org.cryptimeleon.math.structures.rings.zn.Zn; import org.cryptimeleon.math.structures.rings.zn.Zp; import org.junit.Test; @@ -32,7 +23,7 @@ /** * Does generic testing of groups - */ + **/ @RunWith(Parameterized.class) public class GroupImplTests { protected GroupImpl groupImpl; @@ -178,6 +169,7 @@ public void testUniqueRepresentations() { @Parameters(name = "Test: {0}") // add (name="Test: {0}") for jUnit 4.12+ to print group's name to test public static Collection data() { + /* // Some setup // Unit group of a ring RingUnitGroupImpl ringUnitGroupImpl = new RingUnitGroupImpl(new Zp(BigInteger.valueOf(13))); @@ -187,7 +179,7 @@ public static Collection data() { RingAdditiveGroupImpl ringAddGroupInt = new RingAdditiveGroupImpl(new IntegerRing()); // Debug group - CountingGroupImpl countingGroupImpl = new CountingGroupImpl("Testgroup", BigInteger.valueOf(1000)); + DebugGroupImpl debugGroupImpl = new DebugGroupImpl("Testgroup", BigInteger.valueOf(1000)); // BarretoNaehrig BilinearGroupImpl bnGroup = new BarretoNaehrigBilinearGroupImpl(128); @@ -203,12 +195,14 @@ public static Collection data() { TestParams params[][] = new TestParams[][]{ {new TestParams(ringUnitGroupImpl)}, {new TestParams(ringAddGroup)}, {new TestParams(ringAddGroupInt, () -> ringAddGroupInt.new RingAdditiveGroupElementImpl(new IntegerElement(RandomGenerator.getRandomNumber(100000))))}, {new TestParams(sn)}, - {new TestParams(countingGroupImpl)}, + {new TestParams(debugGroupImpl)}, {new TestParams(bnG1)}, {new TestParams(bnG2)}, {new TestParams(bnGT)}, {new TestParams(bnG12)}, {new TestParams(bnG22)}, {new TestParams(bnGT2)}, {new TestParams(new Secp256k1())} }; return Arrays.asList(params); + */ + return Arrays.asList(new TestParams[][]{}); } protected static class TestParams { diff --git a/src/test/java/org/cryptimeleon/math/structures/GroupTests.java b/src/test/java/org/cryptimeleon/math/structures/GroupTests.java index c255524c..8b8ae734 100644 --- a/src/test/java/org/cryptimeleon/math/structures/GroupTests.java +++ b/src/test/java/org/cryptimeleon/math/structures/GroupTests.java @@ -2,10 +2,11 @@ import org.cryptimeleon.math.structures.groups.Group; import org.cryptimeleon.math.structures.groups.GroupElement; -import org.cryptimeleon.math.structures.groups.counting.CountingGroupImpl; import org.cryptimeleon.math.serialization.RepresentableRepresentation; import org.cryptimeleon.math.serialization.Representation; +import org.cryptimeleon.math.structures.groups.GroupImpl; import org.cryptimeleon.math.structures.groups.basic.BasicGroup; +import org.cryptimeleon.math.structures.groups.debug.DebugGroupImpl; import org.cryptimeleon.math.structures.groups.lazy.LazyGroup; import org.cryptimeleon.math.structures.rings.zn.Zn; import org.junit.Test; @@ -214,11 +215,11 @@ public void testUniqueRepresentations() { @Parameters(name = "Test: {0}") public static Collection data() { // Some setup - CountingGroupImpl countingGroupImpl = new CountingGroupImpl( + GroupImpl debugGroupImpl = new DebugGroupImpl( "testGroupImpl", BigInteger.probablePrime(128, new Random()) ); - BasicGroup basicGroup = new BasicGroup(countingGroupImpl); - LazyGroup lazyGroup = new LazyGroup(countingGroupImpl); + BasicGroup basicGroup = new BasicGroup(debugGroupImpl); + LazyGroup lazyGroup = new LazyGroup(debugGroupImpl); // Collect parameters TestParams[][] params = new TestParams[][]{ diff --git a/src/test/java/org/cryptimeleon/math/structures/RingTests.java b/src/test/java/org/cryptimeleon/math/structures/RingTests.java index 1d8f825b..c777eb46 100644 --- a/src/test/java/org/cryptimeleon/math/structures/RingTests.java +++ b/src/test/java/org/cryptimeleon/math/structures/RingTests.java @@ -3,6 +3,7 @@ import org.cryptimeleon.math.structures.rings.Field; import org.cryptimeleon.math.structures.rings.Ring; import org.cryptimeleon.math.structures.rings.RingElement; +import org.cryptimeleon.math.structures.rings.extfield.ExtensionField; import org.cryptimeleon.math.structures.rings.integers.IntegerElement; import org.cryptimeleon.math.structures.rings.integers.IntegerRing; import org.cryptimeleon.math.structures.rings.polynomial.PolynomialRing; @@ -241,6 +242,9 @@ public static Collection data() { // Polynomial ring over z13 PolynomialRing polyRing = new PolynomialRing(z13); + // ExtensionField + ExtensionField extensionField = new ExtensionField(z13.getElement(11), 2); + // Collect parameters TestParams[][] params = new TestParams[][]{ {new TestParams(integerRing, () -> new IntegerElement(5), () -> new IntegerElement(-1))}, @@ -251,7 +255,8 @@ public static Collection data() { () -> polyRing.new Polynomial(new Random().nextBoolean() ? z13.getUniformlyRandomElement() : z13.getZeroElement(), z13.getUniformlyRandomElement()), - polyRing::getUniformlyRandomUnit)} + polyRing::getUniformlyRandomUnit)}, + {new TestParams(extensionField)} }; return Arrays.asList(params); }