2022-11-02 20:21:41 +00:00
|
|
|
#include <inttypes.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2022-11-03 22:13:49 +00:00
|
|
|
#include <sstream> // std::ostringstream
|
|
|
|
#include <algorithm> // std::copy
|
|
|
|
#include <iterator> // std::ostream_iterator
|
2022-11-02 20:21:41 +00:00
|
|
|
#include <napi.h>
|
|
|
|
#include "c_kzg_4844.h"
|
|
|
|
#include "blst.h"
|
|
|
|
|
2022-11-17 00:23:06 +00:00
|
|
|
Napi::Value throw_invalid_arguments_count(
|
2022-11-22 20:27:32 +00:00
|
|
|
const unsigned int expected,
|
|
|
|
const unsigned int actual,
|
2022-11-04 02:54:45 +00:00
|
|
|
const Napi::Env env
|
|
|
|
) {
|
2022-11-17 00:23:06 +00:00
|
|
|
Napi::RangeError::New(
|
2022-11-04 02:54:45 +00:00
|
|
|
env,
|
|
|
|
"Wrong number of arguments. Expected: "
|
|
|
|
+ std::to_string(expected)
|
|
|
|
+ ", received " + std::to_string(actual)
|
2022-11-17 00:23:06 +00:00
|
|
|
).ThrowAsJavaScriptException();
|
|
|
|
|
|
|
|
return env.Null();
|
2022-11-04 02:54:45 +00:00
|
|
|
}
|
|
|
|
|
2022-11-17 00:23:06 +00:00
|
|
|
Napi::Value throw_invalid_argument_type(const Napi::Env env, std::string name, std::string expectedType) {
|
|
|
|
Napi::TypeError::New(
|
2022-11-04 02:54:45 +00:00
|
|
|
env,
|
2022-11-16 23:26:05 +00:00
|
|
|
"Invalid argument type: " + name + ". Expected " + expectedType
|
2022-11-17 00:23:06 +00:00
|
|
|
).ThrowAsJavaScriptException();
|
|
|
|
|
|
|
|
return env.Null();
|
2022-11-04 02:54:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Napi::TypedArrayOf<uint8_t> napi_typed_array_from_bytes(uint8_t* array, size_t length, Napi::Env env) {
|
2022-11-03 19:57:46 +00:00
|
|
|
// Create std::vector<uint8_t> out of array.
|
|
|
|
// We allocate it on the heap to allow wrapping it up into ArrayBuffer.
|
2022-11-04 02:54:45 +00:00
|
|
|
std::unique_ptr<std::vector<uint8_t>> vector =
|
|
|
|
std::make_unique<std::vector<uint8_t>>(length, 0);
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
for (size_t i = 0; i < length; ++i) {
|
|
|
|
(*vector)[i] = array[i];
|
2022-11-03 19:57:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Wrap up the std::vector into the ArrayBuffer.
|
2022-11-04 02:54:45 +00:00
|
|
|
Napi::ArrayBuffer buffer = Napi::ArrayBuffer::New(
|
2022-11-03 19:57:46 +00:00
|
|
|
env,
|
2022-11-04 02:54:45 +00:00
|
|
|
vector->data(),
|
|
|
|
length /* size in bytes */,
|
2022-11-03 19:57:46 +00:00
|
|
|
[](Napi::Env /*env*/, void* /*data*/, std::vector<uint8_t>* hint) {
|
|
|
|
std::unique_ptr<std::vector<uint8_t>> vectorPtrToDelete(hint);
|
|
|
|
},
|
2022-11-04 02:54:45 +00:00
|
|
|
vector.get());
|
2022-11-03 19:57:46 +00:00
|
|
|
|
|
|
|
// The finalizer is responsible for deleting the vector: release the
|
|
|
|
// unique_ptr ownership.
|
2022-11-04 02:54:45 +00:00
|
|
|
vector.release();
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
return Napi::Uint8Array::New(env, length, buffer, 0);
|
2022-11-03 19:57:46 +00:00
|
|
|
}
|
|
|
|
|
2022-12-13 19:21:43 +00:00
|
|
|
const uint8_t * extract_byte_array_from_param(const Napi::CallbackInfo& info, const int index, const std::string name) {
|
|
|
|
auto param = info[index].As<Napi::TypedArray>();
|
|
|
|
if (!param.IsTypedArray() || param.TypedArrayType() != napi_uint8_array) {
|
|
|
|
throw_invalid_argument_type(info.Env(), name, "UInt8Array");
|
|
|
|
}
|
|
|
|
return param.As<Napi::Uint8Array>().Data();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-11-03 21:39:02 +00:00
|
|
|
// loadTrustedSetup: (filePath: string) => SetupHandle;
|
2022-11-02 20:21:41 +00:00
|
|
|
Napi::Value LoadTrustedSetup(const Napi::CallbackInfo& info) {
|
2022-11-04 02:54:45 +00:00
|
|
|
auto env = info.Env();
|
2022-11-02 22:50:04 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
size_t argument_count = info.Length();
|
|
|
|
size_t expected_argument_count = 1;
|
|
|
|
if (argument_count != expected_argument_count) {
|
2022-11-17 00:23:06 +00:00
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
2022-11-02 20:21:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!info[0].IsString()) {
|
2022-11-17 00:23:06 +00:00
|
|
|
return throw_invalid_argument_type(env, "filePath", "string");
|
2022-11-02 20:21:41 +00:00
|
|
|
}
|
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
const std::string file_path = info[0].ToString().Utf8Value();
|
2022-11-02 20:21:41 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
KZGSettings* kzg_settings = (KZGSettings*)malloc(sizeof(KZGSettings));
|
2022-11-02 20:21:41 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
if (kzg_settings == NULL) {
|
|
|
|
Napi::Error::New(env, "Error while allocating memory for KZG settings").ThrowAsJavaScriptException();
|
2022-11-02 20:21:41 +00:00
|
|
|
return env.Null();
|
|
|
|
};
|
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
FILE* f = fopen(file_path.c_str(), "r");
|
2022-11-02 20:21:41 +00:00
|
|
|
|
|
|
|
if (f == NULL) {
|
2022-11-04 02:54:45 +00:00
|
|
|
free(kzg_settings);
|
2022-11-17 02:31:30 +00:00
|
|
|
Napi::Error::New(env, "Error opening trusted setup file: " + file_path).ThrowAsJavaScriptException();
|
2022-11-02 20:21:41 +00:00
|
|
|
return env.Null();
|
|
|
|
}
|
|
|
|
|
2022-12-10 16:07:40 +00:00
|
|
|
if (load_trusted_setup_file(kzg_settings, f) != C_KZG_OK) {
|
2022-11-04 02:54:45 +00:00
|
|
|
free(kzg_settings);
|
|
|
|
Napi::Error::New(env, "Error loading trusted setup file").ThrowAsJavaScriptException();
|
2022-11-02 20:21:41 +00:00
|
|
|
return env.Null();
|
|
|
|
}
|
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
return Napi::External<KZGSettings>::New(info.Env(), kzg_settings);
|
2022-11-02 20:21:41 +00:00
|
|
|
}
|
|
|
|
|
2022-11-03 21:39:02 +00:00
|
|
|
// freeTrustedSetup: (setupHandle: SetupHandle) => void;
|
2022-11-04 02:54:45 +00:00
|
|
|
Napi::Value FreeTrustedSetup(const Napi::CallbackInfo& info) {
|
|
|
|
auto env = info.Env();
|
|
|
|
|
|
|
|
size_t argument_count = info.Length();
|
|
|
|
size_t expected_argument_count = 1;
|
|
|
|
if (argument_count != expected_argument_count) {
|
2022-11-17 00:23:06 +00:00
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
2022-11-04 02:54:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto kzg_settings = info[0].As<Napi::External<KZGSettings>>().Data();
|
|
|
|
free_trusted_setup(kzg_settings);
|
|
|
|
free(kzg_settings);
|
|
|
|
return env.Undefined();
|
2022-11-02 20:21:41 +00:00
|
|
|
}
|
2022-11-02 20:27:00 +00:00
|
|
|
|
2022-11-03 21:39:02 +00:00
|
|
|
// blobToKzgCommitment: (blob: Blob, setupHandle: SetupHandle) => KZGCommitment;
|
2022-11-02 20:21:41 +00:00
|
|
|
Napi::Value BlobToKzgCommitment(const Napi::CallbackInfo& info) {
|
2022-11-03 21:39:02 +00:00
|
|
|
auto env = info.Env();
|
2022-11-03 00:17:17 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
size_t argument_count = info.Length();
|
|
|
|
size_t expected_argument_count = 2;
|
|
|
|
if (argument_count != expected_argument_count) {
|
2022-11-17 00:23:06 +00:00
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
2022-11-03 00:17:17 +00:00
|
|
|
}
|
|
|
|
|
2023-01-12 18:10:23 +00:00
|
|
|
Blob *blob = (Blob *)extract_byte_array_from_param(info, 0, "blob");
|
2022-12-13 19:21:43 +00:00
|
|
|
if (env.IsExceptionPending()) {
|
|
|
|
return env.Null();
|
2022-11-03 00:17:17 +00:00
|
|
|
}
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
auto kzg_settings = info[1].As<Napi::External<KZGSettings>>().Data();
|
2022-11-03 00:17:17 +00:00
|
|
|
|
|
|
|
KZGCommitment commitment;
|
2023-01-10 21:52:24 +00:00
|
|
|
C_KZG_RET ret = blob_to_kzg_commitment(&commitment, blob, kzg_settings);
|
|
|
|
if (ret != C_KZG_OK) {
|
|
|
|
Napi::Error::New(env, "Failed to convert blob to commitment")
|
|
|
|
.ThrowAsJavaScriptException();
|
|
|
|
return env.Undefined();
|
|
|
|
};
|
2022-11-03 00:17:17 +00:00
|
|
|
|
2023-01-16 20:05:23 +00:00
|
|
|
return napi_typed_array_from_bytes((uint8_t *)(&commitment), BYTES_PER_COMMITMENT, env);
|
2022-11-03 19:57:46 +00:00
|
|
|
}
|
2022-11-03 00:17:17 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
// computeKzgProof: (blob: Blob, zBytes: Bytes32, setupHandle: SetupHandle) => KZGProof;
|
|
|
|
Napi::Value ComputeKzgProof(const Napi::CallbackInfo& info) {
|
2022-11-03 19:57:46 +00:00
|
|
|
auto env = info.Env();
|
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
size_t argument_count = info.Length();
|
2023-02-18 21:49:52 +00:00
|
|
|
size_t expected_argument_count = 3;
|
2022-11-04 02:54:45 +00:00
|
|
|
if (argument_count != expected_argument_count) {
|
2022-11-17 00:23:06 +00:00
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
2022-11-03 00:17:17 +00:00
|
|
|
}
|
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
auto blob = extract_byte_array_from_param(info, 0, "blob");
|
|
|
|
auto z_bytes = extract_byte_array_from_param(info, 1, "zBytes");
|
|
|
|
auto kzg_settings = info[2].As<Napi::External<KZGSettings>>().Data();
|
2022-11-03 19:57:46 +00:00
|
|
|
|
|
|
|
KZGProof proof;
|
2023-02-18 21:49:52 +00:00
|
|
|
C_KZG_RET ret = compute_kzg_proof(
|
2022-11-03 19:57:46 +00:00
|
|
|
&proof,
|
2023-02-18 21:49:52 +00:00
|
|
|
(Blob *)blob,
|
|
|
|
(Bytes32 *)z_bytes,
|
2022-11-04 02:54:45 +00:00
|
|
|
kzg_settings
|
2022-11-03 19:57:46 +00:00
|
|
|
);
|
|
|
|
|
2023-01-27 15:15:17 +00:00
|
|
|
if (ret != C_KZG_OK) {
|
2023-02-18 21:49:52 +00:00
|
|
|
Napi::Error::New(env, "Failed to compute proof")
|
2023-01-27 15:15:17 +00:00
|
|
|
.ThrowAsJavaScriptException();
|
|
|
|
return env.Undefined();
|
|
|
|
};
|
|
|
|
|
|
|
|
return napi_typed_array_from_bytes((uint8_t *)(&proof), BYTES_PER_PROOF, env);
|
|
|
|
}
|
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
// computeBlobKzgProof: (blob: Blob, setupHandle: SetupHandle) => KZGProof;
|
|
|
|
Napi::Value ComputeBlobKzgProof(const Napi::CallbackInfo& info) {
|
2023-01-27 15:15:17 +00:00
|
|
|
auto env = info.Env();
|
|
|
|
|
|
|
|
size_t argument_count = info.Length();
|
2023-02-18 21:49:52 +00:00
|
|
|
size_t expected_argument_count = 2;
|
2023-01-27 15:15:17 +00:00
|
|
|
if (argument_count != expected_argument_count) {
|
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto blob = extract_byte_array_from_param(info, 0, "blob");
|
2023-02-18 21:49:52 +00:00
|
|
|
auto kzg_settings = info[1].As<Napi::External<KZGSettings>>().Data();
|
2023-01-27 15:15:17 +00:00
|
|
|
|
|
|
|
KZGProof proof;
|
2023-02-18 21:49:52 +00:00
|
|
|
C_KZG_RET ret = compute_blob_kzg_proof(
|
2023-01-27 15:15:17 +00:00
|
|
|
&proof,
|
|
|
|
(Blob *)blob,
|
|
|
|
kzg_settings
|
|
|
|
);
|
|
|
|
|
2022-11-03 21:39:02 +00:00
|
|
|
if (ret != C_KZG_OK) {
|
2023-02-18 21:49:52 +00:00
|
|
|
Napi::Error::New(env, "Error in computeBlobKzgProof")
|
2022-11-03 19:57:46 +00:00
|
|
|
.ThrowAsJavaScriptException();
|
2022-11-03 21:39:02 +00:00
|
|
|
return env.Undefined();
|
|
|
|
};
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2023-01-16 20:05:23 +00:00
|
|
|
return napi_typed_array_from_bytes((uint8_t *)(&proof), BYTES_PER_PROOF, env);
|
2022-11-03 21:39:02 +00:00
|
|
|
}
|
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
// verifyKzgProof: (commitmentBytes: Bytes48, zBytes: Bytes32, yBytes: Bytes32, proofBytes: Bytes48, setupHandle: SetupHandle) => boolean;
|
|
|
|
Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
2022-11-03 21:39:02 +00:00
|
|
|
auto env = info.Env();
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
size_t argument_count = info.Length();
|
2023-02-18 21:49:52 +00:00
|
|
|
size_t expected_argument_count = 5;
|
2022-11-04 02:54:45 +00:00
|
|
|
if (argument_count != expected_argument_count) {
|
2022-11-17 00:23:06 +00:00
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
2022-11-03 21:39:02 +00:00
|
|
|
}
|
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
auto commitment_bytes = extract_byte_array_from_param(info, 0, "commitmentBytes");
|
|
|
|
auto z_bytes = extract_byte_array_from_param(info, 1, "zBytes");
|
|
|
|
auto y_bytes = extract_byte_array_from_param(info, 2, "yBytes");
|
|
|
|
auto proof_bytes = extract_byte_array_from_param(info, 3, "proofBytes");
|
|
|
|
auto kzg_settings = info[4].As<Napi::External<KZGSettings>>().Data();
|
2023-02-01 20:56:03 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
if (env.IsExceptionPending()) {
|
|
|
|
return env.Null();
|
2023-02-01 20:56:03 +00:00
|
|
|
}
|
2022-11-04 18:56:41 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
bool out;
|
|
|
|
C_KZG_RET ret = verify_kzg_proof(
|
|
|
|
&out,
|
|
|
|
(Bytes48 *)commitment_bytes,
|
|
|
|
(Bytes32 *)z_bytes,
|
|
|
|
(Bytes32 *)y_bytes,
|
|
|
|
(Bytes48 *)proof_bytes,
|
|
|
|
kzg_settings
|
|
|
|
);
|
2023-01-13 16:24:25 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
if (ret != C_KZG_OK) {
|
|
|
|
Napi::TypeError::New(env, "Failed to verify KZG proof").ThrowAsJavaScriptException();
|
2023-01-13 16:24:25 +00:00
|
|
|
return env.Null();
|
2023-02-18 21:49:52 +00:00
|
|
|
}
|
2022-11-03 21:39:02 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
return Napi::Boolean::New(env, out);
|
|
|
|
}
|
2022-11-03 21:39:02 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
// verifyBlobKzgProof: (blob: Blob, commitmentBytes: Bytes48, proofBytes: Bytes48, setupHandle: SetupHandle) => boolean;
|
|
|
|
Napi::Value VerifyBlobKzgProof(const Napi::CallbackInfo& info) {
|
|
|
|
auto env = info.Env();
|
2022-11-03 21:39:02 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
size_t argument_count = info.Length();
|
|
|
|
size_t expected_argument_count = 4;
|
|
|
|
if (argument_count != expected_argument_count) {
|
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
2022-11-03 21:39:02 +00:00
|
|
|
}
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
auto blob_bytes = extract_byte_array_from_param(info, 0, "blob");
|
|
|
|
auto commitment_bytes = extract_byte_array_from_param(info, 1, "commitmentBytes");
|
|
|
|
auto proof_bytes = extract_byte_array_from_param(info, 2, "proofBytes");
|
|
|
|
auto kzg_settings = info[3].As<Napi::External<KZGSettings>>().Data();
|
|
|
|
|
|
|
|
if (env.IsExceptionPending()) {
|
|
|
|
return env.Null();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool out;
|
|
|
|
C_KZG_RET ret = verify_blob_kzg_proof(
|
|
|
|
&out,
|
|
|
|
(Blob *)blob_bytes,
|
|
|
|
(Bytes48 *)commitment_bytes,
|
2023-01-26 14:53:30 +00:00
|
|
|
(Bytes48 *)proof_bytes,
|
2022-11-04 02:54:45 +00:00
|
|
|
kzg_settings
|
|
|
|
);
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2022-11-04 21:12:11 +00:00
|
|
|
if (ret != C_KZG_OK) {
|
2023-02-18 21:49:52 +00:00
|
|
|
Napi::TypeError::New(env, "Error in verifyBlobKzgProof").ThrowAsJavaScriptException();
|
2022-11-03 21:39:02 +00:00
|
|
|
return env.Null();
|
|
|
|
}
|
2022-11-03 19:57:46 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
return Napi::Boolean::New(env, out);
|
2022-11-02 20:21:41 +00:00
|
|
|
}
|
2022-11-02 22:50:04 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
// verifyBlobKzgProofBatch: (blobs: Blob[], commitmentsBytes: Bytes48[], proofsBytes: Bytes48[], setupHandle: SetupHandle) => boolean;
|
|
|
|
Napi::Value VerifyBlobKzgProofBatch(const Napi::CallbackInfo& info) {
|
2022-11-03 19:57:46 +00:00
|
|
|
auto env = info.Env();
|
2022-11-02 22:50:04 +00:00
|
|
|
|
2022-11-04 02:54:45 +00:00
|
|
|
size_t argument_count = info.Length();
|
2023-02-18 21:49:52 +00:00
|
|
|
size_t expected_argument_count = 4;
|
2022-11-04 02:54:45 +00:00
|
|
|
if (argument_count != expected_argument_count) {
|
2022-11-17 00:23:06 +00:00
|
|
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
2022-11-02 22:50:04 +00:00
|
|
|
}
|
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
auto blobs_param = info[0].As<Napi::Array>();
|
|
|
|
auto commitments_param = info[1].As<Napi::Array>();
|
|
|
|
auto proofs_param = info[2].As<Napi::Array>();
|
|
|
|
auto kzg_settings = info[3].As<Napi::External<KZGSettings>>().Data();
|
2022-11-02 22:50:04 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
auto blobs_count = blobs_param.Length();
|
|
|
|
auto commitments_count = commitments_param.Length();
|
|
|
|
auto proofs_count = proofs_param.Length();
|
|
|
|
|
|
|
|
if (blobs_count != commitments_count || blobs_count != proofs_count) {
|
|
|
|
Napi::Error::New(env, "verifyBlobKzgProofBatch requires equal number of blobs/commitments/proofs")
|
|
|
|
.ThrowAsJavaScriptException();
|
2022-12-13 19:21:43 +00:00
|
|
|
return env.Null();
|
2022-11-03 19:57:46 +00:00
|
|
|
}
|
2022-11-02 22:50:04 +00:00
|
|
|
|
2023-02-18 21:49:52 +00:00
|
|
|
auto blobs = (Blob*)calloc(blobs_count, sizeof(Blob));
|
|
|
|
if (blobs == NULL) {
|
|
|
|
Napi::Error::New(env, "Error while allocating memory for blobs").ThrowAsJavaScriptException();
|
|
|
|
return env.Null();
|
|
|
|
};
|
|
|
|
|
|
|
|
auto commitments = (Bytes48*)calloc(commitments_count, sizeof(Bytes48));
|
|
|
|
if (commitments == NULL) {
|
|
|
|
free(blobs);
|
|
|
|
Napi::Error::New(env, "Error while allocating memory for commitments").ThrowAsJavaScriptException();
|
|
|
|
return env.Null();
|
|
|
|
};
|
|
|
|
|
|
|
|
auto proofs = (Bytes48*)calloc(proofs_count, sizeof(Bytes48));
|
|
|
|
if (proofs == NULL) {
|
|
|
|
free(blobs);
|
|
|
|
free(commitments);
|
|
|
|
Napi::Error::New(env, "Error while allocating memory for proofs").ThrowAsJavaScriptException();
|
|
|
|
return env.Null();
|
|
|
|
};
|
|
|
|
|
|
|
|
for (uint32_t index = 0; index < blobs_count; index++) {
|
|
|
|
// Extract blob bytes from parameter
|
|
|
|
Napi::Value blob = blobs_param[index];
|
|
|
|
auto blob_bytes = blob.As<Napi::Uint8Array>().Data();
|
|
|
|
memcpy(blobs[index].bytes, blob_bytes, BYTES_PER_BLOB);
|
|
|
|
|
|
|
|
// Extract commitment from parameter
|
|
|
|
Napi::Value commitment = commitments_param[index];
|
|
|
|
auto commitment_bytes = commitment.As<Napi::Uint8Array>().Data();
|
|
|
|
memcpy(&commitments[index], commitment_bytes, BYTES_PER_COMMITMENT);
|
|
|
|
|
|
|
|
// Extract proof from parameter
|
|
|
|
Napi::Value proof = proofs_param[index];
|
|
|
|
auto proof_bytes = proof.As<Napi::Uint8Array>().Data();
|
|
|
|
memcpy(&proofs[index], proof_bytes, BYTES_PER_PROOF);
|
|
|
|
}
|
|
|
|
|
2022-11-03 23:20:33 +00:00
|
|
|
bool out;
|
2023-02-18 21:49:52 +00:00
|
|
|
C_KZG_RET ret = verify_blob_kzg_proof_batch(
|
2023-01-16 20:05:23 +00:00
|
|
|
&out,
|
2023-02-18 21:49:52 +00:00
|
|
|
blobs,
|
|
|
|
commitments,
|
|
|
|
proofs,
|
|
|
|
blobs_count,
|
2023-01-16 20:05:23 +00:00
|
|
|
kzg_settings
|
|
|
|
);
|
|
|
|
|
|
|
|
if (ret != C_KZG_OK) {
|
2023-02-18 21:49:52 +00:00
|
|
|
Napi::TypeError::New(env, "Error in verifyBlobKzgProofBatch").ThrowAsJavaScriptException();
|
2022-11-04 21:12:11 +00:00
|
|
|
return env.Null();
|
2022-11-02 22:50:04 +00:00
|
|
|
}
|
|
|
|
|
2022-11-03 23:54:52 +00:00
|
|
|
return Napi::Boolean::New(env, out);
|
2022-11-02 20:21:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
2022-11-03 23:20:33 +00:00
|
|
|
// Functions
|
2022-11-03 22:13:49 +00:00
|
|
|
exports["loadTrustedSetup"] = Napi::Function::New(env, LoadTrustedSetup);
|
|
|
|
exports["freeTrustedSetup"] = Napi::Function::New(env, FreeTrustedSetup);
|
|
|
|
exports["blobToKzgCommitment"] = Napi::Function::New(env, BlobToKzgCommitment);
|
2023-01-27 15:15:17 +00:00
|
|
|
exports["computeKzgProof"] = Napi::Function::New(env, ComputeKzgProof);
|
2023-02-18 21:49:52 +00:00
|
|
|
exports["computeBlobKzgProof"] = Napi::Function::New(env, ComputeBlobKzgProof);
|
2023-01-27 15:15:17 +00:00
|
|
|
exports["verifyKzgProof"] = Napi::Function::New(env, VerifyKzgProof);
|
2023-02-18 21:49:52 +00:00
|
|
|
exports["verifyBlobKzgProof"] = Napi::Function::New(env, VerifyBlobKzgProof);
|
|
|
|
exports["verifyBlobKzgProofBatch"] = Napi::Function::New(env, VerifyBlobKzgProofBatch);
|
2022-11-03 23:20:33 +00:00
|
|
|
|
|
|
|
// Constants
|
2023-02-14 21:11:10 +00:00
|
|
|
exports["BYTES_PER_BLOB"] = Napi::Number::New(env, BYTES_PER_BLOB);
|
|
|
|
exports["BYTES_PER_COMMITMENT"] = Napi::Number::New(env, BYTES_PER_COMMITMENT);
|
2022-11-04 18:44:57 +00:00
|
|
|
exports["BYTES_PER_FIELD_ELEMENT"] = Napi::Number::New(env, BYTES_PER_FIELD_ELEMENT);
|
2023-02-14 21:11:10 +00:00
|
|
|
exports["BYTES_PER_PROOF"] = Napi::Number::New(env, BYTES_PER_PROOF);
|
|
|
|
exports["FIELD_ELEMENTS_PER_BLOB"] = Napi::Number::New(env, FIELD_ELEMENTS_PER_BLOB);
|
2022-11-03 23:20:33 +00:00
|
|
|
|
2022-11-02 20:21:41 +00:00
|
|
|
return exports;
|
|
|
|
}
|
|
|
|
|
|
|
|
NODE_API_MODULE(addon, Init)
|