Update Compute*KZGProof in java bindings (#182)

This commit is contained in:
Justin Traglia 2023-03-08 14:31:20 -07:00 committed by GitHub
parent 02b7855eb7
commit 6f3751d97b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 117 additions and 27 deletions

View File

@ -185,7 +185,7 @@ JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_blobToKzgCommitm
return commitment;
}
JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeKzgProof(JNIEnv *env, jclass thisCls, jbyteArray blob, jbyteArray z_bytes)
JNIEXPORT jobject JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeKzgProof(JNIEnv *env, jclass thisCls, jbyteArray blob, jbyteArray z_bytes)
{
if (settings == NULL)
{
@ -207,16 +207,22 @@ JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeKzgProof(
return NULL;
}
/* The output variables, will be combined in a tuple */
jbyteArray proof = (*env)->NewByteArray(env, BYTES_PER_PROOF);
jbyteArray y = (*env)->NewByteArray(env, BYTES_PER_FIELD_ELEMENT);
/* The native variables */
KZGProof *proof_native = (KZGProof *)(uint8_t *)(*env)->GetByteArrayElements(env, proof, NULL);
Bytes32 *y_native = (Bytes32 *)(uint8_t *)(*env)->GetByteArrayElements(env, y, NULL);
Blob *blob_native = (Blob *)(*env)->GetByteArrayElements(env, blob, NULL);
Bytes32 *z_native = (Bytes32 *)(*env)->GetByteArrayElements(env, z_bytes, NULL);
jbyteArray proof = (*env)->NewByteArray(env, BYTES_PER_PROOF);
KZGProof *proof_native = (KZGProof *)(uint8_t *)(*env)->GetByteArrayElements(env, proof, NULL);
C_KZG_RET ret = compute_kzg_proof(proof_native, y_native, blob_native, z_native, settings);
C_KZG_RET ret = compute_kzg_proof(proof_native, blob_native, z_native, settings);
(*env)->ReleaseByteArrayElements(env, blob, (jbyte *)blob_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, proof, (jbyte *)proof_native, 0);
(*env)->ReleaseByteArrayElements(env, y, (jbyte *)y_native, 0);
(*env)->ReleaseByteArrayElements(env, blob, (jbyte *)blob_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, z_bytes, (jbyte *)z_native, JNI_ABORT);
if (ret != C_KZG_OK)
{
@ -224,10 +230,31 @@ JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeKzgProof(
return NULL;
}
return proof;
jclass tupleClass = (*env)->FindClass(env, "ethereum/ckzg4844/Tuple");
if (tupleClass == NULL)
{
throw_exception(env, "Failed to find Tuple class.");
return NULL;
}
jmethodID tupleConstructor = (*env)->GetMethodID(env, tupleClass, "<init>", "([B[B)V");
if (tupleConstructor == NULL)
{
throw_exception(env, "Failed to find Tuple constructor.");
return NULL;
}
jobject tuple = (*env)->NewObject(env, tupleClass, tupleConstructor, proof, y);
if (tuple == NULL)
{
throw_exception(env, "Failed to instantiate new Tuple.");
return NULL;
}
return tuple;
}
JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeBlobKzgProof(JNIEnv *env, jclass thisCls, jbyteArray blob)
JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeBlobKzgProof(JNIEnv *env, jclass thisCls, jbyteArray blob, jbyteArray commitment_bytes)
{
if (settings == NULL)
{
@ -242,14 +269,23 @@ JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeBlobKzgPr
return NULL;
}
size_t commitment_bytes_size = (size_t)(*env)->GetArrayLength(env, commitment_bytes);
if (commitment_bytes_size != BYTES_PER_COMMITMENT)
{
throw_invalid_size_exception(env, "Invalid commitment size.", commitment_bytes_size, BYTES_PER_COMMITMENT);
return NULL;
}
Blob *blob_native = (Blob *)(*env)->GetByteArrayElements(env, blob, NULL);
Bytes48 *commitment_native = (Bytes48 *)(*env)->GetByteArrayElements(env, commitment_bytes, NULL);
jbyteArray proof = (*env)->NewByteArray(env, BYTES_PER_PROOF);
KZGProof *proof_native = (KZGProof *)(uint8_t *)(*env)->GetByteArrayElements(env, proof, NULL);
C_KZG_RET ret = compute_blob_kzg_proof(proof_native, blob_native, settings);
C_KZG_RET ret = compute_blob_kzg_proof(proof_native, blob_native, commitment_native, settings);
(*env)->ReleaseByteArrayElements(env, blob, (jbyte *)blob_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, commitment_bytes, (jbyte *)commitment_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, proof, (jbyte *)proof_native, 0);
if (ret != C_KZG_OK)

View File

@ -53,10 +53,12 @@ public class CKZG4844JNIBenchmark {
@State(Scope.Benchmark)
public static class ComputeBlobKzgProofState {
private byte[] blob;
private byte[] commitment;
@Setup(Level.Iteration)
public void setUp() {
blob = TestUtils.createRandomBlob();
commitment = TestUtils.createRandomCommitment();
}
}
@ -123,13 +125,13 @@ public class CKZG4844JNIBenchmark {
}
@Benchmark
public byte[] computeKzgProof(final ComputeKzgProofState state) {
public Tuple computeKzgProof(final ComputeKzgProofState state) {
return CKZG4844JNI.computeKzgProof(state.blob, state.z);
}
@Benchmark
public byte[] computeBlobKzgProof(final ComputeBlobKzgProofState state) {
return CKZG4844JNI.computeBlobKzgProof(state.blob);
return CKZG4844JNI.computeBlobKzgProof(state.blob, state.commitment);
}
@Benchmark

View File

@ -156,19 +156,20 @@ public class CKZG4844JNI {
*
* @param blob blob bytes
* @param z_bytes a point
* @return the proof
* @return a tuple of the proof and the value y = f(z)
* @throws CKZGException if there is a crypto error
*/
public static native byte[] computeKzgProof(byte[] blob, byte[] z_bytes);
public static native Tuple computeKzgProof(byte[] blob, byte[] z_bytes);
/**
* Given a blob, return the KZG proof that is used to verify it against the commitment
*
* @param blob blob bytes
* @return the aggregated proof
* @param commitment_bytes commitment bytes
* @return the proof
* @throws CKZGException if there is a crypto error
*/
public static native byte[] computeBlobKzgProof(byte[] blob);
public static native byte[] computeBlobKzgProof(byte[] blob, byte[] commitment_bytes);
/**
* Verify the proof by point evaluation for the given commitment

View File

@ -0,0 +1,23 @@
package ethereum.ckzg4844;
public class Tuple {
private byte[] first;
private byte[] second;
public Tuple(byte[] first, byte[] second) {
this.first = first;
this.second = second;
}
public byte[] getFirst() {
return first;
}
public byte[] getSecond() {
return second;
}
public static Tuple of(byte[] first, byte[] second) {
return new Tuple(first, second);
}
}

View File

@ -70,8 +70,9 @@ public class CKZG4844JNITest {
if (PRESET != Preset.MAINNET) return;
try {
byte[] proof = CKZG4844JNI.computeKzgProof(test.getInput().getBlob(), test.getInput().getZ());
assertArrayEquals(test.getOutput(), proof);
Tuple tuple = CKZG4844JNI.computeKzgProof(test.getInput().getBlob(), test.getInput().getZ());
assertArrayEquals(test.getOutput().getFirst(), tuple.getFirst());
assertArrayEquals(test.getOutput().getSecond(), tuple.getSecond());
} catch (CKZGException ex) {
assertNull(test.getOutput());
}
@ -83,7 +84,9 @@ public class CKZG4844JNITest {
if (PRESET != Preset.MAINNET) return;
try {
byte[] proof = CKZG4844JNI.computeBlobKzgProof(test.getInput().getBlob());
byte[] proof =
CKZG4844JNI.computeBlobKzgProof(
test.getInput().getBlob(), test.getInput().getCommitment());
assertArrayEquals(test.getOutput(), proof);
} catch (CKZGException ex) {
assertNull(test.getOutput());
@ -165,7 +168,7 @@ public class CKZG4844JNITest {
i -> {
blobsArray[i] = TestUtils.createRandomBlob();
commitmentsArray[i] = CKZG4844JNI.blobToKzgCommitment(blobsArray[i]);
proofsArray[i] = CKZG4844JNI.computeBlobKzgProof(blobsArray[i]);
proofsArray[i] = CKZG4844JNI.computeBlobKzgProof(blobsArray[i], commitmentsArray[i]);
});
final byte[] blobs = TestUtils.flatten(blobsArray);
final byte[] commitments = TestUtils.flatten(commitmentsArray);
@ -188,8 +191,9 @@ public class CKZG4844JNITest {
loadTrustedSetup();
final byte[] blob = TestUtils.createRandomBlob();
final byte[] z_bytes = TestUtils.randomBLSFieldElementBytes();
final byte[] proof = CKZG4844JNI.computeKzgProof(blob, z_bytes);
assertEquals(CKZG4844JNI.BYTES_PER_PROOF, proof.length);
final Tuple tuple = CKZG4844JNI.computeKzgProof(blob, z_bytes);
assertEquals(CKZG4844JNI.BYTES_PER_PROOF, tuple.getFirst().length);
assertEquals(CKZG4844JNI.BYTES_PER_FIELD_ELEMENT, tuple.getSecond().length);
CKZG4844JNI.freeTrustedSetup();
}
@ -197,7 +201,8 @@ public class CKZG4844JNITest {
public void checkComputeBlobKzgProof() {
loadTrustedSetup();
final byte[] blob = TestUtils.createRandomBlob();
final byte[] proof = CKZG4844JNI.computeBlobKzgProof(blob);
final byte[] commitment = TestUtils.createRandomCommitment();
final byte[] proof = CKZG4844JNI.computeBlobKzgProof(blob, commitment);
assertEquals(CKZG4844JNI.BYTES_PER_PROOF, proof.length);
CKZG4844JNI.freeTrustedSetup();
}
@ -254,7 +259,9 @@ public class CKZG4844JNITest {
exception.getErrorMessage());
exception =
assertThrows(CKZGException.class, () -> CKZG4844JNI.computeBlobKzgProof(new byte[123]));
assertThrows(
CKZGException.class,
() -> CKZG4844JNI.computeBlobKzgProof(new byte[123], new byte[32]));
assertEquals(C_KZG_BADARGS, exception.getError());
assertEquals(
@ -262,6 +269,18 @@ public class CKZG4844JNITest {
"Invalid blob size. Expected %d bytes but got 123.", CKZG4844JNI.getBytesPerBlob()),
exception.getErrorMessage());
exception =
assertThrows(
CKZGException.class,
() ->
CKZG4844JNI.computeBlobKzgProof(
new byte[CKZG4844JNI.getBytesPerBlob()], new byte[49]));
assertEquals(C_KZG_BADARGS, exception.getError());
assertEquals(
String.format("Invalid commitment size. Expected 48 bytes but got 49."),
exception.getErrorMessage());
exception =
assertThrows(
CKZGException.class,

View File

@ -61,7 +61,7 @@ public class TestUtils {
}
public static byte[] createRandomProof() {
return CKZG4844JNI.computeBlobKzgProof(createRandomBlob());
return CKZG4844JNI.computeBlobKzgProof(createRandomBlob(), createRandomCommitment());
}
public static byte[] createRandomProofs(final int count) {

View File

@ -5,10 +5,15 @@ import org.apache.tuweni.bytes.Bytes;
public class ComputeBlobKzgProofTest {
public static class Input {
private String blob;
private String commitment;
public byte[] getBlob() {
return Bytes.fromHexString(blob).toArray();
}
public byte[] getCommitment() {
return Bytes.fromHexString(commitment).toArray();
}
}
private Input input;

View File

@ -1,5 +1,7 @@
package ethereum.ckzg4844.test_formats;
import ethereum.ckzg4844.Tuple;
import java.util.List;
import org.apache.tuweni.bytes.Bytes;
public class ComputeKzgProofTest {
@ -17,16 +19,18 @@ public class ComputeKzgProofTest {
}
private Input input;
private String output;
private List<String> output;
public Input getInput() {
return input;
}
public byte[] getOutput() {
public Tuple getOutput() {
if (output == null) {
return null;
}
return Bytes.fromHexString(output).toArray();
byte[] proof = Bytes.fromHexString(output.get(0)).toArray();
byte[] y = Bytes.fromHexString(output.get(1)).toArray();
return Tuple.of(proof, y);
}
}