Skip to content

Commit

Permalink
Merge pull request #104 from ChainSafe/mkeil/rebuild-sync-pki
Browse files Browse the repository at this point in the history
feat(rebuild): sync pki with unit tests
  • Loading branch information
matthewkeil committed Jul 31, 2023
2 parents 888bdd5 + 2feef06 commit 768a240
Show file tree
Hide file tree
Showing 31 changed files with 1,716 additions and 9 deletions.
8 changes: 8 additions & 0 deletions rebuild/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
BasedOnStyle: Google
IndentWidth: 4
AlignAfterOpenBracket: AlwaysBreak
AllowAllParametersOfDeclarationOnNextLine: True
AlignEscapedNewlines: Right
BinPackArguments: False
BinPackParameters: False
InsertNewlineAtEOF: True
1 change: 1 addition & 0 deletions rebuild/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.nyc_output
.vscode/settings.json
coverage
build
dist
Expand Down
20 changes: 20 additions & 0 deletions rebuild/.vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
"/Users/matthewkeil/.node-gyp/**"
],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-arm64"
}
],
"version": 4
}
15 changes: 15 additions & 0 deletions rebuild/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "0.0.1",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug Native Addon",
"cwd": "${workspaceRoot}",
"preLaunchTask": "npm: build:debug",
"program": "node",
"args": ["node_modules/.bin/mocha", "test/unit/**/*.test.ts"]
}
]
}

63 changes: 63 additions & 0 deletions rebuild/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
'targets': [
{
'target_name': 'blst_ts_addon',
'sources': [
'deps/blst/src/server.c',
'deps/blst/build/assembly.S',
'src/addon.cc',
'src/secret_key.cc',
'src/public_key.cc',
'src/signature.cc',
# 'src/functions.cc',
],
'include_dirs': [
'deps/blst/bindings',
"<!@(node -p \"require('node-addon-api').include_dir\")",
],
'dependencies': [ "<!(node -p \"require('node-addon-api').gyp\")" ],
'defines': [
'NAPI_CPP_EXCEPTIONS'
],
'cflags': [
'-fexceptions',
'-Werror',
'-Wall',
'-Wextra',
'-Wpedantic',
],
'cflags_cc': [
'-fexceptions',
'-Werror',
'-Wall',
'-Wextra',
'-Wpedantic',
],
'conditions': [
[ 'OS=="win"', {
'sources': [ 'blst/build/win64/*-x86_64.asm' ],
'defines': [ '_HAS_EXCEPTIONS=1' ],
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1,
'EnablePREfast': 'true',
},
},
}
],
[ 'OS=="linux"', {
'ldflags': [ '-Wl,-Bsymbolic' ],
}
],
['OS=="mac"', {
'xcode_settings': {
'OTHER_CFLAGS': ['-fvisibility=hidden'],
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'CLANG_CXX_LIBRARY': 'libc++',
'MACOSX_DEPLOYMENT_TARGET': '12',
}
}]
],
}
]
}
Empty file removed rebuild/lib/.gitkeep
Empty file.
90 changes: 90 additions & 0 deletions rebuild/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Points are represented in two ways in BLST:
* - affine coordinates (x,y)
* - jacobian coordinates (x,y,z)
*
* The jacobian coordinates allow to aggregate points more efficiently,
* so if P1 points are aggregated often (Eth2.0) you want to keep the point
* cached in jacobian coordinates.
*/
export enum CoordType {
affine,
jacobian,
}

export type BlstBuffer = Uint8Array;
export type PublicKeyArg = BlstBuffer | PublicKey;
export type SignatureArg = BlstBuffer | Signature;
export interface SignatureSet {
msg: BlstBuffer;
publicKey: PublicKeyArg;
signature: SignatureArg;
}
export interface Serializable {
serialize(): Uint8Array;
}

/**
* Critical constants for BLST public key infrastructure.
*/
export const BLST_CONSTANTS: {
DST: string;
SECRET_KEY_LENGTH: number;
PUBLIC_KEY_LENGTH_UNCOMPRESSED: number;
PUBLIC_KEY_LENGTH_COMPRESSED: number;
SIGNATURE_LENGTH_UNCOMPRESSED: number;
SIGNATURE_LENGTH_COMPRESSED: number;
};

/*
* Private constructor. Randomly generate ikm when new'ing a key if no
* ikm is provided.
*
* Use static methods `SecretKey.deserialize`, `SecretKey.fromKeygen` or
* `SecretKey.fromKeygenSync` to generate `SecretKey`s from your own material
* (ie serialized key or ikm). See notes on `SecretKey.fromKeygen` for important
* security considerations.
*
* example:
* ```typescript
* const ikm = UintArray8.from(Buffer.from("your very own ikm"));
* const keyInfo = "Some key info";
* const key: SecretKey = SecretKey.fromKeygen(ikm, keyInfo);
*
* key = SecretKey.fromBytes(key.serialize());
* ```
*/
export class SecretKey implements Serializable {
private constructor();
/**
* `fromKeygen` takes two parameters. The first parameter is a salt and is
* required. IKM MUST be at least 32 bytes long, but it MAY be longer. The
* second parameter, info, is optional and may be used to derive multiple
* independent keys from the same IKM. By default, info is the empty string.
*/
static fromKeygen(ikm: BlstBuffer, info?: string): SecretKey;
/**
* Convert a serialized secret key into a SecretKey object.
*/
static deserialize(skBytes: BlstBuffer): SecretKey;
/**
* Serialize a secret key into a Buffer.
*/
serialize(): Buffer;
toPublicKey(): PublicKey;
sign(msg: BlstBuffer): Signature;
}

export class PublicKey implements Serializable {
private constructor();
static deserialize(skBytes: BlstBuffer, coordType?: CoordType): PublicKey;
serialize(compress?: boolean): Buffer;
keyValidate(): void;
}

export class Signature implements Serializable {
private constructor();
static deserialize(skBytes: BlstBuffer, coordType?: CoordType): Signature;
serialize(compress?: boolean): Buffer;
sigValidate(): void;
}
13 changes: 13 additions & 0 deletions rebuild/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-require-imports */
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable @typescript-eslint/no-unsafe-call */
const bindings = require("bindings")("blst_ts_addon");

bindings.CoordType = {
affine: 0,
jacobian: 1,
};

module.exports = exports = bindings;
20 changes: 15 additions & 5 deletions rebuild/package.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
{
"name": "@chainsafe/blst",
"name": "@chainsafe/blst-ts",
"version": "1.0.0",
"description": "Typescript wrapper for supranational/blst native bindings, a highly performant BLS12-381 signature library",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"gypfile": true,
"private": false,
"files": [
"binding.gyp",
"deps",
"lib",
"src"
],
"scripts": {
"preinstall": "mkdir -p deps && cp -r ../blst deps",
"clean": "npm run clean:dist; npm run clean:build",
"clean:dist": "rm -rf dist",
"clean:build": "node-gyp clean && node-gyp configure",
"dev": "ts-node tools/dev",
"build": "node-gyp build",
"build:clean": "npm run clean && npm run build",
"build:debug": "node-gyp build --debug",
"lint": "eslint --color --ext .ts lib/ test/",
"lint:ts": "eslint --color --ext .ts lib/ test/",
"lint:c": "clang-format -i ./src/*",
"lint": "npm run lint:c && npm run lint:ts",
"test": "yarn test:unit",
"test:unit": "mocha test/unit/**/*.test.ts"
"test:unit": "mocha test/unit/**/*.test.ts",
"test:spec": "mocha 'test/spec/**/*.test.ts'",
"download-spec-tests": "node -r ts-node/register test/spec/downloadTests.ts"
},
"repository": {
"type": "git",
Expand All @@ -45,13 +53,15 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.2.1",
"mocha": "^10.2.0",
"node-fetch": "2.6.6",
"prettier": "^2.8.7",
"tar": "^6.1.14",
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
},
"dependencies": {
"bindings": "^1.5.0",
"node-addon-api": "^6.0.0",
"node-addon-api": "^6.1.0",
"node-gyp": "^9.3.1"
}
}
}
Empty file removed rebuild/src/.gitkeep
Empty file.
67 changes: 67 additions & 0 deletions rebuild/src/addon.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "addon.h"

bool is_zero_bytes(
const uint8_t *data, const size_t start_byte, const size_t byte_length) {
for (size_t i = start_byte; i < byte_length; i++) {
if (data[i] != 0) {
return false;
}
}
return true;
}

bool is_valid_length(
std::string &error_out,
size_t byte_length,
size_t length1,
size_t length2) {
if (byte_length == length1 || (length2 != 0 && byte_length == length2)) {
return true;
}
error_out.append(
" is " + std::to_string(byte_length) + " bytes, but must be ");
if (length1 != 0) {
error_out.append(std::to_string(length1));
};
if (length2 != 0) {
if (length1 != 0) {
error_out.append(" or ");
}
error_out.append(std::to_string(length2));
};
error_out.append(" bytes long");
return false;
};

BlstTsAddon::BlstTsAddon(Napi::Env env, Napi::Object exports)
: _dst{"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"},
_blst_error_strings{
"BLST_SUCCESS",
"BLST_BAD_ENCODING",
"BLST_POINT_NOT_ON_CURVE",
"BLST_POINT_NOT_IN_GROUP",
"BLST_AGGR_TYPE_MISMATCH",
"BLST_VERIFY_FAIL",
"BLST_PK_IS_INFINITY",
"BLST_BAD_SCALAR",
} {
Napi::Object js_constants = Napi::Object::New(env);
js_constants.Set(
Napi::String::New(env, "DST"), Napi::String::New(env, _dst));
DefineAddon(
exports,
{
InstanceValue("BLST_CONSTANTS", js_constants, napi_enumerable),
});
SecretKey::Init(env, exports, this);
PublicKey::Init(env, exports, this);
Signature::Init(env, exports, this);
// Functions::Init(env, exports);
env.SetInstanceData(this);
}

std::string BlstTsAddon::GetBlstErrorString(const blst::BLST_ERROR &err) {
return _blst_error_strings[err];
}

NODE_API_ADDON(BlstTsAddon)
Loading

0 comments on commit 768a240

Please sign in to comment.