Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions bindings/csharp/Ckzg.Bindings/Ckzg.Bindings.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
</ItemGroup>

<ItemGroup>
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/win-x64/native/ckzg.dll" Pack="true" PackagePath="runtimes/win-x64/native/ckzg.dll" />
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/win-x64/native/ckzg.dll" Condition="Exists('runtimes/win-x64/native/ckzg.dll')" Pack="true" PackagePath="runtimes/win-x64/native/ckzg.dll" />

<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/linux-x64/native/ckzg.so" Pack="true" PackagePath="runtimes/linux-x64/native/ckzg.so" />
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/linux-arm64/native/ckzg.so" Pack="true" PackagePath="runtimes/linux-arm64/native/ckzg.so" />
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/linux-x64/native/ckzg.so" Condition="Exists('runtimes/linux-x64/native/ckzg.so')" Pack="true" PackagePath="runtimes/linux-x64/native/ckzg.so" />
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/linux-arm64/native/ckzg.so" Condition="Exists('runtimes/linux-arm64/native/ckzg.so')" Pack="true" PackagePath="runtimes/linux-arm64/native/ckzg.so" />

<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/osx-x64/native/ckzg.dylib" Pack="true" PackagePath="runtimes/osx-x64/native/ckzg.dylib" />
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/osx-arm64/native/ckzg.dylib" Pack="true" PackagePath="runtimes/osx-arm64/native/ckzg.dylib" />
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/osx-x64/native/ckzg.dylib" Condition="Exists('runtimes/osx-x64/native/ckzg.dylib')" Pack="true" PackagePath="runtimes/osx-x64/native/ckzg.dylib" />
<Content CopyToOutputDirectory="PreserveNewest" Include="runtimes/osx-arm64/native/ckzg.dylib" Condition="Exists('runtimes/osx-arm64/native/ckzg.dylib')" Pack="true" PackagePath="runtimes/osx-arm64/native/ckzg.dylib" />
</ItemGroup>

<ItemGroup>
Expand Down
22 changes: 22 additions & 0 deletions bindings/csharp/Ckzg.Bindings/Ckzg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,28 @@ public static unsafe bool VerifyBlobKzgProofBatch(ReadOnlySpan<byte> blobs, Read
}
}

/// <summary>
/// Given a blob, get all of its cells.
/// </summary>
/// <param name="cells">Cells as a flattened byte array</param>
/// <param name="blob">Blob bytes</param>
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when length of an argument is not correct or settings are not correct</exception>
/// <exception cref="ApplicationException">Thrown when the library returns unexpected Error code</exception>
/// <exception cref="InsufficientMemoryException">Thrown when the library has no enough memory to process</exception>
public static unsafe void ComputeCells(Span<byte> cells, ReadOnlySpan<byte> blob, IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(cells, nameof(cells), BytesPerCell * CellsPerExtBlob);
ThrowOnInvalidLength(blob, nameof(blob), BytesPerBlob);

fixed (byte* cellsPtr = cells, blobPtr = blob)
{
KzgResult result = ComputeCellsAndKzgProofs(cellsPtr, null, blobPtr, ckzgSetup);
ThrowOnError(result);
}
}

/// <summary>
/// Given a blob, get all of its cells and proofs.
/// </summary>
Expand Down
50 changes: 50 additions & 0 deletions bindings/csharp/Ckzg.Test/ReferenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void TestSetupLoaded()
private static readonly string _verifyKzgProofTests = Path.Join(TestDir, "verify_kzg_proof");
private static readonly string _verifyBlobKzgProofTests = Path.Join(TestDir, "verify_blob_kzg_proof");
private static readonly string _verifyBlobKzgProofBatchTests = Path.Join(TestDir, "verify_blob_kzg_proof_batch");
private static readonly string _computeCellsTests = Path.Join(TestDir, "compute_cells");
private static readonly string _computeCellsAndKzgProofsTests = Path.Join(TestDir, "compute_cells_and_kzg_proofs");
private static readonly string _recoverCellsAndKzgProofsTests = Path.Join(TestDir, "recover_cells_and_kzg_proofs");
private static readonly string _verifyCellKzgProofBatchTests = Path.Join(TestDir, "verify_cell_kzg_proof_batch");
Expand Down Expand Up @@ -366,6 +367,55 @@ public void TestVerifyBlobKzgProofBatch(VerifyBlobKzgProofBatchTest test)

#endregion

#region ComputeCells

public class ComputeCellsInput
{
public string Blob { get; set; } = null!;
}

public class ComputeCellsTest
{
public ComputeCellsInput Input { get; set; } = null!;
public List<string>? Output { get; set; } = null!;
}

private static IEnumerable<ComputeCellsTest> GetComputeCellsTests()
{
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*/*/data.yaml" });
IEnumerable<string> testFiles = matcher.GetResultsInFullPath(_computeCellsTests);
foreach (string testFile in testFiles)
{
string yaml = File.ReadAllText(testFile);
ComputeCellsTest test = _deserializer.Deserialize<ComputeCellsTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));
yield return test;
}
}


[Test, TestCaseSource(nameof(GetComputeCellsTests))]
public void TestComputeCells(ComputeCellsTest test)
{
byte[] cells = new byte[CellsPerExtBlob * Ckzg.BytesPerCell];
byte[] blob = GetBytes(test.Input.Blob);

try
{
Ckzg.ComputeCells(cells, blob, _ts);
Assert.That(test.Output, Is.Not.EqualTo(null));
byte[] expectedCells = GetFlatBytes(test.Output);
Assert.That(cells, Is.EqualTo(expectedCells));
}
catch
{
Assert.That(test.Output, Is.EqualTo(null));
}
}

#endregion

#region ComputeCellsAndKzgProofs

public class ComputeCellsAndKzgProofsInput
Expand Down
27 changes: 27 additions & 0 deletions bindings/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,33 @@ func VerifyBlobKZGProofBatch(blobs []Blob, commitmentsBytes, proofsBytes []Bytes
return bool(result), nil
}

/*
ComputeCellsAndKZGProofs is the binding for:

C_KZG_RET compute_cells_and_kzg_proofs(
Cell *cells,
KZGProof *proofs,
const Blob *blob,
const KZGSettings *s);
*/
func ComputeCells(blob *Blob) ([CellsPerExtBlob]Cell, error) {
if !loaded {
panic("trusted setup isn't loaded")
}

cells := [CellsPerExtBlob]Cell{}
ret := C.compute_cells_and_kzg_proofs(
(*C.Cell)(unsafe.Pointer(&cells)),
(*C.KZGProof)(nil),
(*C.Blob)(unsafe.Pointer(blob)),
&settings)

if ret != C.C_KZG_OK {
return [CellsPerExtBlob]Cell{}, makeErrorFromRet(ret)
}
return cells, nil
}

/*
ComputeCellsAndKZGProofs is the binding for:

Expand Down
55 changes: 55 additions & 0 deletions bindings/go/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ var (
verifyKZGProofTests = filepath.Join(testDir, "verify_kzg_proof/*/*/*")
verifyBlobKZGProofTests = filepath.Join(testDir, "verify_blob_kzg_proof/*/*/*")
verifyBlobKZGProofBatchTests = filepath.Join(testDir, "verify_blob_kzg_proof_batch/*/*/*")
computeCellsTests = filepath.Join(testDir, "compute_cells/*/*/*")
computeCellsAndKZGProofsTests = filepath.Join(testDir, "compute_cells_and_kzg_proofs/*/*/*")
recoverCellsAndKZGProofsTests = filepath.Join(testDir, "recover_cells_and_kzg_proofs/*/*/*")
verifyCellKZGProofBatchTests = filepath.Join(testDir, "verify_cell_kzg_proof_batch/*/*/*")
Expand Down Expand Up @@ -426,6 +427,53 @@ func TestVerifyBlobKZGProofBatch(t *testing.T) {
}
}

func TestComputeCells(t *testing.T) {
type Test struct {
Input struct {
Blob string `yaml:"blob"`
}
Output *[]string `yaml:"output"`
}

tests, err := filepath.Glob(computeCellsTests)
require.NoError(t, err)
require.True(t, len(tests) > 0)

for _, testPath := range tests {
t.Run(testPath, func(t *testing.T) {
testFile, err := os.Open(testPath)
require.NoError(t, err)
test := Test{}
err = yaml.NewDecoder(testFile).Decode(&test)
require.NoError(t, testFile.Close())
require.NoError(t, err)

var blob Blob
err = blob.UnmarshalText([]byte(test.Input.Blob))
if err != nil {
require.Nil(t, test.Output)
return
}

cells, err := ComputeCells(&blob)
if err == nil {
require.NotNil(t, test.Output)
var expectedCells []Cell
for _, cellStr := range *test.Output {
var cell Cell
err := cell.UnmarshalText([]byte(cellStr))
require.NoError(t, err)
expectedCells = append(expectedCells, cell)
}
require.Equal(t, expectedCells, cells[:])

} else {
require.Nil(t, test.Output)
}
})
}
}

func TestComputeCellsAndKZGProofs(t *testing.T) {
type Test struct {
Input struct {
Expand Down Expand Up @@ -725,6 +773,13 @@ func Benchmark(b *testing.B) {
})
}

b.Run("ComputeCells", func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, err := ComputeCells(&blobs[0])
require.NoError(b, err)
}
})

FreeTrustedSetup()
for i := 0; i <= 8; i++ {
if err := LoadTrustedSetupFile("../../src/trusted_setup.txt", uint(i)); err != nil {
Expand Down
39 changes: 37 additions & 2 deletions bindings/java/ckzg_jni.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,42 @@ Java_ethereum_ckzg4844_CKZG4844JNI_verifyBlobKzgProofBatch(
return (jboolean)out;
}

JNIEXPORT jobject JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeCells(
JNIEnv *env, jclass thisCls, jbyteArray blob) {
if (settings == NULL) {
throw_exception(env, TRUSTED_SETUP_NOT_LOADED);
return NULL;
}

size_t blob_size = (size_t)(*env)->GetArrayLength(env, blob);
if (blob_size != BYTES_PER_BLOB) {
throw_invalid_size_exception(env, "Invalid blob size.", blob_size,
BYTES_PER_BLOB);
return NULL;
}

/* The output cells */
jbyteArray cells =
(*env)->NewByteArray(env, CELLS_PER_EXT_BLOB * BYTES_PER_CELL);

/* The native variables */
Cell *cells_native = (Cell *)(*env)->GetByteArrayElements(env, cells, NULL);
Blob *blob_native = (Blob *)(*env)->GetByteArrayElements(env, blob, NULL);

C_KZG_RET ret =
compute_cells_and_kzg_proofs(cells_native, NULL, blob_native, settings);

(*env)->ReleaseByteArrayElements(env, cells, (jbyte *)cells_native, 0);
(*env)->ReleaseByteArrayElements(env, blob, (jbyte *)blob_native, JNI_ABORT);

if (ret != C_KZG_OK) {
throw_c_kzg_exception(env, ret, "There was an error in computeCells.");
return NULL;
}

return cells;
}

JNIEXPORT jobject JNICALL
Java_ethereum_ckzg4844_CKZG4844JNI_computeCellsAndKzgProofs(JNIEnv *env,
jclass thisCls,
Expand Down Expand Up @@ -637,8 +673,7 @@ Java_ethereum_ckzg4844_CKZG4844JNI_verifyCellKzgProofBatch(
(size_t)(*env)->GetArrayLength(env, commitments_bytes);
if (commitments_size % BYTES_PER_COMMITMENT != 0) {
throw_invalid_size_exception(env, "Invalid commitments size.",
commitments_size,
BYTES_PER_COMMITMENT);
commitments_size, BYTES_PER_COMMITMENT);
return 0;
}
size_t num_commitments = commitments_size / BYTES_PER_COMMITMENT;
Expand Down
12 changes: 10 additions & 2 deletions bindings/java/ckzg_jni.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,15 @@ public static native boolean verifyBlobKzgProof(
public static native boolean verifyBlobKzgProofBatch(
byte[] blobs, byte[] commitmentsBytes, byte[] proofsBytes, long count);

/**
* Get the cells for a given blob.
*
* @param blob the blob to get cells for
* @return the cells
* @throws CKZGException if there is a crypto error
*/
public static native byte[] computeCells(byte[] blob);

/**
* Get the cells and proofs for a given blob.
*
Expand Down
16 changes: 16 additions & 0 deletions bindings/java/src/test/java/ethereum/ckzg4844/CKZG4844JNITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ public void verifyBlobKzgProofBatchTests(final VerifyBlobKzgProofBatchTest test)
}
}

@ParameterizedTest
@MethodSource("getComputeCellsTests")
public void verifyComputeCellsTests(final ComputeCellsTest test) {
try {
byte[] cells = CKZG4844JNI.computeCells(test.getInput().getBlob());
assertArrayEquals(test.getOutput(), cells);
} catch (CKZGException ex) {
assertNull(test.getOutput());
}
}

@ParameterizedTest
@MethodSource("getComputeCellsAndKzgProofsTests")
public void verifyComputeCellsAndKzgProofsTests(final ComputeCellsAndKzgProofsTest test) {
Expand Down Expand Up @@ -522,6 +533,11 @@ private static Stream<VerifyBlobKzgProofBatchTest> getVerifyBlobKzgProofBatchTes
.onClose(CKZG4844JNI::freeTrustedSetup);
}

private static Stream<ComputeCellsTest> getComputeCellsTests() {
loadTrustedSetup();
return TestUtils.getComputeCellsTests().stream().onClose(CKZG4844JNI::freeTrustedSetup);
}

private static Stream<ComputeCellsAndKzgProofsTest> getComputeCellsAndKzgProofsTests() {
loadTrustedSetup();
return TestUtils.getComputeCellsAndKzgProofsTests().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class TestUtils {
private static final String VERIFY_BLOB_KZG_PROOF_TESTS = "../../tests/verify_blob_kzg_proof/";
private static final String VERIFY_BLOB_KZG_PROOF_BATCH_TESTS =
"../../tests/verify_blob_kzg_proof_batch/";
private static final String COMPUTE_CELLS_TESTS = "../../tests/compute_cells/";
private static final String COMPUTE_CELLS_AND_KZG_PROOFS_TESTS =
"../../tests/compute_cells_and_kzg_proofs/";
private static final String RECOVER_CELLS_AND_KZG_PROOFS_TESTS =
Expand Down Expand Up @@ -205,6 +206,24 @@ public static List<VerifyBlobKzgProofBatchTest> getVerifyBlobKzgProofBatchTests(
return tests.build().collect(Collectors.toList());
}

public static List<ComputeCellsTest> getComputeCellsTests() {
final Stream.Builder<ComputeCellsTest> tests = Stream.builder();
List<String> testFiles = getTestFiles(COMPUTE_CELLS_TESTS);
assert !testFiles.isEmpty();

try {
for (String testFile : testFiles) {
String jsonData = Files.readString(Path.of(testFile));
ComputeCellsTest test = OBJECT_MAPPER.readValue(jsonData, ComputeCellsTest.class);
tests.add(test);
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}

return tests.build().collect(Collectors.toList());
}

public static List<ComputeCellsAndKzgProofsTest> getComputeCellsAndKzgProofsTests() {
final Stream.Builder<ComputeCellsAndKzgProofsTest> tests = Stream.builder();
List<String> testFiles = getTestFiles(COMPUTE_CELLS_AND_KZG_PROOFS_TESTS);
Expand Down
Loading
Loading