Skip to content

Commit 7cab622

Browse files
author
Jan Bobolz
authored
Merge pull request #39 from cryptimeleon/develop
Release 3.2.0
2 parents 1eb66f2 + b5ce239 commit 7cab622

19 files changed

+247
-130
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
55

66
## [3.x] - 2021-09-21
77
- A precompiled version of mcl is now packaged with mclwrap.
8+
- Added BLS12-381.
89

910
## [2.x] - 2021-06-29
1011
- Made most of the mcl wrapper classes package-private.

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
![Build Status](https://github.com/cryptimeleon/mclwrap/actions/workflows/scheduled-main-ci.yaml/badge.svg)
55
# Mclwrap
66

7-
Mclwrap provides a wrapper around the BN-254 bilinear group implemented in the [MCL library](https://github.com/herumi/mcl). As the bilinear groups implemented in the Cryptimeleon Math library are not particulary efficient, use of this wrapper is recommended for proper benchmarks.
7+
Mclwrap provides a wrapper around the BN-254 and BLS12-381 bilinear group implemented in the [MCL library](https://github.com/herumi/mcl). As the bilinear groups implemented in the Cryptimeleon Math library are not particulary efficient, use of this wrapper is recommended for proper benchmarks.
88
Specifically, the Mclwrap implementation's group operations are roughly 100 times as fast as our own implementation.
99

1010
## Security Disclaimer
@@ -21,7 +21,9 @@ Specifically, the Mclwrap implementation's group operations are roughly 100 time
2121

2222
## Quickstart
2323

24-
Simply add mclwrap as a dependency (see below for [maven](#adding-mclwrap-dependency-with-maven) and [gradle](#adding-mclwrap-dependency-with-gradle) snippets) and start using the `MclBilinearGroup` in your code.
24+
Simply add mclwrap as a dependency (see below for [maven](#adding-mclwrap-dependency-with-maven) and [gradle](#adding-mclwrap-dependency-with-gradle) snippets) and start using the `MclBilinearGroup` in your code.
25+
You can pass `GroupChoice.BN254` or `GroupChoice.BLS12_381` to the constructor of `MclBilinearGroup` to choose which group to use.
26+
Note that we currently do not support instantiating both groups at the same time.
2527

2628
For full performance, you should compile the underlying mcl library for your system yourself (by default, a precompiled maximum-compatibility version of mcl is used, which may miss out on some modern processor features).
2729
Instructions for this can be found below.

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ plugins {
88
group 'org.cryptimeleon'
99
archivesBaseName = project.name
1010
boolean isRelease = project.hasProperty("release")
11-
version = '3.1.0' + (isRelease ? "" : "-SNAPSHOT")
11+
version = '3.2.0' + (isRelease ? "" : "-SNAPSHOT")
1212

1313
sourceCompatibility = 1.8
1414
targetCompatibility = 1.8
@@ -52,7 +52,7 @@ dependencies {
5252

5353
test {
5454
useJUnitPlatform()
55-
maxParallelForks 4
55+
maxParallelForks = 1
5656
//we want display the following test events
5757
testLogging {
5858
events "PASSED", "STARTED", "FAILED", "SKIPPED"

src/main/java/com/herumi/mcl/Mcl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
package com.herumi.mcl;
1010

11-
public class Mcl implements MclConstants {
11+
public class Mcl {
1212
public static void SystemInit(int curveType) {
1313
MclJNI.SystemInit(curveType);
1414
}

src/main/java/com/herumi/mcl/MclConstants.java

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/main/java/org/cryptimeleon/mclwrap/bn254/MclBasicBilinearGroup.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import org.cryptimeleon.math.structures.groups.basic.BasicBilinearGroup;
55

66
/**
7-
* A wrapper (with naive evaluation of operations) around the efficient type 3 Barreto-Naehrig pairing implementation
8-
* with a group order of 254 bits provided by the Mcl library.
7+
* A wrapper (with naive evaluation of operations) around the efficient type 3 Barreto-Naehrig or BLS pairing implementation
8+
* provided by the Mcl library.
99
* <p>
1010
* Operation evaluation is done naively via {@link BasicBilinearGroup}.
1111
*
@@ -14,7 +14,11 @@
1414
public class MclBasicBilinearGroup extends BasicBilinearGroup {
1515

1616
public MclBasicBilinearGroup() {
17-
super(new MclBilinearGroupImpl());
17+
this(MclBilinearGroup.defaultGroup);
18+
}
19+
20+
public MclBasicBilinearGroup(MclBilinearGroup.GroupChoice groupChoice) {
21+
super(new MclBilinearGroupImpl(groupChoice));
1822
}
1923

2024
public MclBasicBilinearGroup(Representation repr) {

src/main/java/org/cryptimeleon/mclwrap/bn254/MclBilinearGroup.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import org.cryptimeleon.math.structures.groups.lazy.LazyBilinearGroup;
55

66
/**
7-
* A wrapper (with lazy evaluation of operations) around the efficient type 3 Barreto-Naehrig pairing implementation
8-
* with a group order of 254 bits provided by the Mcl library.
7+
* A wrapper (with lazy evaluation of operations) around the efficient type 3 Barreto-Naehrig or BLS pairing implementation
8+
* provided by the Mcl library.
99
* <p>
1010
* Operation evaluation is done lazily via {@link LazyBilinearGroup}.
1111
* This class should be preferred over {@link MclBasicBilinearGroup} due to potential performance advantages.
@@ -14,11 +14,45 @@
1414
*/
1515
public class MclBilinearGroup extends LazyBilinearGroup {
1616

17+
public enum GroupChoice {
18+
BN254(0),
19+
BLS12_381(5);
20+
//, SECP256K1(102)
21+
22+
final int mclconstant;
23+
24+
GroupChoice(int mclconstant) {
25+
this.mclconstant = mclconstant;
26+
}
27+
}
28+
29+
static final MclBilinearGroup.GroupChoice defaultGroup = MclBilinearGroup.GroupChoice.BN254;
30+
1731
public MclBilinearGroup() {
18-
super(new MclBilinearGroupImpl());
32+
this(defaultGroup);
33+
}
34+
35+
public MclBilinearGroup(GroupChoice groupChoice) {
36+
super(new MclBilinearGroupImpl(groupChoice));
1937
}
2038

2139
public MclBilinearGroup(Representation repr) {
2240
super(repr);
2341
}
42+
43+
/**
44+
* Usually, you can only instantiate one of the Mcl groups (BN/BLS).
45+
* If you try to instantiate the second one within the same JVM, you'll be met with an exception.
46+
* This is a known limitation right now https://github.com/cryptimeleon/mclwrap/issues/5.
47+
*
48+
* Calling this method allows you to reset the group so that you can instantiate the "other" one.
49+
* Please only call this if you know what you're doing. Existing GroupElements will be reinterpreted for the new group,
50+
* so everything will behave pretty weirdly if you keep using them.
51+
*
52+
* This should be fine to do if you don't ever use the old Group/GroupElement/etc. objects anymore after calling this.
53+
*/
54+
public static void resetMclInitializationAndAcceptErrors() {
55+
MclBilinearGroupImpl.initializedGroup = null;
56+
System.err.println("Resetting mcl initialization. Hope you know what you're doing.");
57+
}
2458
}

src/main/java/org/cryptimeleon/mclwrap/bn254/MclBilinearGroupImpl.java

Lines changed: 67 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -15,38 +15,31 @@
1515
import java.nio.file.Files;
1616

1717
/**
18-
* A wrapper around the efficient type 3 Barreto-Naehrig pairing implementation with a group order of 254 bits provided
19-
* by the Mcl library.
18+
* A wrapper around the efficient type 3 Barreto-Naehrig or BLS pairing implementation provided by the Mcl library.
2019
*
2120
* @see <a href="https://github.com/herumi/mcl">Mcl library on Github</a>
2221
*/
2322
class MclBilinearGroupImpl implements BilinearGroupImpl {
24-
private static boolean isInitialized = false;
25-
protected static MclGroup1Impl g1;
26-
protected static MclGroup2Impl g2;
27-
protected static MclGroupTImpl gt;
2823

29-
protected static MclHashIntoG1Impl hashIntoG1;
30-
protected static MclHashIntoG2Impl hashIntoG2;
24+
protected static MclBilinearGroup.GroupChoice initializedGroup = null;
25+
protected MclGroup1Impl g1;
26+
protected MclGroup2Impl g2;
27+
protected MclGroupTImpl gt;
3128

29+
protected MclHashIntoG1Impl hashIntoG1;
30+
protected MclHashIntoG2Impl hashIntoG2;
3231

33-
public MclBilinearGroupImpl() {
34-
init(true);
32+
public MclBilinearGroupImpl(MclBilinearGroup.GroupChoice choice) {
33+
init(choice);
34+
g1 = new MclGroup1Impl(choice);
35+
g2 = new MclGroup2Impl(choice);
36+
gt = new MclGroupTImpl(choice);
37+
hashIntoG1 = new MclHashIntoG1Impl(g1);
38+
hashIntoG2 = new MclHashIntoG2Impl(g2);
3539
}
3640

3741
public MclBilinearGroupImpl(Representation repr) {
38-
this();
39-
if (!repr.str().get().equals("bn254")) {
40-
throw new IllegalArgumentException("Invalid representation");
41-
}
42-
}
43-
44-
/**
45-
* Returns true if the native library is available, false otherwise.
46-
*/
47-
public static boolean isAvailable() {
48-
init(false);
49-
return isInitialized;
42+
this(MclBilinearGroup.GroupChoice.valueOf(repr.str().get()));
5043
}
5144

5245
protected static boolean loadIncludedLibrary(){
@@ -61,7 +54,7 @@ protected static boolean loadIncludedLibrary(){
6154
if(platformArch.equals("x86")){
6255
requiredLibraryName="mcljava-win-x86.dll";
6356
}
64-
if(platformArch.equals("amd64")){
57+
if(platformArch.equals("amd64") || platformArch.equals("x86_64")){
6558
requiredLibraryName="mcljava-win-x64.dll";
6659
}
6760
}
@@ -71,18 +64,19 @@ protected static boolean loadIncludedLibrary(){
7164
if(platformArch.equals("x86") || platformArch.equals("i386")){
7265
requiredLibraryName="mcljava-linux-x86.so";
7366
}
74-
if(platformArch.equals("amd64")){
67+
if(platformArch.equals("amd64") || platformArch.equals("x86_64")){
7568
requiredLibraryName="mcljava-linux-x64.so";
7669
}
7770
}
7871

7972
if(platformName.contains("mac")){
80-
if(platformArch.equals("amd64")){
73+
if(platformArch.equals("amd64") || platformArch.equals("x86_64")){
8174
requiredLibraryName="mcljava-mac-x64.dylib";
8275
}
8376
}
8477

8578
if(requiredLibraryName == null){
79+
System.err.println("Could not find precompiled library for "+platformName+" "+platformArch);
8680
return false;
8781
}
8882
InputStream nativeLibrary = MclBilinearGroupImpl.class.getResourceAsStream(requiredLibraryName);
@@ -117,44 +111,43 @@ protected static boolean loadIncludedLibrary(){
117111
return true;
118112
}
119113

120-
protected static void init(boolean printError) {
121-
if (!isInitialized) {
122-
String lib = "mcljava";
123-
try {
124-
System.loadLibrary(lib);
125-
} catch (UnsatisfiedLinkError le) {
126-
boolean couldLoadProvidedLibrary = loadIncludedLibrary();
127-
if (printError && !couldLoadProvidedLibrary) {
128-
le.printStackTrace();
129-
String libName = System.mapLibraryName(lib);
130-
System.err.println("If you get this error, the required native library " + libName + " was not found and none of the included libraries could be used!");
131-
System.err.println("You need to retrieve the native mcljava library that is appropriate for your platform and install it into one of the lib directories:");
132-
System.err.println(System.getProperty("java.library.path"));
133-
return;
134-
}
135-
else if(printError){
136-
System.err.println("The required native mcl library was not found on this system, but one of the included pre-compiled libraries could be used.");
137-
System.err.println("mclwrap will work as expected, but for optimal run-time performance, please compile the mcljava library from source and install it into one of the lib directories:");
138-
System.err.println(System.getProperty("java.library.path"));
139-
}
140-
}
141-
try {
142-
// TODO: DO we want to offer the other curve type too?
143-
Mcl.SystemInit(Mcl.BN254);
144-
} catch (UnsatisfiedLinkError le) {
145-
if (printError) {
146-
le.printStackTrace();
147-
System.err.println("mcl library was found, but its functions cannot be called properly");
148-
}
114+
protected static synchronized void init(MclBilinearGroup.GroupChoice groupChoice) {
115+
if (initializedGroup == groupChoice)
116+
return;
117+
if (initializedGroup != null)
118+
throw new IllegalArgumentException("mcl has already been initialized with " + initializedGroup + ", you're trying to instantiate " + groupChoice + ". " +
119+
"We currently do not support running multiple mcl settings at once. It's a known limitation of mcl's Java wrapper. " +
120+
"If you promise you won't use the old GroupElements anymore (or don't fear undefined behavior), you can call MclBilinearGroupImpl.resetMclInitialization() and then retry.");
121+
//If you really, really want to make the two settings work concurrently, feel free to pull request that. It's nontrivial though.
122+
//You'd need to adapt the Java wrapper in this project and the corresponding C code in mcl, see discussion here: https://github.com/cryptimeleon/mclwrap/issues/5.
123+
124+
String lib = "mcljava";
125+
try {
126+
System.loadLibrary(lib);
127+
} catch (UnsatisfiedLinkError le) {
128+
boolean couldLoadProvidedLibrary = loadIncludedLibrary();
129+
if (!couldLoadProvidedLibrary) {
130+
le.printStackTrace();
131+
String libName = System.mapLibraryName(lib);
132+
System.err.println("If you get this error, the required native library " + libName + " was not found and none of the included libraries could be used!");
133+
System.err.println("You need to retrieve the native mcljava library that is appropriate for your platform and install it into one of the lib directories:");
134+
System.err.println(System.getProperty("java.library.path"));
135+
System.err.println("See README.md");
149136
return;
137+
} else {
138+
System.err.println("The required native mcl library was not found on this system, but one of the included pre-compiled libraries could be used.");
139+
System.err.println("mclwrap will work as expected, but for optimal run-time performance, please compile the mcljava library from source and install it into one of the lib directories:");
140+
System.err.println(System.getProperty("java.library.path"));
141+
System.err.println("See README.md");
150142
}
151-
isInitialized = true;
152-
g1 = new MclGroup1Impl();
153-
g2 = new MclGroup2Impl();
154-
gt = new MclGroupTImpl();
155-
hashIntoG1 = new MclHashIntoG1Impl(g1);
156-
hashIntoG2 = new MclHashIntoG2Impl(g2);
157143
}
144+
try {
145+
Mcl.SystemInit(groupChoice.mclconstant);
146+
} catch (UnsatisfiedLinkError le) {
147+
throw new RuntimeException("mcl library was loaded, but cannot be initialized", le);
148+
}
149+
150+
initializedGroup = groupChoice;
158151
}
159152

160153
@Override
@@ -199,7 +192,13 @@ public HashIntoGroupImpl getHashIntoGT() throws UnsupportedOperationException {
199192

200193
@Override
201194
public Integer getSecurityLevel() {
202-
return 100;
195+
switch (g1.groupChoice) {
196+
case BN254:
197+
return 100; //https://tools.ietf.org/id/draft-yonezawa-pairing-friendly-curves-00.html "BN256"
198+
case BLS12_381:
199+
return 127; //https://tools.ietf.org/id/draft-yonezawa-pairing-friendly-curves-00.html
200+
}
201+
throw new IllegalArgumentException("unknown security level");
203202
}
204203

205204
@Override
@@ -209,7 +208,7 @@ public BilinearGroup.Type getPairingType() {
209208

210209
@Override
211210
public Representation getRepresentation() {
212-
return new StringRepresentation("bn254");
211+
return new StringRepresentation(g1.groupChoice.name());
213212
}
214213

215214
@Override
@@ -219,6 +218,11 @@ public int hashCode() {
219218

220219
@Override
221220
public boolean equals(Object obj) {
222-
return obj instanceof MclBilinearGroupImpl;
221+
return obj instanceof MclBilinearGroupImpl && ((MclBilinearGroupImpl) obj).g1.equals(g1);
222+
}
223+
224+
@Override
225+
public String toString() {
226+
return g1.groupChoice.toString();
223227
}
224228
}

src/main/java/org/cryptimeleon/mclwrap/bn254/MclGroup1Impl.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
class MclGroup1Impl extends MclGroupImpl {
1010
protected MclGroup1ElementImpl generator = null;
1111

12-
public MclGroup1Impl() {
13-
super();
12+
public MclGroup1Impl(MclBilinearGroup.GroupChoice groupChoice) {
13+
super(groupChoice);
1414
}
1515

1616
public MclGroup1Impl(Representation repr) {
@@ -58,7 +58,13 @@ public MclGroup1ElementImpl getGenerator() throws UnsupportedOperationException
5858

5959
@Override
6060
public double estimateCostInvPerOp() {
61-
return 1.875;
61+
switch (groupChoice) {
62+
case BN254:
63+
return 1.5;
64+
case BLS12_381:
65+
return 2;
66+
}
67+
throw new IllegalArgumentException("Unknown cost estimate.");
6268
}
6369

6470
}

0 commit comments

Comments
 (0)