Closer to working
This commit is contained in:
parent
a5ca06450f
commit
672346f017
|
@ -37,34 +37,7 @@ Napi::TypedArrayOf<uint8_t> napiTypedArrayFromByteArray(uint8_t* array, size_t a
|
|||
return Napi::Uint8Array::New(env, arrayLength, arrayBuffer, 0);
|
||||
}
|
||||
|
||||
int verifyAggregateKzgProof(const uint8_t blobs[], const uint8_t commitments[], size_t n, const uint8_t proof[48], const KZGSettings *s) {
|
||||
Polynomial* p = (Polynomial*)calloc(n, sizeof(Polynomial));
|
||||
if (p == NULL) return -1;
|
||||
|
||||
KZGCommitment* c = (KZGCommitment*)calloc(n, sizeof(KZGCommitment));
|
||||
if (c == NULL) { free(p); return -1; }
|
||||
|
||||
C_KZG_RET ret;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
for (size_t j = 0; j < FIELD_ELEMENTS_PER_BLOB; j++)
|
||||
bytes_to_bls_field(&p[i][j], &blobs[i * FIELD_ELEMENTS_PER_BLOB * 32 + j * 32]);
|
||||
ret = bytes_to_g1(&c[i], &commitments[i * 48]);
|
||||
if (ret != C_KZG_OK) { free(c); free(p); return -1; }
|
||||
}
|
||||
|
||||
KZGProof f;
|
||||
ret = bytes_to_g1(&f, proof);
|
||||
if (ret != C_KZG_OK) { free(c); free(p); return -1; }
|
||||
|
||||
bool b;
|
||||
ret = verify_aggregate_kzg_proof(&b, p, c, n, &f, s);
|
||||
if (ret != C_KZG_OK) { free(c); free(p); return -1; }
|
||||
|
||||
free(c); free(p);
|
||||
return b ? 0 : 1;
|
||||
}
|
||||
|
||||
// loadTrustedSetup: (filePath: string) => SetupHandle;
|
||||
Napi::Value LoadTrustedSetup(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
|
@ -106,17 +79,17 @@ Napi::Value LoadTrustedSetup(const Napi::CallbackInfo& info) {
|
|||
return Napi::External<KZGSettings>::New(info.Env(), kzgSettings);
|
||||
}
|
||||
|
||||
// Maybe this can be done with a finalizer on the thing returned by LoadTrustedSetup, and then the JS garbage collector can just sort it out.
|
||||
// freeTrustedSetup: (setupHandle: SetupHandle) => void;
|
||||
void FreeTrustedSetup(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
KZGSettings* kzgSettings = info[0].As<Napi::External<KZGSettings>>().Data();
|
||||
// Maybe this can be done with a finalizer on the thing returned by LoadTrustedSetup, and then the JS garbage collector can just sort it out.
|
||||
auto kzgSettings = info[0].As<Napi::External<KZGSettings>>().Data();
|
||||
free_trusted_setup(kzgSettings);
|
||||
free(kzgSettings);
|
||||
}
|
||||
|
||||
// blobToKzgCommitment: (blob: Blob) => KZGCommitment;
|
||||
// blobToKzgCommitment: (blob: Blob, setupHandle: SetupHandle) => KZGCommitment;
|
||||
Napi::Value BlobToKzgCommitment(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
auto env = info.Env();
|
||||
|
||||
if (info.Length() != 2) {
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
|
@ -130,9 +103,9 @@ Napi::Value BlobToKzgCommitment(const Napi::CallbackInfo& info) {
|
|||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
uint8_t* blob = typedArray.As<Napi::Uint8Array>().Data();
|
||||
auto blob = typedArray.As<Napi::Uint8Array>().Data();
|
||||
|
||||
KZGSettings* kzgSettings = info[1].As<Napi::External<KZGSettings>>().Data();
|
||||
auto kzgSettings = info[1].As<Napi::External<KZGSettings>>().Data();
|
||||
|
||||
Polynomial polynomial;
|
||||
for (size_t i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++)
|
||||
|
@ -142,15 +115,12 @@ Napi::Value BlobToKzgCommitment(const Napi::CallbackInfo& info) {
|
|||
blob_to_kzg_commitment(&commitment, polynomial, kzgSettings);
|
||||
|
||||
// Turn it into a byte array
|
||||
uint8_t array[48];
|
||||
bytes_from_g1(array, &commitment);
|
||||
return napiTypedArrayFromByteArray(array, sizeof(array), env);
|
||||
}
|
||||
|
||||
Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
uint8_t commitmentBytes[BYTES_PER_COMMITMENT];
|
||||
bytes_from_g1(commitmentBytes, &commitment);
|
||||
return napiTypedArrayFromByteArray(commitmentBytes, BYTES_PER_COMMITMENT, env);
|
||||
}
|
||||
|
||||
// computeAggregateKzgProof: (blobs: Blob[], setupHandle: SetupHandle) => KZGProof;
|
||||
Napi::Value ComputeAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||
auto env = info.Env();
|
||||
|
||||
|
@ -164,34 +134,16 @@ Napi::Value ComputeAggregateKzgProof(const Napi::CallbackInfo& info) {
|
|||
auto kzgSettings = info[1].As<Napi::External<KZGSettings>>().Data();
|
||||
|
||||
auto numberOfBlobs = blobs_param.Length();
|
||||
// auto blobs = blobs_param.As<Napi::Array<Napi::Uint8Array>>();
|
||||
|
||||
int BYTES_PER_FIELD = 32;
|
||||
int BYTES_PER_BLOB = FIELD_ELEMENTS_PER_BLOB * BYTES_PER_FIELD;
|
||||
|
||||
printf("ComputeAggregateKzgProof called with %i blobs", numberOfBlobs);
|
||||
|
||||
// uint8_t blobBytes[numberOfBlobs * FIELD_ELEMENTS_PER_BLOB];
|
||||
// for(int i = 0; i < numberOfBlobs; i++)
|
||||
// {
|
||||
// Napi::Value blob = blobs_param[i];
|
||||
// if (blob.IsTypedArray())
|
||||
// {
|
||||
// auto blobBytes = blob.As<Napi::Uint8Array>().Data();
|
||||
// memcpy(blobBytes + i * BYTES_PER_BLOB, blobBytes, BYTES_PER_BLOB);
|
||||
// }
|
||||
// }
|
||||
|
||||
// printf("ComputeAggregateKzgProof copied %i bytes", sizeof(blobBytes));
|
||||
printf("ComputeAggregateKzgProof called with %i blob(s)\n", numberOfBlobs);
|
||||
|
||||
auto polynomial = (Polynomial*)calloc(numberOfBlobs, sizeof(Polynomial));
|
||||
// if (p == NULL) return C_KZG_ERROR;
|
||||
|
||||
for (uint32_t blobIndex = 0; blobIndex < numberOfBlobs; blobIndex++) {
|
||||
Napi::Value blob = blobs_param[blobIndex];
|
||||
auto blobBytes = blob.As<Napi::Uint8Array>().Data();
|
||||
|
||||
printf("Iterating blob index: %i", blobIndex);
|
||||
printf("Iterating blob index: %i\n", blobIndex);
|
||||
|
||||
for (uint32_t fieldIndex = 0; fieldIndex < FIELD_ELEMENTS_PER_BLOB; fieldIndex++) {
|
||||
bytes_to_bls_field(
|
||||
|
@ -201,13 +153,6 @@ Napi::Value ComputeAggregateKzgProof(const Napi::CallbackInfo& info) {
|
|||
}
|
||||
}
|
||||
|
||||
printf("ComputeAggregateKzgProof 1");
|
||||
printf("ComputeAggregateKzgProof 1");
|
||||
printf("ComputeAggregateKzgProof 1");
|
||||
printf("ComputeAggregateKzgProof 1");
|
||||
|
||||
// return env.Null();
|
||||
|
||||
KZGProof proof;
|
||||
C_KZG_RET ret = compute_aggregate_kzg_proof(
|
||||
&proof,
|
||||
|
@ -215,33 +160,112 @@ Napi::Value ComputeAggregateKzgProof(const Napi::CallbackInfo& info) {
|
|||
numberOfBlobs,
|
||||
kzgSettings
|
||||
);
|
||||
|
||||
Napi::TypeError::New(env, "STOPPING HERE")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
|
||||
printf("ComputeAggregateKzgProof 2");
|
||||
|
||||
free(polynomial);
|
||||
|
||||
printf("ComputeAggregateKzgProof 3");
|
||||
|
||||
if (ret != C_KZG_OK) {
|
||||
Napi::TypeError::New(env, "Failed to compute proof")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
return env.Undefined();
|
||||
};
|
||||
|
||||
printf("ComputeAggregateKzgProof 4");
|
||||
printf("proof generated: %llu y: %llu z: %llu\n", proof.x, proof.y, proof.z);
|
||||
printf("compute_aggregate_kzg_proof ret was %i\n", ret);
|
||||
|
||||
uint8_t* bytes;
|
||||
bytes_from_g1(bytes, &proof);
|
||||
uint8_t array[48];
|
||||
bytes_from_g1(array, &proof);
|
||||
|
||||
printf("ComputeAggregateKzgProof 5");
|
||||
printf("Turned proof into bytes: [");
|
||||
for (int i = 0; i < sizeof(array); i++) {
|
||||
printf("%x ", array[i]);
|
||||
}
|
||||
printf("]\n");
|
||||
|
||||
return napiTypedArrayFromByteArray(bytes, sizeof(bytes), env);
|
||||
return napiTypedArrayFromByteArray(array, sizeof(array), env);
|
||||
}
|
||||
|
||||
// verifyAggregateKzgProof: (blobs: Blob[], expectedKzgCommitments: KZGCommitment[], kzgAggregatedProof: KZGProof) => boolean;
|
||||
Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||
auto env = info.Env();
|
||||
|
||||
if (info.Length() != 4) {
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
auto blobs_param = info[0].As<Napi::Array>();
|
||||
|
||||
auto comittments_param = info[1].As<Napi::Array>();
|
||||
|
||||
auto proof_param = info[2].As<Napi::TypedArray>();
|
||||
auto proofBytes = proof_param.As<Napi::Uint8Array>().Data();
|
||||
|
||||
auto kzgSettings = info[3].As<Napi::External<KZGSettings>>().Data();
|
||||
|
||||
auto numberOfBlobs = blobs_param.Length();
|
||||
auto polynomial = (Polynomial*)calloc(numberOfBlobs, sizeof(Polynomial));
|
||||
auto commitments = (KZGCommitment*)calloc(numberOfBlobs, sizeof(KZGCommitment));
|
||||
|
||||
C_KZG_RET ret;
|
||||
|
||||
for (uint32_t blobIndex = 0; blobIndex < numberOfBlobs; blobIndex++) {
|
||||
Napi::Value blob = blobs_param[blobIndex];
|
||||
auto blobBytes = blob.As<Napi::Uint8Array>().Data();
|
||||
|
||||
Napi::Value commitment = comittments_param[blobIndex];
|
||||
auto commitmentBytes = commitment.As<Napi::Uint8Array>().Data();
|
||||
|
||||
for (uint32_t fieldIndex = 0; fieldIndex < FIELD_ELEMENTS_PER_BLOB; fieldIndex++) {
|
||||
bytes_to_bls_field(&polynomial[blobIndex][fieldIndex], &blobBytes[fieldIndex * BYTES_PER_FIELD]);
|
||||
}
|
||||
|
||||
ret = bytes_to_g1(&commitments[blobIndex], &commitmentBytes[blobIndex * BYTES_PER_COMMITMENT]);
|
||||
if (ret != C_KZG_OK) {
|
||||
free(commitments);
|
||||
free(polynomial);
|
||||
|
||||
Napi::TypeError::New(env, "Error parsing blobs and commitments")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
}
|
||||
|
||||
KZGProof proof;
|
||||
ret = bytes_to_g1(&proof, proofBytes);
|
||||
if (ret != C_KZG_OK) {
|
||||
free(commitments);
|
||||
free(polynomial);
|
||||
|
||||
Napi::TypeError::New(env, "Error converting proof parameter to KZGProof")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
bool verificationResult;
|
||||
ret = verify_aggregate_kzg_proof(
|
||||
&verificationResult,
|
||||
polynomial,
|
||||
commitments,
|
||||
numberOfBlobs,
|
||||
&proof,
|
||||
kzgSettings
|
||||
);
|
||||
if (ret != C_KZG_OK) {
|
||||
free(commitments);
|
||||
free(polynomial);
|
||||
|
||||
Napi::TypeError::New(env, "Error calling verify_aggregate_kzg_proof")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
free(commitments);
|
||||
free(polynomial);
|
||||
|
||||
return Napi::Boolean::New(env, verificationResult);
|
||||
}
|
||||
|
||||
// verifyKzgProof: (polynomialKzg: KZGCommitment, z: BLSFieldElement, y: BLSFieldElement, kzgProof: KZGProof, setupHandle: SetupHandle) => boolean;
|
||||
Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
||||
auto env = info.Env();
|
||||
|
||||
|
@ -304,19 +328,18 @@ Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
|||
std::copy(c, c+sizeof(c), std::ostream_iterator<int>(ss, ","));
|
||||
Napi::TypeError::New(env, "Failed to parse argument commitment: " + ss.str() + " Return code was: " + std::to_string(ret)).ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
// return -1;
|
||||
};
|
||||
|
||||
if (bytes_to_g1(&proof, p) != C_KZG_OK) {
|
||||
Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
// return -1;
|
||||
}
|
||||
|
||||
if (verify_kzg_proof(&out, &commitment, &fx, &fy, &proof, kzgSettings) != C_KZG_OK) {
|
||||
return env.Null();
|
||||
return Napi::Boolean::New(env, false);
|
||||
}
|
||||
|
||||
return env.Null();
|
||||
return Napi::Boolean::New(env, true);
|
||||
}
|
||||
|
||||
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
||||
|
@ -332,19 +355,3 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|||
}
|
||||
|
||||
NODE_API_MODULE(addon, Init)
|
||||
|
||||
|
||||
// SCRATCH
|
||||
// Napi::Object obj = Napi::Object::New(env);
|
||||
|
||||
// // Assign values to properties
|
||||
// obj.Set("hello", "world");
|
||||
// // obj.Set(uint32_t(42), "The Answer to Life, the Universe, and Everything");
|
||||
// // obj.Set("Douglas Adams", true);
|
||||
// // obj.Set("fftSettings", kzgSettings->fs);
|
||||
// // Napi::Array::Array(napi_env env, napi_value value);
|
||||
|
||||
// const Napi::Array g1Values = Napi::Array::New(env, )
|
||||
|
||||
// obj.Set('g1Values', kzgSettings->g1_values);
|
||||
// obj.Set('g2Values', kzgSettings->g2_values);
|
||||
|
|
|
@ -4,56 +4,104 @@ import bindings from 'bindings';
|
|||
export const BLOB_SIZE = 4096;
|
||||
export const NUMBER_OF_FIELDS = 32;
|
||||
|
||||
// Consider making this internal state of the native code
|
||||
// so we don't have to pass it around in the application layer
|
||||
export type SetupHandle = Object;
|
||||
|
||||
export enum ReturnValue {
|
||||
/** Success! */
|
||||
OK = 0,
|
||||
/** The supplied data is invalid in some way */
|
||||
BADARGS,
|
||||
/** Internal error - this should never occur and may indicate a bug in the library */
|
||||
ERROR,
|
||||
/** Could not allocate memory */
|
||||
MALLOC,
|
||||
}
|
||||
|
||||
export type Point = Uint8Array;
|
||||
export type BLSFieldElement = Uint8Array;
|
||||
export type KZGProof = Uint8Array;
|
||||
export type KZGCommitment = Uint8Array;
|
||||
export type Blob = Uint8Array;
|
||||
export type Blobs = Blob[];
|
||||
|
||||
type KZG = {
|
||||
loadTrustedSetup: (path: string) => SetupHandle;
|
||||
loadTrustedSetup: (filePath: string) => SetupHandle;
|
||||
|
||||
freeTrustedSetup: (setupHandle: SetupHandle) => void;
|
||||
|
||||
blobToKzgCommitment: (blob: Blob, setupHandle: SetupHandle) => KZGCommitment;
|
||||
|
||||
verifyAggregateKzgProof: (blobs: Blobs) => ReturnValue;
|
||||
|
||||
computeAggregateKzgProof: (
|
||||
blobs: Blobs,
|
||||
blobs: Blob[],
|
||||
setupHandle: SetupHandle,
|
||||
) => KZGProof;
|
||||
|
||||
verifyKzgProof: (
|
||||
commitment: KZGCommitment,
|
||||
x: Point,
|
||||
y: Point,
|
||||
proof: KZGProof,
|
||||
verifyAggregateKzgProof: (
|
||||
blobs: Blob[],
|
||||
expectedKzgCommitments: KZGCommitment[],
|
||||
kzgAggregatedProof: KZGProof,
|
||||
setupHandle: SetupHandle,
|
||||
) => ReturnValue;
|
||||
) => boolean;
|
||||
|
||||
verifyKzgProof: (
|
||||
polynomialKzg: KZGCommitment,
|
||||
z: BLSFieldElement,
|
||||
y: BLSFieldElement,
|
||||
kzgProof: KZGProof,
|
||||
setupHandle: SetupHandle,
|
||||
) => boolean;
|
||||
};
|
||||
|
||||
const kzg: KZG = bindings('kzg.node');
|
||||
|
||||
export const loadTrustedSetup = kzg.loadTrustedSetup;
|
||||
export const freeTrustedSetup = kzg.freeTrustedSetup;
|
||||
export const blobToKzgCommitment = kzg.blobToKzgCommitment;
|
||||
export const verifyAggregateKzgProof = kzg.verifyAggregateKzgProof;
|
||||
export const computeAggregateKzgProof = kzg.computeAggregateKzgProof;
|
||||
export const verifyKzgProof = kzg.verifyKzgProof;
|
||||
export default kzg;
|
||||
// Stored as internal state
|
||||
let setupHandle: SetupHandle | undefined;
|
||||
|
||||
export function loadTrustedSetup(filePath: string) {
|
||||
if (setupHandle) {
|
||||
throw new Error(
|
||||
'Call freeTrustedSetup before loading a new trusted setup.',
|
||||
);
|
||||
}
|
||||
setupHandle = kzg.loadTrustedSetup(filePath);
|
||||
}
|
||||
|
||||
export function freeTrustedSetup() {
|
||||
if (!setupHandle) {
|
||||
throw new Error('You must call loadTrustedSetup before freeTrustedSetup.');
|
||||
}
|
||||
kzg.freeTrustedSetup(setupHandle);
|
||||
setupHandle = undefined;
|
||||
}
|
||||
|
||||
export function blobToKzgCommitment(blob: Blob) {
|
||||
if (!setupHandle) {
|
||||
throw new Error('You must call loadTrustedSetup to initialize KZG.');
|
||||
}
|
||||
return kzg.blobToKzgCommitment(blob, setupHandle);
|
||||
}
|
||||
|
||||
export function computeAggregateKzgProof(blobs: Blob[]) {
|
||||
if (!setupHandle) {
|
||||
throw new Error('You must call loadTrustedSetup to initialize KZG.');
|
||||
}
|
||||
return kzg.computeAggregateKzgProof(blobs, setupHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomialKzg``.
|
||||
*/
|
||||
export function verifyKzgProof(
|
||||
polynomialKzg: KZGCommitment,
|
||||
z: BLSFieldElement,
|
||||
y: BLSFieldElement,
|
||||
kzgProof: KZGProof,
|
||||
) {
|
||||
if (!setupHandle) {
|
||||
throw new Error('You must call loadTrustedSetup to initialize KZG.');
|
||||
}
|
||||
return kzg.verifyKzgProof(polynomialKzg, z, y, kzgProof, setupHandle);
|
||||
}
|
||||
|
||||
export function verifyAggregateKzgProof(
|
||||
blobs: Blob[],
|
||||
expectedKzgCommitments: KZGCommitment[],
|
||||
kzgAggregatedProof: KZGProof,
|
||||
) {
|
||||
if (!setupHandle) {
|
||||
throw new Error('You must call loadTrustedSetup to initialize KZG.');
|
||||
}
|
||||
return kzg.verifyAggregateKzgProof(
|
||||
blobs,
|
||||
expectedKzgCommitments,
|
||||
kzgAggregatedProof,
|
||||
setupHandle,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,77 +4,44 @@ import {
|
|||
freeTrustedSetup,
|
||||
verifyKzgProof,
|
||||
blobToKzgCommitment,
|
||||
ReturnValue,
|
||||
SetupHandle,
|
||||
Blob,
|
||||
BLOB_SIZE,
|
||||
NUMBER_OF_FIELDS,
|
||||
computeAggregateKzgProof,
|
||||
verifyAggregateKzgProof,
|
||||
} from './kzg';
|
||||
|
||||
const SETUP_FILE_PATH = '../../src/trusted_setup.txt';
|
||||
|
||||
const COMMITMENT_BYTE_LENGTH = 48;
|
||||
|
||||
function generateRandomBlob(): Blob {
|
||||
return new Uint8Array(randomBytes(NUMBER_OF_FIELDS * BLOB_SIZE));
|
||||
return new Uint8Array(randomBytes(BLOB_SIZE * NUMBER_OF_FIELDS));
|
||||
}
|
||||
|
||||
describe('C-KZG', () => {
|
||||
let sharedSetupHandle: SetupHandle;
|
||||
|
||||
beforeAll(() => {
|
||||
sharedSetupHandle = loadTrustedSetup(SETUP_FILE_PATH);
|
||||
beforeEach(() => {
|
||||
loadTrustedSetup(SETUP_FILE_PATH);
|
||||
});
|
||||
|
||||
describe('setup', () => {
|
||||
it('can both load and free', () => {
|
||||
expect(
|
||||
freeTrustedSetup(loadTrustedSetup(SETUP_FILE_PATH)),
|
||||
).toBeUndefined();
|
||||
});
|
||||
afterEach(() => {
|
||||
freeTrustedSetup();
|
||||
});
|
||||
|
||||
describe('computing a KZG commitment from a blob', () => {
|
||||
it('returns data with the correct length', () => {
|
||||
const blob = generateRandomBlob();
|
||||
const commitment = blobToKzgCommitment(blob, sharedSetupHandle);
|
||||
expect(commitment.length).toBe(COMMITMENT_BYTE_LENGTH);
|
||||
it('computes and verifies an aggregate KZG proof', async () => {
|
||||
const blob1 = generateRandomBlob();
|
||||
const blob2 = generateRandomBlob();
|
||||
const blobs = [blob1, blob2];
|
||||
|
||||
const commitments = blobs.map(blobToKzgCommitment);
|
||||
|
||||
const proof = computeAggregateKzgProof(blobs);
|
||||
|
||||
console.log({
|
||||
commitments,
|
||||
proof,
|
||||
});
|
||||
});
|
||||
|
||||
describe('verifying a KZG proof', () => {
|
||||
it.only('returns the expected value', () => {
|
||||
const byteEncoder = new TextEncoder();
|
||||
const result = verifyAggregateKzgProof(blobs, commitments, proof);
|
||||
|
||||
const blob = generateRandomBlob();
|
||||
const commitment = blobToKzgCommitment(blob, sharedSetupHandle);
|
||||
const proof = computeAggregateKzgProof([blob], sharedSetupHandle);
|
||||
|
||||
const x = byteEncoder.encode(
|
||||
'0345f802a75a6c0d9cc5b8a1e71642b8fa80b0a78938edc6da1e591149578d1a',
|
||||
);
|
||||
const y = byteEncoder.encode(
|
||||
'3b17cab634c3795d311380f3bc93ce8e768efc0e2b9e79496cfc8f351594b472',
|
||||
);
|
||||
|
||||
const result = verifyKzgProof(commitment, y, x, proof, sharedSetupHandle);
|
||||
console.log({ result });
|
||||
expect(result).toBe(ReturnValue.OK);
|
||||
});
|
||||
});
|
||||
|
||||
describe('computing an aggregate KZG proof', () => {
|
||||
it('returns the expected value', () => {
|
||||
const blob = generateRandomBlob();
|
||||
const commitment = blobToKzgCommitment(blob, sharedSetupHandle);
|
||||
const proof = computeAggregateKzgProof([blob], sharedSetupHandle);
|
||||
});
|
||||
});
|
||||
|
||||
describe('verifying an aggregate KZG proof', () => {
|
||||
it('returns the expected value', () => {
|
||||
expect(true).toBe(false);
|
||||
});
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BYTES_PER_COMMITMENT 48
|
||||
#define BYTES_PER_FIELD 32
|
||||
#define FIELD_ELEMENTS_PER_BLOB 4096
|
||||
|
||||
|
|
Loading…
Reference in New Issue