Skip to content

Commit

Permalink
API: argument order of functions (breaking external Nim/C/Go/Rust API…
Browse files Browse the repository at this point in the history
… of Ethereum KZG EIP-4844) (#394)
  • Loading branch information
mratsim authored Jun 13, 2024
1 parent 6ca7cbf commit b33479d
Show file tree
Hide file tree
Showing 21 changed files with 323 additions and 227 deletions.
35 changes: 35 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Architecture

## APIs

### Argument orders

Function calls have arguments ordered the following way:

1. Context arguments
2. Threadpool context
3. OUT arguments (only written to)
4. INOUT arguments
5. IN arguments

The first context argument should allow method call syntax

In C, length of arrays immediately follow the array, unless there are multiple array arguments with same length.
If an argument is associated with a label, for domain separation for example,
that label precedes the argument.

### Return values

Constantine avoids returning values bigger than the word size
and prefer mutable out parameters.

1. In some cases they introduce extra copies.
2. There is less guarantees over stack space usage.
3. Nim will zero the values without {.noInit.}
and that zeroing might not be optimized away by the compiler
on large inputs like `Fp12[BLS12_381]` 48\*12 bytes = 576 bytes.
4. As we sometimes return SecretBool or status code, this keeps the API consistent.

## Code organization

TBD
12 changes: 6 additions & 6 deletions benchmarks/bench_eth_eip4844_kzg.nim
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ proc benchBlobToKzgCommitment(b: BenchSet, ctx: ptr EthereumKZGContext, iters: i
block:
bench("blob_to_kzg_commitment", $tp.numThreads & " threads", iters):
var commitment {.noInit.}: array[48, byte]
doAssert cttEthKzg_Success == ctx.blob_to_kzg_commitment_parallel(tp, commitment, b.blobs[0].addr)
doAssert cttEthKzg_Success == tp.blob_to_kzg_commitment_parallel(ctx, commitment, b.blobs[0].addr)
let stopParallel = getMonotime()

tp.shutdown()
Expand Down Expand Up @@ -108,7 +108,7 @@ proc benchComputeKzgProof(b: BenchSet, ctx: ptr EthereumKZGContext, iters: int)
bench("compute_kzg_proof", $tp.numThreads & " threads", iters):
var proof {.noInit.}: array[48, byte]
var eval_at_challenge {.noInit.}: array[32, byte]
doAssert cttEthKzg_Success == ctx.compute_kzg_proof_parallel(tp, proof, eval_at_challenge, b.blobs[0].addr, b.challenge)
doAssert cttEthKzg_Success == tp.compute_kzg_proof_parallel(ctx, proof, eval_at_challenge, b.blobs[0].addr, b.challenge)
let stopParallel = getMonotime()

tp.shutdown()
Expand All @@ -135,7 +135,7 @@ proc benchComputeBlobKzgProof(b: BenchSet, ctx: ptr EthereumKZGContext, iters: i
block:
bench("compute_blob_kzg_proof", $tp.numThreads & " threads", iters):
var proof {.noInit.}: array[48, byte]
doAssert cttEthKzg_Success == ctx.compute_blob_kzg_proof_parallel(tp, proof, b.blobs[0].addr, b.commitments[0])
doAssert cttEthKzg_Success == tp.compute_blob_kzg_proof_parallel(ctx, proof, b.blobs[0].addr, b.commitments[0])
let stopParallel = getMonotime()

tp.shutdown()
Expand Down Expand Up @@ -167,7 +167,7 @@ proc benchVerifyBlobKzgProof(b: BenchSet, ctx: ptr EthereumKZGContext, iters: in
let startParallel = getMonotime()
block:
bench("verify_blob_kzg_proof", $tp.numThreads & " threads", iters):
discard ctx.verify_blob_kzg_proof_parallel(tp, b.blobs[0].addr, b.commitments[0], b.proofs[0])
discard tp.verify_blob_kzg_proof_parallel(ctx, b.blobs[0].addr, b.commitments[0], b.proofs[0])
let stopParallel = getMonotime()

tp.shutdown()
Expand Down Expand Up @@ -205,8 +205,8 @@ proc benchVerifyBlobKzgProofBatch(b: BenchSet, ctx: ptr EthereumKZGContext, iter
let startParallel = getMonotime()
block:
bench("verify_blob_kzg_proof (batch " & $i & ')', $tp.numThreads & " threads", iters):
discard ctx.verify_blob_kzg_proof_batch_parallel(
tp,
discard tp.verify_blob_kzg_proof_batch_parallel(
ctx,
b.blobs.asUnchecked(),
b.commitments.asUnchecked(),
b.proofs.asUnchecked(),
Expand Down
43 changes: 31 additions & 12 deletions constantine-go/constantine.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type (

type EthKzgContext struct {
cCtx *C.ctt_eth_kzg_context
threadpool Threadpool
}

func EthKzgContextNew(trustedSetupFile string) (ctx EthKzgContext, err error) {
Expand All @@ -72,9 +73,14 @@ func EthKzgContextNew(trustedSetupFile string) (ctx EthKzgContext, err error) {
C.GoString(C.ctt_eth_trusted_setup_status_to_string(status)),
)
}
ctx.threadpool.ctx = nil
return ctx, err
}

func (ctx *EthKzgContext) SetThreadpool(tp Threadpool) {
ctx.threadpool = tp
}

func (ctx EthKzgContext) Delete() {
C.ctt_eth_trusted_setup_delete(ctx.cCtx)
}
Expand Down Expand Up @@ -183,9 +189,12 @@ func (ctx EthKzgContext) VerifyBlobKzgProofBatch(blobs []EthBlob, commitments []
// Ethereum EIP-4844 KZG API - Parallel
// -----------------------------------------------------

func (ctx EthKzgContext) BlobToKZGCommitmentParallel(tp Threadpool, blob EthBlob) (commitment EthKzgCommitment, err error) {
func (ctx EthKzgContext) BlobToKZGCommitmentParallel(blob EthBlob) (commitment EthKzgCommitment, err error) {
if ctx.threadpool.ctx == nil {
return commitment, errors.New("BlobToKZGCommitmentParallel: The threadpool is not configured.")
}
status := C.ctt_eth_kzg_blob_to_kzg_commitment_parallel(
ctx.cCtx, tp.ctx,
ctx.threadpool.ctx, ctx.cCtx,
(*C.ctt_eth_kzg_commitment)(unsafe.Pointer(&commitment)),
(*C.ctt_eth_kzg_blob)(unsafe.Pointer(&blob)),
)
Expand All @@ -197,9 +206,12 @@ func (ctx EthKzgContext) BlobToKZGCommitmentParallel(tp Threadpool, blob EthBlob
return commitment, err
}

func (ctx EthKzgContext) ComputeKzgProofParallel(tp Threadpool, blob EthBlob, z EthKzgChallenge) (proof EthKzgProof, y EthKzgEvalAtChallenge, err error) {
func (ctx EthKzgContext) ComputeKzgProofParallel(blob EthBlob, z EthKzgChallenge) (proof EthKzgProof, y EthKzgEvalAtChallenge, err error) {
if ctx.threadpool.ctx == nil {
return proof, y, errors.New("ComputeKzgProofParallel: The Constantine's threadpool is not configured.")
}
status := C.ctt_eth_kzg_compute_kzg_proof_parallel(
ctx.cCtx, tp.ctx,
ctx.threadpool.ctx, ctx.cCtx,
(*C.ctt_eth_kzg_proof)(unsafe.Pointer(&proof)),
(*C.ctt_eth_kzg_eval_at_challenge)(unsafe.Pointer(&y)),
(*C.ctt_eth_kzg_blob)(unsafe.Pointer(&blob)),
Expand All @@ -213,9 +225,12 @@ func (ctx EthKzgContext) ComputeKzgProofParallel(tp Threadpool, blob EthBlob, z
return proof, y, err
}

func (ctx EthKzgContext) ComputeBlobKzgProofParallel(tp Threadpool, blob EthBlob, commitment EthKzgCommitment) (proof EthKzgProof, err error) {
func (ctx EthKzgContext) ComputeBlobKzgProofParallel(blob EthBlob, commitment EthKzgCommitment) (proof EthKzgProof, err error) {
if ctx.threadpool.ctx == nil {
return proof, errors.New("ComputeBlobKzgProofParallel: The threadpool is not configured.")
}
status := C.ctt_eth_kzg_compute_blob_kzg_proof_parallel(
ctx.cCtx, tp.ctx,
ctx.threadpool.ctx, ctx.cCtx,
(*C.ctt_eth_kzg_proof)(unsafe.Pointer(&proof)),
(*C.ctt_eth_kzg_blob)(unsafe.Pointer(&blob)),
(*C.ctt_eth_kzg_commitment)(unsafe.Pointer(&commitment)),
Expand All @@ -228,9 +243,12 @@ func (ctx EthKzgContext) ComputeBlobKzgProofParallel(tp Threadpool, blob EthBlob
return proof, err
}

func (ctx EthKzgContext) VerifyBlobKzgProofParallel(tp Threadpool, blob EthBlob, commitment EthKzgCommitment, proof EthKzgProof) (bool, error) {
func (ctx EthKzgContext) VerifyBlobKzgProofParallel(blob EthBlob, commitment EthKzgCommitment, proof EthKzgProof) (bool, error) {
if ctx.threadpool.ctx == nil {
return false, errors.New("VerifyBlobKzgProofParallel: The threadpool is not configured.")
}
status := C.ctt_eth_kzg_verify_blob_kzg_proof_parallel(
ctx.cCtx, tp.ctx,
ctx.threadpool.ctx, ctx.cCtx,
(*C.ctt_eth_kzg_blob)(unsafe.Pointer(&blob)),
(*C.ctt_eth_kzg_commitment)(unsafe.Pointer(&commitment)),
(*C.ctt_eth_kzg_proof)(unsafe.Pointer(&proof)),
Expand All @@ -244,14 +262,15 @@ func (ctx EthKzgContext) VerifyBlobKzgProofParallel(tp Threadpool, blob EthBlob,
return true, nil
}

func (ctx EthKzgContext) VerifyBlobKzgProofBatchParallel(tp Threadpool, blobs []EthBlob, commitments []EthKzgCommitment, proofs []EthKzgProof, secureRandomBytes [32]byte) (bool, error) {

func (ctx EthKzgContext) VerifyBlobKzgProofBatchParallel(blobs []EthBlob, commitments []EthKzgCommitment, proofs []EthKzgProof, secureRandomBytes [32]byte) (bool, error) {
if len(blobs) != len(commitments) || len(blobs) != len(proofs) {
return false, errors.New("VerifyBlobKzgProofBatch: Lengths of inputs do not match.")
}

if ctx.threadpool.ctx == nil {
return false, errors.New("VerifyBlobKzgProofBatch: The threadpool is not configured.")
}
status := C.ctt_eth_kzg_verify_blob_kzg_proof_batch_parallel(
ctx.cCtx, tp.ctx,
ctx.threadpool.ctx, ctx.cCtx,
*(**C.ctt_eth_kzg_blob)(unsafe.Pointer(&blobs)),
*(**C.ctt_eth_kzg_commitment)(unsafe.Pointer(&commitments)),
*(**C.ctt_eth_kzg_proof)(unsafe.Pointer(&proofs)),
Expand Down
Loading

0 comments on commit b33479d

Please sign in to comment.