Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify the wrapper around the c-kzg library #6530

Merged
merged 13 commits into from
Dec 1, 2022
1 change: 1 addition & 0 deletions gradle/versions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ dependencyManagement {

dependency 'io.libp2p:jvm-libp2p-minimal:0.10.0-RELEASE'
dependency 'tech.pegasys:jblst:0.3.8'
dependency 'tech.pegasys:jc-kzg-4844:develop'

dependency 'org.hdrhistogram:HdrHistogram:2.1.12'

Expand Down
10 changes: 3 additions & 7 deletions infrastructure/kzg/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
repositories {
maven { url "https://artifacts.consensys.net/public/maven/maven/" }
}

dependencies {
implementation project(':infrastructure:io')

implementation 'org.apache.tuweni:tuweni-bytes'
implementation 'org.apache.tuweni:tuweni-ssz'
implementation("tech.pegasys:jc-kzg-4844:develop")
implementation 'tech.pegasys:jc-kzg-4844'
implementation 'commons-io:commons-io'

implementation project(":infrastructure:io")
}
163 changes: 55 additions & 108 deletions infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZG.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,119 +13,66 @@

package tech.pegasys.teku.kzg;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.infrastructure.io.resource.ResourceLoader;
import tech.pegasys.teku.kzg.impl.KZG4844;
import tech.pegasys.teku.kzg.impl.KzgException;
import tech.pegasys.teku.kzg.impl.ckzg.CkzgLoader;

/**
* Implements the standard KZG functions needed for the EIP-4844 specification.
*
* <p>This package strives to implement the KZG standard as used in the Eth2 specification and is
* the entry-point for all KZG operations in Teku. Do not rely on any of the classes used by this
* one conforming to the specification or standard.
* This interface specifies all the KZG functions needed for the EIP-4844 specification and is the
* entry-point for all KZG operations in Teku.
*/
public final class KZG {
private static final Logger LOG = LogManager.getLogger();
private static final String FILE_SCHEME = "file";

private static KZG4844 kzgImpl;

static {
resetKzgImplementation();
}

public static void setKzgImplementation(final KZG4844 kzgImpl) {
KZG.kzgImpl = kzgImpl;
}

public static void resetKzgImplementation() {
if (CkzgLoader.INSTANCE.isPresent()) {
kzgImpl = CkzgLoader.INSTANCE.get();
LOG.info("KZG: loaded CKZG library");
} else {
throw new KzgException("Failed to load CKZG library.");
}
}

public static KZG4844 getKzgImpl() {
return kzgImpl;
}

public static void resetTrustedSetup() {
try {
kzgImpl.resetTrustedSetup();
} catch (final KzgException ex) {
LOG.trace("Trying to reset KZG trusted setup which is not loaded");
}
}

public static void loadTrustedSetup(final URL url) {
final String filePath;
try {
filePath = copyResourceToTempFileIfNeeded(url);
} catch (final IOException ex) {
throw new KzgException(
String.format("Failed to copy trusted setup '%s' to temporary file", url), ex);
}
kzgImpl.loadTrustedSetup(filePath);
}

public static KZGProof computeAggregateKzgProof(final List<Bytes> blobs) {
return kzgImpl.computeAggregateKzgProof(blobs);
}

public static boolean verifyAggregateKzgProof(
final List<Bytes> blobs, final List<KZGCommitment> kzgCommitments, final KZGProof kzgProof) {
return kzgImpl.verifyAggregateKzgProof(blobs, kzgCommitments, kzgProof);
}

public static KZGCommitment blobToKzgCommitment(final Bytes blob) {
return kzgImpl.blobToKzgCommitment(blob);
}

public static boolean verifyKzgProof(
final KZGCommitment kzgCommitment,
final Bytes32 z,
final Bytes32 y,
final KZGProof kzgProof) {
return kzgImpl.verifyKzgProof(kzgCommitment, z, y, kzgProof);
}

private static String copyResourceToTempFileIfNeeded(final URL url) throws IOException {
try {
if (url.toURI().getScheme().equals(FILE_SCHEME)) {
// Platform-agnostic safe way to get path
return Paths.get(url.toURI()).toFile().getPath();
}
} catch (final URISyntaxException ex) {
throw new KzgException(String.format("%s is incorrect file path", url), ex);
}

final Bytes resource =
ResourceLoader.urlOrFile("application/octet-stream")
.loadBytes(url.toExternalForm())
.orElseThrow(() -> new FileNotFoundException("Not found"));

File temp = File.createTempFile("resource", ".tmp");
temp.deleteOnExit();

try (final FileOutputStream out = new FileOutputStream(temp)) {
out.write(resource.toArray());
}

return temp.getAbsolutePath();
}
public interface KZG {

KZG NOOP =
new KZG() {
@Override
public void loadTrustedSetup(final URL trustedSetup) throws KZGException {}

@Override
public void freeTrustedSetup() throws KZGException {}

@Override
public KZGProof computeAggregateKzgProof(final List<Bytes> blobs) throws KZGException {
return KZGProof.infinity();
}

@Override
public boolean verifyAggregateKzgProof(
final List<Bytes> blobs,
final List<KZGCommitment> kzgCommitments,
final KZGProof kzgProof)
throws KZGException {
return true;
}

@Override
public KZGCommitment blobToKzgCommitment(final Bytes blob) throws KZGException {
return KZGCommitment.infinity();
}

@Override
public boolean verifyKzgProof(
final KZGCommitment kzgCommitment,
final Bytes32 z,
final Bytes32 y,
final KZGProof kzgProof)
throws KZGException {
return true;
}
};

void loadTrustedSetup(URL trustedSetup) throws KZGException;

void freeTrustedSetup() throws KZGException;

KZGProof computeAggregateKzgProof(List<Bytes> blobs) throws KZGException;

boolean verifyAggregateKzgProof(
List<Bytes> blobs, List<KZGCommitment> kzgCommitments, KZGProof kzgProof) throws KZGException;

KZGCommitment blobToKzgCommitment(Bytes blob) throws KZGException;

boolean verifyKzgProof(KZGCommitment kzgCommitment, Bytes32 z, Bytes32 y, KZGProof kzgProof)
throws KZGException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@ public static KZGCommitment fromSSZBytes(final Bytes bytes) {
reader -> new KZGCommitment(Bytes48.wrap(reader.readFixedBytes(KZG_COMMITMENT_SIZE))));
}

public static KZGCommitment fromBytesCompressed(final Bytes48 bytes)
throws IllegalArgumentException {
public static KZGCommitment fromBytesCompressed(final Bytes48 bytes) {
return new KZGCommitment(bytes);
}

public static KZGCommitment fromArray(final byte[] bytes) {
return fromBytesCompressed(Bytes48.wrap(bytes));
}

private final Bytes48 bytesCompressed;

public KZGCommitment(final Bytes48 bytesCompressed) {
Expand All @@ -71,6 +74,10 @@ public Bytes48 getBytesCompressed() {
return bytesCompressed;
}

public byte[] toArray() {
return bytesCompressed.toArray();
}

public String toAbbreviatedString() {
return getBytesCompressed().toUnprefixedHexString().substring(0, 7);
}
Expand Down Expand Up @@ -98,7 +105,7 @@ public boolean equals(final Object obj) {
return false;
}

KZGCommitment other = (KZGCommitment) obj;
final KZGCommitment other = (KZGCommitment) obj;
return Objects.equals(this.getBytesCompressed(), other.getBytesCompressed());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,11 @@
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.kzg.impl;
package tech.pegasys.teku.kzg;

public class KzgException extends IllegalArgumentException {
public class KZGException extends RuntimeException {

public KzgException(String message) {
StefanBratanov marked this conversation as resolved.
Show resolved Hide resolved
super(message);
}

public KzgException(String message, Throwable cause) {
public KZGException(final String message, final Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,20 @@ public static KZGProof fromBytesCompressed(final Bytes48 bytes) throws IllegalAr
return new KZGProof(bytes);
}

public static KZGProof fromArray(final byte[] bytes) {
return fromBytesCompressed(Bytes48.wrap(bytes));
}

private final Bytes48 bytesCompressed;

public KZGProof(final Bytes48 bytesCompressed) {
this.bytesCompressed = bytesCompressed;
}

/**
* Returns the SSZ serialization of the <em>compressed</em> form of the commitment
* Returns the SSZ serialization of the <em>compressed</em> form of the proof
*
* @return the serialization of the compressed form of the commitment.
* @return the serialization of the compressed form of the proof.
*/
public Bytes toSSZBytes() {
return SSZ.encode(writer -> writer.writeFixedBytes(getBytesCompressed()));
Expand All @@ -69,6 +73,10 @@ public Bytes48 getBytesCompressed() {
return bytesCompressed;
}

public byte[] toArray() {
return bytesCompressed.toArray();
}

public String toAbbreviatedString() {
return getBytesCompressed().toUnprefixedHexString().substring(0, 7);
}
Expand Down Expand Up @@ -96,7 +104,7 @@ public boolean equals(final Object obj) {
return false;
}

KZGProof other = (KZGProof) obj;
final KZGProof other = (KZGProof) obj;
return Objects.equals(this.getBytesCompressed(), other.getBytesCompressed());
}

Expand Down
Loading