Merge pull request #12 from dgcoffman/dgc/add-ability-to-parse-json-trusted-setup-to-txt

Add ability to parse json trusted setup to txt
This commit is contained in:
Ramana Kumar 2022-11-18 01:33:26 +00:00 committed by GitHub
commit 2745c54711
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 88 additions and 10 deletions

View File

@ -2,3 +2,4 @@ build
dist
*.node
node_modules
testing_trusted_setups.txt

View File

@ -18,3 +18,5 @@ babel.config.js
Dockerfile
binding.dist.gyp
Makefile
testing_trusted_setups.txt
testing_trusted_setups.json

View File

@ -4,7 +4,7 @@ FROM node:16
COPY ./dist/ /app/dist/
COPY test.ts /app
COPY trusted_setup.txt /app
COPY testing_trusted_setups.json /app
COPY kzg.ts /app
COPY kzg.cxx /app
COPY package.json /app

View File

@ -32,7 +32,5 @@ publish: bundle
linux-test: bundle
cp ../../src/trusted_setup.txt .
docker build -t "linux-test" .
rm trusted_setup.txt
docker logs --follow `docker run -d linux-test`

View File

@ -1,5 +1,37 @@
This package wraps the c-kzg C code in C++ NAPI bindings which allow it to be imported into a NodeJS program.
Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/polynomial-commitments.md
# Usage
Install this library with
```sh
yarn add c-kzg
```
Import from it like any other library
```js
import {
KZGCommitment,
blobToKzgCommitment,
verifyAggregateKzgProof,
loadTrustedSetup,
transformTrustedSetupJSON,
} from "c-kzg";
```
Requirements
- The C and C++ code is compiled by node-gyp on installation, so your environment will need a compiler like GCC or clang
# Contributing
This directory contains the code necessary to generate NodeJS bindings for C-KZG.
The bindings file has the following interface:
```js
loadTrustedSetup: (filePath: string) => SetupHandle;
@ -21,7 +53,7 @@ This directory contains the code necessary to generate NodeJS bindings for C-KZG
) => boolean;
```
Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/polynomial-commitments.md
But this library wraps it in module with manages the setupHandle internally.
First,
`npm install -g yarn` if you don't have it.

View File

@ -86,7 +86,7 @@ Napi::Value LoadTrustedSetup(const Napi::CallbackInfo& info) {
if (f == NULL) {
free(kzg_settings);
Napi::Error::New(env, "Error opening trusted setup file").ThrowAsJavaScriptException();
Napi::Error::New(env, "Error opening trusted setup file: " + file_path).ThrowAsJavaScriptException();
return env.Null();
}

View File

@ -3,6 +3,7 @@
* https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/polynomial-commitments.md#kzg
*/
const kzg: KZG = require("./kzg.node");
const fs = require("fs");
export type BLSFieldElement = Uint8Array; // 32 bytes
export type KZGProof = Uint8Array; // 48 bytes
@ -44,6 +45,13 @@ type KZG = {
) => boolean;
};
type TrustedSetupJSON = {
setup_G1: string[];
setup_G2: string[];
setup_G1_lagrange: string[];
roots_of_unity: string[];
};
export const FIELD_ELEMENTS_PER_BLOB = kzg.FIELD_ELEMENTS_PER_BLOB;
export const BYTES_PER_FIELD_ELEMENT = kzg.BYTES_PER_FIELD_ELEMENT;
@ -57,12 +65,38 @@ function requireSetupHandle(): SetupHandle {
return setupHandle;
}
export async function transformTrustedSetupJSON(
filePath: string,
): Promise<string> {
const data: TrustedSetupJSON = JSON.parse(fs.readFileSync(filePath));
const textFilePath = filePath.replace(".json", "") + ".txt";
try {
fs.unlinkSync(textFilePath);
} catch {}
const file = fs.createWriteStream(textFilePath);
file.write(`${FIELD_ELEMENTS_PER_BLOB}\n65\n`);
file.write(data.setup_G1.map((p) => p.replace("0x", "")).join("\n"));
file.write(data.setup_G2.map((p) => p.replace("0x", "")).join("\n"));
file.end();
const p = new Promise((resolve) => {
file.close(resolve);
});
await p;
return textFilePath;
}
export function loadTrustedSetup(filePath: string): void {
if (setupHandle) {
throw new Error(
"Call freeTrustedSetup before loading a new trusted setup.",
);
}
setupHandle = kzg.loadTrustedSetup(filePath);
}

View File

@ -1,6 +1,6 @@
{
"name": "c-kzg",
"version": "1.0.3",
"version": "1.0.5",
"description": "NodeJS bindings for C-KZG",
"author": "Dan Coffman",
"license": "MIT",

View File

@ -9,9 +9,10 @@ import {
verifyAggregateKzgProof,
BYTES_PER_FIELD_ELEMENT,
FIELD_ELEMENTS_PER_BLOB,
transformTrustedSetupJSON,
} from "./kzg";
const setupFileName = "trusted_setup.txt";
const setupFileName = "testing_trusted_setups.json";
const SETUP_FILE_PATH = existsSync(setupFileName)
? setupFileName
@ -22,8 +23,9 @@ const BLOB_BYTE_COUNT = FIELD_ELEMENTS_PER_BLOB * BYTES_PER_FIELD_ELEMENT;
const generateRandomBlob = () => new Uint8Array(randomBytes(BLOB_BYTE_COUNT));
describe("C-KZG", () => {
beforeAll(() => {
loadTrustedSetup(SETUP_FILE_PATH);
beforeAll(async () => {
const file = await transformTrustedSetupJSON(SETUP_FILE_PATH);
loadTrustedSetup(file);
});
afterAll(() => {
@ -38,7 +40,8 @@ describe("C-KZG", () => {
});
it("returns the identity (aka zero, aka neutral) element when blobs is an empty array", () => {
expect(computeAggregateKzgProof([]).toString()).toEqual(
const aggregateProofOfNothing = computeAggregateKzgProof([]);
expect(aggregateProofOfNothing.toString()).toEqual(
[
192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -47,6 +50,13 @@ describe("C-KZG", () => {
);
});
// Just don't call verifyAggregateKzgProof when there are no blobs or commitments
it.skip("verifies the aggregate proof of empty blobs and commitments", () => {
expect(verifyAggregateKzgProof([], [], computeAggregateKzgProof([]))).toBe(
true,
);
});
it("computes the aggregate proof when for a single blob", () => {
let blobs = new Array(1).fill(0).map(generateRandomBlob);
let commitments = blobs.map(blobToKzgCommitment);

File diff suppressed because one or more lines are too long