Skip to content

Commit

Permalink
In batch cell verification, take commitment for each cell (#451)
Browse files Browse the repository at this point in the history
  • Loading branch information
jtraglia authored Jul 11, 2024
1 parent 5e4be92 commit 5ce1d4f
Show file tree
Hide file tree
Showing 59 changed files with 1,232 additions and 361 deletions.
5 changes: 2 additions & 3 deletions bindings/csharp/Ckzg.Bindings/Ckzg.Bindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ private static extern unsafe KzgResult VerifyCellKzgProof(out bool result, byte*
byte* cell, byte* proof, IntPtr ts);

[DllImport("ckzg", EntryPoint = "verify_cell_kzg_proof_batch", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult VerifyCellKzgProofBatch(out bool result, byte* row_commitments,
int num_commitments, ulong* row_indices, ulong* column_indices, byte* cells, byte* proofs,
int num_cells, IntPtr ts);
private static extern unsafe KzgResult VerifyCellKzgProofBatch(out bool result, byte* commitments,
ulong* column_indices, byte* cells, byte* proofs, int num_cells, IntPtr ts);

[DllImport("ckzg", EntryPoint = "recover_cells_and_kzg_proofs", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult RecoverCellsAndKzgProofs(byte *recovered_cells, byte *recovered_proofs,
Expand Down
16 changes: 7 additions & 9 deletions bindings/csharp/Ckzg.Bindings/Ckzg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,23 +228,21 @@ public static unsafe bool VerifyCellKzgProof(ReadOnlySpan<byte> commitment, ulon
}
}

public static unsafe bool VerifyCellKzgProofBatch(ReadOnlySpan<byte> rowCommitments, int numRowCommitments,
ReadOnlySpan<ulong> rowIndices, ReadOnlySpan<ulong> columnIndices, ReadOnlySpan<byte> cells,
ReadOnlySpan<byte> proofs, int numCells, IntPtr ckzgSetup)
public static unsafe bool VerifyCellKzgProofBatch(ReadOnlySpan<byte> commitments, ReadOnlySpan<ulong> columnIndices,
ReadOnlySpan<byte> cells, ReadOnlySpan<byte> proofs, int numCells, IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(rowCommitments, nameof(rowCommitments), BytesPerCommitment * numRowCommitments);
ThrowOnInvalidLength(rowIndices, nameof(rowIndices), numCells);
ThrowOnInvalidLength(commitments, nameof(commitments), BytesPerCommitment * numCells);
ThrowOnInvalidLength(columnIndices, nameof(columnIndices), numCells);
ThrowOnInvalidLength(cells, nameof(cells), BytesPerCell * numCells);
ThrowOnInvalidLength(proofs, nameof(proofs), BytesPerProof * numCells);

fixed (byte* rowCommitmentPtr = rowCommitments, cellsPtr = cells, proofsPtr = proofs)
fixed (byte* commitmentsPtr = commitments, cellsPtr = cells, proofsPtr = proofs)
{
fixed (ulong* rowIndicesPtr = rowIndices, columnIndicesPtr = columnIndices)
fixed (ulong* columnIndicesPtr = columnIndices)
{
KzgResult kzgResult = VerifyCellKzgProofBatch(out var result, rowCommitmentPtr, numRowCommitments,
rowIndicesPtr, columnIndicesPtr, cellsPtr, proofsPtr, numCells, ckzgSetup);
KzgResult kzgResult = VerifyCellKzgProofBatch(out var result, commitmentsPtr,
columnIndicesPtr, cellsPtr, proofsPtr, numCells, ckzgSetup);
ThrowOnError(kzgResult);
return result;
}
Expand Down
9 changes: 3 additions & 6 deletions bindings/csharp/Ckzg.Test/ReferenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,7 @@ public void TestVerifyCellKzgProof()

private class VerifyCellKzgProofBatchInput
{
public List<string> RowCommitments { get; set; } = null!;
public List<ulong> RowIndices { get; set; } = null!;
public List<string> Commitments { get; set; } = null!;
public List<ulong> ColumnIndices { get; set; } = null!;
public List<string> Cells { get; set; } = null!;
public List<string> Proofs { get; set; } = null!;
Expand All @@ -494,17 +493,15 @@ public void TestVerifyCellKzgProofBatch()
VerifyCellKzgProofBatchTest test = _deserializer.Deserialize<VerifyCellKzgProofBatchTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));

byte[] rowCommitments = GetFlatBytes(test.Input.RowCommitments);
ulong[] rowIndices = test.Input.RowIndices.ToArray();
byte[] commitments = GetFlatBytes(test.Input.Commitments);
ulong[] columnIndices = test.Input.ColumnIndices.ToArray();
byte[] cells = GetFlatBytes(test.Input.Cells);
byte[] proofs = GetFlatBytes(test.Input.Proofs);
int numCommitments = rowCommitments.Length / Ckzg.BytesPerCommitment;
int numCells = cells.Length / Ckzg.BytesPerCell;

try
{
bool isCorrect = Ckzg.VerifyCellKzgProofBatch(rowCommitments, numCommitments, rowIndices, columnIndices, cells, proofs, numCells, _ts);
bool isCorrect = Ckzg.VerifyCellKzgProofBatch(commitments, columnIndices, cells, proofs, numCells, _ts);
Assert.That(isCorrect, Is.EqualTo(test.Output));
}
catch
Expand Down
8 changes: 2 additions & 6 deletions bindings/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,29 +502,25 @@ VerifyCellKZGProofBatch is the binding for:
C_KZG_RET verify_cell_kzg_proof_batch(
bool *ok,
const Bytes48 *commitments_bytes,
size_t num_commitments,
const uint64_t *row_indices,
const uint64_t *column_indices,
const Cell *cells,
const Bytes48 *proofs_bytes,
size_t num_cells,
const KZGSettings *s);
*/
func VerifyCellKZGProofBatch(commitmentsBytes []Bytes48, rowIndices, columnIndices []uint64, cells []Cell, proofsBytes []Bytes48) (bool, error) {
func VerifyCellKZGProofBatch(commitmentsBytes []Bytes48, columnIndices []uint64, cells []Cell, proofsBytes []Bytes48) (bool, error) {
if !loaded {
panic("trusted setup isn't loaded")
}
cellCount := len(cells)
if len(rowIndices) != cellCount || len(columnIndices) != cellCount || len(proofsBytes) != cellCount {
if len(commitmentsBytes) != cellCount || len(columnIndices) != cellCount || len(proofsBytes) != cellCount {
return false, ErrBadArgs
}

var result C.bool
ret := C.verify_cell_kzg_proof_batch(
&result,
*(**C.Bytes48)(unsafe.Pointer(&commitmentsBytes)),
(C.size_t)(len(commitmentsBytes)),
*(**C.uint64_t)(unsafe.Pointer(&rowIndices)),
*(**C.uint64_t)(unsafe.Pointer(&columnIndices)),
*(**C.Cell)(unsafe.Pointer(&cells)),
*(**C.Bytes48)(unsafe.Pointer(&proofsBytes)),
Expand Down
42 changes: 20 additions & 22 deletions bindings/go/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@ func getPartialCells(cells [cellsPerExtBlob]Cell, i int) ([]uint64, []Cell) {
return cellIndices, partialCells
}

func getColumns(cellRows [][cellsPerExtBlob]Cell, proofRows [][cellsPerExtBlob]Bytes48, numCols int) ([]uint64, []uint64, []Cell, []Bytes48) {
var rowIndices []uint64
func getColumns(blobCommitments []Bytes48, cellRows [][cellsPerExtBlob]Cell, proofRows [][cellsPerExtBlob]Bytes48, numCols int) ([]Bytes48, []uint64, []Cell, []Bytes48) {
var cellCommitments []Bytes48
var columnIndices []uint64
var cells []Cell
var cellProofs []Bytes48
for i := range cellRows {
for j := 0; j < numCols; j++ {
rowIndices = append(rowIndices, uint64(i))
cellCommitments = append(cellCommitments, blobCommitments[i])
columnIndices = append(columnIndices, uint64(j))
cells = append(cells, cellRows[i][j])
cellProofs = append(cellProofs, proofRows[i][j])
}
}
return rowIndices, columnIndices, cells, cellProofs
return cellCommitments, columnIndices, cells, cellProofs
}

func divideRoundUp(a, b int) int {
Expand Down Expand Up @@ -545,11 +545,10 @@ func TestVerifyCellKZGProof(t *testing.T) {
func TestVerifyCellKZGProofBatch(t *testing.T) {
type Test struct {
Input struct {
RowCommitments []string `yaml:"row_commitments"`
RowIndices []uint64 `yaml:"row_indices"`
ColumnIndices []uint64 `yaml:"column_indices"`
Cells []string `yaml:"cells"`
Proofs []string `yaml:"proofs"`
Commitments []string `yaml:"commitments"`
ColumnIndices []uint64 `yaml:"column_indices"`
Cells []string `yaml:"cells"`
Proofs []string `yaml:"proofs"`
}
Output *bool `yaml:"output"`
}
Expand All @@ -567,18 +566,17 @@ func TestVerifyCellKZGProofBatch(t *testing.T) {
require.NoError(t, testFile.Close())
require.NoError(t, err)

var rowCommitments []Bytes48
for _, c := range test.Input.RowCommitments {
var commitments []Bytes48
for _, c := range test.Input.Commitments {
var commitment Bytes48
err = commitment.UnmarshalText([]byte(c))
if err != nil {
require.Nil(t, test.Output)
return
}
rowCommitments = append(rowCommitments, commitment)
commitments = append(commitments, commitment)
}

rowIndices := test.Input.RowIndices
columnIndices := test.Input.ColumnIndices

var cells []Cell
Expand All @@ -603,7 +601,7 @@ func TestVerifyCellKZGProofBatch(t *testing.T) {
proofs = append(proofs, proof)
}

valid, err := VerifyCellKZGProofBatch(rowCommitments, rowIndices, columnIndices, cells, proofs)
valid, err := VerifyCellKZGProofBatch(commitments, columnIndices, cells, proofs)
if err == nil {
require.NotNil(t, test.Output)
require.Equal(t, *test.Output, valid)
Expand Down Expand Up @@ -857,29 +855,29 @@ func Benchmark(b *testing.B) {
})

b.Run("VerifyCellKZGProofBatch", func(b *testing.B) {
var rowIndices []uint64
var cellCommitments []Bytes48
var columnIndices []uint64
var cells []Cell
var cellProofs []Bytes48
for rowIndex, blobCell := range blobCells {
for columnIndex, cell := range blobCell {
rowIndices = append(rowIndices, uint64(rowIndex))
cellCommitments = append(cellCommitments, commitments[rowIndex])
columnIndices = append(columnIndices, uint64(columnIndex))
cells = append(cells, cell)
cellProofs = append(cellProofs, blobCellProofs[rowIndex][columnIndex])
}
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
ok, err := VerifyCellKZGProofBatch(commitments[:], rowIndices, columnIndices, cells, cellProofs)
ok, err := VerifyCellKZGProofBatch(cellCommitments, columnIndices, cells, cellProofs)
require.NoError(b, err)
require.True(b, ok)
}
})

for i := 1; i <= length; i *= 2 {
b.Run(fmt.Sprintf("VerifyRows(count=%v)", i), func(b *testing.B) {
var rowIndices []uint64
var cellCommitments []Bytes48
var columnIndices []uint64
var cells []Cell
var cellProofs []Bytes48
Expand All @@ -888,26 +886,26 @@ func Benchmark(b *testing.B) {
break
}
for columnIndex, cell := range blobCell {
rowIndices = append(rowIndices, uint64(rowIndex))
cellCommitments = append(cellCommitments, commitments[rowIndex])
columnIndices = append(columnIndices, uint64(columnIndex))
cells = append(cells, cell)
cellProofs = append(cellProofs, blobCellProofs[rowIndex][columnIndex])
}
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
ok, err := VerifyCellKZGProofBatch(commitments[:i], rowIndices, columnIndices, cells, cellProofs)
ok, err := VerifyCellKZGProofBatch(cellCommitments, columnIndices, cells, cellProofs)
require.NoError(b, err)
require.True(b, ok)
}
})
}

for i := 1; i <= cellsPerExtBlob; i *= 2 {
rowIndices, columnIndices, cells, cellProofs := getColumns(blobCells[:], blobCellProofs[:], i)
cellCommitments, columnIndices, cells, cellProofs := getColumns(commitments[:], blobCells[:], blobCellProofs[:], i)
b.Run(fmt.Sprintf("VerifyColumns(count=%v)", i), func(b *testing.B) {
for n := 0; n < b.N; n++ {
ok, err := VerifyCellKZGProofBatch(commitments[:], rowIndices, columnIndices, cells, cellProofs)
ok, err := VerifyCellKZGProofBatch(cellCommitments, columnIndices, cells, cellProofs)
require.NoError(b, err)
require.True(b, ok)
}
Expand Down
13 changes: 5 additions & 8 deletions bindings/java/c_kzg_4844_jni.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyCellKzgProof
return (jboolean)out;
}

JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyCellKzgProofBatch(JNIEnv *env, jclass thisCls, jbyteArray commitments_bytes, jlongArray row_indices, jlongArray column_indices, jbyteArray cells, jbyteArray proofs_bytes)
JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyCellKzgProofBatch(JNIEnv *env, jclass thisCls, jbyteArray commitments_bytes, jlongArray column_indices, jbyteArray cells, jbyteArray proofs_bytes)
{
if (settings == NULL)
{
Expand All @@ -630,15 +630,14 @@ JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyCellKzgProof
return 0;
}
size_t num_commitments = commitments_size / BYTES_PER_COMMITMENT;
size_t count = num_commitments;

size_t row_indices_count = (size_t)(*env)->GetArrayLength(env, row_indices);
size_t column_indices_count = (size_t)(*env)->GetArrayLength(env, column_indices);
if (row_indices_count != column_indices_count)
if (column_indices_count != count)
{
throw_invalid_size_exception(env, "Invalid columnIndices counts.", row_indices_count, column_indices_count);
throw_invalid_size_exception(env, "Invalid columnIndices size.", column_indices_count, count);
return 0;
}
size_t count = row_indices_count;

size_t cells_size = (size_t)(*env)->GetArrayLength(env, cells);
if (cells_size != count * BYTES_PER_CELL)
Expand All @@ -655,16 +654,14 @@ JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyCellKzgProof
}

Bytes48 *commitments_native = (Bytes48 *)(*env)->GetByteArrayElements(env, commitments_bytes, NULL);
uint64_t *row_indices_native = (uint64_t *)(*env)->GetLongArrayElements(env, row_indices, NULL);
uint64_t *column_indices_native = (uint64_t *)(*env)->GetLongArrayElements(env, column_indices, NULL);
Cell *cells_native = (Cell *)(*env)->GetByteArrayElements(env, cells, NULL);
Bytes48 *proofs_native = (Bytes48 *)(*env)->GetByteArrayElements(env, proofs_bytes, NULL);

bool out;
C_KZG_RET ret = verify_cell_kzg_proof_batch(&out, commitments_native, num_commitments, row_indices_native, column_indices_native, cells_native, proofs_native, count, settings);
C_KZG_RET ret = verify_cell_kzg_proof_batch(&out, commitments_native, column_indices_native, cells_native, proofs_native, count, settings);

(*env)->ReleaseByteArrayElements(env, commitments_bytes, (jbyte *)commitments_native, JNI_ABORT);
(*env)->ReleaseLongArrayElements(env, row_indices, (jlong *)row_indices_native, JNI_ABORT);
(*env)->ReleaseLongArrayElements(env, column_indices, (jlong *)column_indices_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, cells, (jbyte *)cells_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, proofs_bytes, (jbyte *)proofs_native, JNI_ABORT);
Expand Down
4 changes: 2 additions & 2 deletions bindings/java/c_kzg_4844_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 @@ -238,18 +238,13 @@ public static native boolean verifyCellKzgProof(
/**
* Verify that multiple cells' proofs are valid.
*
* @param commitmentsBytes the commitments for all blobs
* @param rowIndices the row index for each cell
* @param commitmentsBytes the commitments for each cell
* @param columnIndices the column index for each cell
* @param cells the cells to verify
* @param proofsBytes the proof for each cell
* @return true if the cells are valid with respect to the given commitments
* @throws CKZGException if there is a crypto error
*/
public static native boolean verifyCellKzgProofBatch(
byte[] commitmentsBytes,
long[] rowIndices,
long[] columnIndices,
byte[] cells,
byte[] proofsBytes);
byte[] commitmentsBytes, long[] columnIndices, byte[] cells, byte[] proofsBytes);
}
24 changes: 14 additions & 10 deletions bindings/java/src/test/java/ethereum/ckzg4844/CKZG4844JNITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,7 @@ public void verifyCellKzgProofBatchTests(final VerifyCellKzgProofBatchTest test)
try {
boolean valid =
CKZG4844JNI.verifyCellKzgProofBatch(
test.getInput().getRowCommitments(),
test.getInput().getRowIndices(),
test.getInput().getCommitments(),
test.getInput().getColumnIndices(),
test.getInput().getCells(),
test.getInput().getProofs());
Expand Down Expand Up @@ -263,20 +262,27 @@ public void checkVerifyCellBatch() {
loadTrustedSetup();

final int count = 6;
final int commitmentsLength = CELLS_PER_EXT_BLOB * BYTES_PER_COMMITMENT;
final int cellsLength = CELLS_PER_EXT_BLOB * BYTES_PER_CELL;
final int proofsLength = CELLS_PER_EXT_BLOB * BYTES_PER_PROOF;

final byte[] commitments = new byte[count * BYTES_PER_COMMITMENT];
final byte[] commitments = new byte[count * commitmentsLength];
final CellsAndProofs[] data = new CellsAndProofs[count];
final long[] rowIndices = new long[count * CELLS_PER_EXT_BLOB];
final long[] columnIndices = new long[count * CELLS_PER_EXT_BLOB];
final byte[] cells = new byte[count * CELLS_PER_EXT_BLOB * BYTES_PER_CELL];
final byte[] proofs = new byte[count * CELLS_PER_EXT_BLOB * BYTES_PER_PROOF];
final byte[] cells = new byte[count * cellsLength];
final byte[] proofs = new byte[count * proofsLength];

for (int i = 0; i < count; i++) {
final byte[] blob = TestUtils.createRandomBlob();
final byte[] commitment = CKZG4844JNI.blobToKzgCommitment(blob);
System.arraycopy(commitment, 0, commitments, i * BYTES_PER_COMMITMENT, BYTES_PER_COMMITMENT);
for (int j = 0; j < CELLS_PER_EXT_BLOB; j++) {
System.arraycopy(
commitment,
0,
commitments,
i * commitmentsLength + j * BYTES_PER_COMMITMENT,
BYTES_PER_COMMITMENT);
}
data[i] = CKZG4844JNI.computeCellsAndKzgProofs(blob);
System.arraycopy(data[i].getCells(), 0, cells, i * cellsLength, cellsLength);
System.arraycopy(data[i].getProofs(), 0, proofs, i * proofsLength, proofsLength);
Expand All @@ -285,13 +291,11 @@ public void checkVerifyCellBatch() {
for (int i = 0; i < count; i++) {
for (int j = 0; j < CELLS_PER_EXT_BLOB; j++) {
final int index = i * CELLS_PER_EXT_BLOB + j;
rowIndices[index] = i;
columnIndices[index] = j;
}
}

assertTrue(
CKZG4844JNI.verifyCellKzgProofBatch(commitments, rowIndices, columnIndices, cells, proofs));
assertTrue(CKZG4844JNI.verifyCellKzgProofBatch(commitments, columnIndices, cells, proofs));
CKZG4844JNI.freeTrustedSetup();
}

Expand Down
Loading

0 comments on commit 5ce1d4f

Please sign in to comment.