Checkpoint
This commit is contained in:
parent
dbf2a1d905
commit
fcd7fbd9e7
|
@ -1,7 +1,22 @@
|
|||
install:
|
||||
brew install llvm
|
||||
yarn install
|
||||
|
||||
clean:
|
||||
yarn clean
|
||||
rm -rf build
|
||||
rm -f kzg.node
|
||||
rm -f *.node
|
||||
rm -f *.a
|
||||
rm -f *.o
|
||||
|
||||
# objcopy --globalize-symbol=symbolname
|
||||
# Give symbol symbolname global scoping so that it is visible
|
||||
# outside of the file in which it is defined. This option may
|
||||
# be given more than once.
|
||||
# c_kzg_4844's static void hash() calls sha256_... which are private
|
||||
# We use objcopy's globalize-symbol to make them public.
|
||||
# libblst.a: ../../lib/libblst.a
|
||||
# $$(brew --prefix llvm)/bin/llvm-objcopy --globalize-symbol=sha256_init --globalize-symbol=sha256_update --globalize-symbol=sha256_final $< $@
|
||||
|
||||
build: kzg.cxx Makefile
|
||||
cd ../../src; make lib
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
'include_dirs': ['../../inc', '../../src', "<!@(node -p \"require('node-addon-api').include\")"],
|
||||
'libraries': [
|
||||
'/Users/coffman@coinbase.com/src/c-kzg/bindings/node.js/c_kzg_4844.o',
|
||||
'/Users/coffman@coinbase.com/src/c-kzg/bindings/node.js/sha256.o',
|
||||
'/Users/coffman@coinbase.com/src/c-kzg/lib/libblst.a'
|
||||
],
|
||||
'dependencies': [
|
||||
|
|
|
@ -10,6 +10,33 @@
|
|||
#include <algorithm> // std::copy
|
||||
#include <iterator> // std::ostream_iterator
|
||||
|
||||
Napi::TypedArrayOf<uint8_t> napiTypedArrayFromByteArray(uint8_t* array, size_t arrayLength, Napi::Env env) {
|
||||
// Create std::vector<uint8_t> out of array.
|
||||
// We allocate it on the heap to allow wrapping it up into ArrayBuffer.
|
||||
std::unique_ptr<std::vector<uint8_t>> nativeArray =
|
||||
std::make_unique<std::vector<uint8_t>>(arrayLength, 0);
|
||||
|
||||
for (size_t i = 0; i < arrayLength; ++i) {
|
||||
(*nativeArray)[i] = array[i];
|
||||
}
|
||||
|
||||
// Wrap up the std::vector into the ArrayBuffer.
|
||||
Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(
|
||||
env,
|
||||
nativeArray->data(),
|
||||
arrayLength /* size in bytes */,
|
||||
[](Napi::Env /*env*/, void* /*data*/, std::vector<uint8_t>* hint) {
|
||||
std::unique_ptr<std::vector<uint8_t>> vectorPtrToDelete(hint);
|
||||
},
|
||||
nativeArray.get());
|
||||
|
||||
// The finalizer is responsible for deleting the vector: release the
|
||||
// unique_ptr ownership.
|
||||
nativeArray.release();
|
||||
|
||||
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;
|
||||
|
@ -38,24 +65,6 @@ int verifyAggregateKzgProof(const uint8_t blobs[], const uint8_t commitments[],
|
|||
return b ? 0 : 1;
|
||||
}
|
||||
|
||||
C_KZG_RET computeAggregateKzgProof(uint8_t out[48], const uint8_t blobs[], size_t n, const KZGSettings *s) {
|
||||
Polynomial* p = (Polynomial*)calloc(n, sizeof(Polynomial));
|
||||
if (p == NULL) return C_KZG_ERROR;
|
||||
|
||||
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]);
|
||||
|
||||
KZGProof f;
|
||||
C_KZG_RET ret = compute_aggregate_kzg_proof(&f, p, n, s);
|
||||
|
||||
free(p);
|
||||
if (ret != C_KZG_OK) return ret;
|
||||
|
||||
bytes_from_g1(out, &f);
|
||||
return C_KZG_OK;
|
||||
}
|
||||
|
||||
Napi::Value LoadTrustedSetup(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
|
@ -105,9 +114,6 @@ void FreeTrustedSetup(const Napi::CallbackInfo& info) {
|
|||
free(kzgSettings);
|
||||
}
|
||||
|
||||
// https://github.com/nodejs/node-addon-examples/blob/35c714f95b0674a7415ca7c166e9e981f5a77cf9/typed_array_to_native/node-addon-api/typed_array_to_native.cc
|
||||
|
||||
|
||||
// blobToKzgCommitment: (blob: Blob) => KZGCommitment;
|
||||
Napi::Value BlobToKzgCommitment(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
@ -119,14 +125,13 @@ Napi::Value BlobToKzgCommitment(const Napi::CallbackInfo& info) {
|
|||
}
|
||||
|
||||
Napi::TypedArray typedArray = info[0].As<Napi::TypedArray>();
|
||||
|
||||
if (typedArray.TypedArrayType() != napi_uint8_array) {
|
||||
Napi::Error::New(info.Env(), "Expected an Uint8Array")
|
||||
Napi::Error::New(env, "Expected an Uint8Array")
|
||||
.ThrowAsJavaScriptException();
|
||||
return info.Env().Undefined();
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
uint8_t* blob = typedArray.As<Napi::Uint8Array>().Data();
|
||||
|
||||
KZGSettings* kzgSettings = info[1].As<Napi::External<KZGSettings>>().Data();
|
||||
|
||||
Polynomial polynomial;
|
||||
|
@ -139,32 +144,7 @@ Napi::Value BlobToKzgCommitment(const Napi::CallbackInfo& info) {
|
|||
// Turn it into a byte array
|
||||
uint8_t array[48];
|
||||
bytes_from_g1(array, &commitment);
|
||||
size_t arrayLength = sizeof(array);
|
||||
|
||||
// Create std::vector<uint8_t> out of array.
|
||||
// We allocate it on the heap to allow wrapping it up into ArrayBuffer.
|
||||
std::unique_ptr<std::vector<uint8_t>> nativeArray =
|
||||
std::make_unique<std::vector<uint8_t>>(arrayLength, 0);
|
||||
|
||||
for (size_t i = 0; i < arrayLength; ++i) {
|
||||
(*nativeArray)[i] = array[i];
|
||||
}
|
||||
|
||||
// Wrap up the std::vector into the ArrayBuffer.
|
||||
Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(
|
||||
info.Env(),
|
||||
nativeArray->data(),
|
||||
arrayLength /* size in bytes */,
|
||||
[](Napi::Env /*env*/, void* /*data*/, std::vector<uint8_t>* hint) {
|
||||
std::unique_ptr<std::vector<uint8_t>> vectorPtrToDelete(hint);
|
||||
},
|
||||
nativeArray.get());
|
||||
|
||||
// The finalizer is responsible for deleting the vector: release the
|
||||
// unique_ptr ownership.
|
||||
nativeArray.release();
|
||||
|
||||
return Napi::Uint8Array::New(info.Env(), arrayLength, arrayBuffer, 0);
|
||||
return napiTypedArrayFromByteArray(array, sizeof(array), env);
|
||||
}
|
||||
|
||||
Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||
|
@ -172,11 +152,98 @@ Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
|||
}
|
||||
|
||||
Napi::Value ComputeAggregateKzgProof(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")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
auto blobs_param = info[0].As<Napi::Array>();
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
for (uint32_t fieldIndex = 0; fieldIndex < FIELD_ELEMENTS_PER_BLOB; fieldIndex++) {
|
||||
bytes_to_bls_field(
|
||||
&polynomial[blobIndex][fieldIndex],
|
||||
&blobBytes[fieldIndex * BYTES_PER_FIELD]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
polynomial,
|
||||
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();
|
||||
};
|
||||
|
||||
printf("ComputeAggregateKzgProof 4");
|
||||
|
||||
uint8_t* bytes;
|
||||
bytes_from_g1(bytes, &proof);
|
||||
|
||||
printf("ComputeAggregateKzgProof 5");
|
||||
|
||||
return napiTypedArrayFromByteArray(bytes, sizeof(bytes), env);
|
||||
}
|
||||
|
||||
Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
auto env = info.Env();
|
||||
|
||||
if (info.Length() != 5) {
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
|
@ -185,19 +252,43 @@ Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
|||
}
|
||||
|
||||
// const uint8_t c[48]
|
||||
uint8_t* c = reinterpret_cast<uint8_t*>(info[0].As<Napi::Int8Array>().Data());
|
||||
auto c_param = info[0].As<Napi::TypedArray>();
|
||||
if (c_param.TypedArrayType() != napi_uint8_array) {
|
||||
Napi::Error::New(env, "Expected an Uint8Array")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
auto c = c_param.As<Napi::Uint8Array>().Data();
|
||||
|
||||
// const uint8_t x[32]
|
||||
uint8_t* x = reinterpret_cast<uint8_t*>(info[1].As<Napi::Int8Array>().Data());
|
||||
auto x_param = info[0].As<Napi::TypedArray>();
|
||||
if (x_param.TypedArrayType() != napi_uint8_array) {
|
||||
Napi::Error::New(env, "Expected an Uint8Array")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
auto x = x_param.As<Napi::Uint8Array>().Data();
|
||||
|
||||
// const uint8_t y[32]
|
||||
uint8_t* y = reinterpret_cast<uint8_t*>(info[2].As<Napi::Int8Array>().Data());
|
||||
auto y_param = info[0].As<Napi::TypedArray>();
|
||||
if (y_param.TypedArrayType() != napi_uint8_array) {
|
||||
Napi::Error::New(env, "Expected an Uint8Array")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
auto y = y_param.As<Napi::Uint8Array>().Data();
|
||||
|
||||
// const uint8_t p[48]
|
||||
uint8_t* p = reinterpret_cast<uint8_t*>(info[3].As<Napi::Int8Array>().Data());
|
||||
auto p_param = info[0].As<Napi::TypedArray>();
|
||||
if (p_param.TypedArrayType() != napi_uint8_array) {
|
||||
Napi::Error::New(info.Env(), "Expected an Uint8Array")
|
||||
.ThrowAsJavaScriptException();
|
||||
return info.Env().Undefined();
|
||||
}
|
||||
auto p = p_param.As<Napi::Uint8Array>().Data();
|
||||
|
||||
// KZGSettings *s
|
||||
KZGSettings* kzgSettings = info[4].As<Napi::External<KZGSettings>>().Data();
|
||||
auto kzgSettings = info[4].As<Napi::External<KZGSettings>>().Data();
|
||||
|
||||
KZGCommitment commitment;
|
||||
KZGProof proof;
|
||||
|
@ -207,11 +298,10 @@ Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
|||
bytes_to_bls_field(&fx, x);
|
||||
bytes_to_bls_field(&fy, y);
|
||||
|
||||
C_KZG_RET ret = bytes_to_g1(&commitment, c);
|
||||
auto ret = bytes_to_g1(&commitment, c);
|
||||
if (ret != C_KZG_OK) {
|
||||
std::ostringstream ss;
|
||||
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;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// @ts-expect-error
|
||||
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;
|
||||
|
@ -16,9 +19,6 @@ export enum ReturnValue {
|
|||
MALLOC,
|
||||
}
|
||||
|
||||
export const BLOB_SIZE = 4096;
|
||||
export const NUMBER_OF_FIELDS = 32;
|
||||
|
||||
export type Point = Uint8Array;
|
||||
export type KZGProof = Uint8Array;
|
||||
export type KZGCommitment = Uint8Array;
|
||||
|
@ -27,14 +27,18 @@ export type Blobs = Blob[];
|
|||
|
||||
type KZG = {
|
||||
loadTrustedSetup: (path: string) => SetupHandle;
|
||||
|
||||
freeTrustedSetup: (setupHandle: SetupHandle) => void;
|
||||
|
||||
blobToKzgCommitment: (blob: Blob, setupHandle: SetupHandle) => KZGCommitment;
|
||||
|
||||
verifyAggregateKzgProof: (blobs: Blobs) => ReturnValue;
|
||||
|
||||
computeAggregateKzgProof: (
|
||||
blobs: Blobs,
|
||||
size: number,
|
||||
setupHandle: SetupHandle,
|
||||
) => KZGProof;
|
||||
|
||||
verifyKzgProof: (
|
||||
commitment: KZGCommitment,
|
||||
x: Point,
|
||||
|
@ -52,5 +56,4 @@ export const blobToKzgCommitment = kzg.blobToKzgCommitment;
|
|||
export const verifyAggregateKzgProof = kzg.verifyAggregateKzgProof;
|
||||
export const computeAggregateKzgProof = kzg.computeAggregateKzgProof;
|
||||
export const verifyKzgProof = kzg.verifyKzgProof;
|
||||
|
||||
export default kzg;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { randomBytes } from 'crypto';
|
||||
import {
|
||||
loadTrustedSetup,
|
||||
freeTrustedSetup,
|
||||
|
@ -8,54 +9,56 @@ import {
|
|||
Blob,
|
||||
BLOB_SIZE,
|
||||
NUMBER_OF_FIELDS,
|
||||
computeAggregateKzgProof,
|
||||
} from './kzg';
|
||||
|
||||
import { randomBytes } from 'crypto';
|
||||
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));
|
||||
}
|
||||
|
||||
describe('C-KZG', () => {
|
||||
let setupHandle: SetupHandle;
|
||||
let sharedSetupHandle: SetupHandle;
|
||||
|
||||
beforeAll(() => {
|
||||
setupHandle = loadTrustedSetup('../../src/trusted_setup.txt');
|
||||
sharedSetupHandle = loadTrustedSetup(SETUP_FILE_PATH);
|
||||
});
|
||||
|
||||
describe('setup', () => {
|
||||
it('can both load and free', () => {
|
||||
expect(freeTrustedSetup(setupHandle)).toBeUndefined();
|
||||
expect(
|
||||
freeTrustedSetup(loadTrustedSetup(SETUP_FILE_PATH)),
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('computing a KZG commitment from a blob', () => {
|
||||
it.only('returns data with the correct length', () => {
|
||||
it('returns data with the correct length', () => {
|
||||
const blob = generateRandomBlob();
|
||||
const commitment = blobToKzgCommitment(blob, setupHandle);
|
||||
expect(commitment.length).toBe(48);
|
||||
const commitment = blobToKzgCommitment(blob, sharedSetupHandle);
|
||||
expect(commitment.length).toBe(COMMITMENT_BYTE_LENGTH);
|
||||
});
|
||||
});
|
||||
|
||||
describe('verifying a KZG proof', () => {
|
||||
it.skip('returns the expected value', () => {
|
||||
it.only('returns the expected value', () => {
|
||||
const byteEncoder = new TextEncoder();
|
||||
|
||||
const commitment = byteEncoder.encode(
|
||||
'b91c022acf7bd3b63be69a4c19b781ea7a3d5df1cd66ceb7dd0f399610f0ee04695dace82e04bfb83af2b17d7319f87f',
|
||||
);
|
||||
console.log({ commitment });
|
||||
const blob = generateRandomBlob();
|
||||
const commitment = blobToKzgCommitment(blob, sharedSetupHandle);
|
||||
const proof = computeAggregateKzgProof([blob], sharedSetupHandle);
|
||||
|
||||
const x = byteEncoder.encode(
|
||||
'0345f802a75a6c0d9cc5b8a1e71642b8fa80b0a78938edc6da1e591149578d1a',
|
||||
);
|
||||
const y = byteEncoder.encode(
|
||||
'3b17cab634c3795d311380f3bc93ce8e768efc0e2b9e79496cfc8f351594b472',
|
||||
);
|
||||
const proof = byteEncoder.encode(
|
||||
'a5ddd6da04c47a9cd4628beb8d55ebd2e930a64dfa29f876ebf393cfd6574d48a3ce96ac5a2af4a4f9ec9caa47d304d3',
|
||||
);
|
||||
|
||||
const result = verifyKzgProof(commitment, y, x, proof, setupHandle);
|
||||
const result = verifyKzgProof(commitment, y, x, proof, sharedSetupHandle);
|
||||
console.log({ result });
|
||||
expect(result).toBe(ReturnValue.OK);
|
||||
});
|
||||
|
@ -63,7 +66,9 @@ describe('C-KZG', () => {
|
|||
|
||||
describe('computing an aggregate KZG proof', () => {
|
||||
it('returns the expected value', () => {
|
||||
expect(true).toBe(false);
|
||||
const blob = generateRandomBlob();
|
||||
const commitment = blobToKzgCommitment(blob, sharedSetupHandle);
|
||||
const proof = computeAggregateKzgProof([blob], sharedSetupHandle);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,103 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
"target": "esnext",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ INCLUDE_DIRS = ../inc
|
|||
CFLAGS += -O2
|
||||
|
||||
c_kzg_4844.o: c_kzg_4844.c Makefile
|
||||
clang -Wall -I$(INCLUDE_DIRS) $(CFLAGS) -c $<
|
||||
clang -Wall -I$(INCLUDE_DIRS) $(CFLAGS) -c c_kzg_4844.c sha256.c
|
||||
|
||||
lib: c_kzg_4844.c Makefile
|
||||
clang -Wall -I$(INCLUDE_DIRS) $(CFLAGS) -c c_kzg_4844.c
|
||||
mv c_kzg_4844.o ../bindings/node.js
|
||||
lib: c_kzg_4844.o Makefile
|
||||
mv *.o ../bindings/node.js
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sha256.h"
|
||||
|
||||
/**
|
||||
* Wrapped `malloc()` that reports failures to allocate.
|
||||
|
@ -1041,44 +1042,34 @@ static C_KZG_RET compute_kzg_proof(KZGProof *out, const Polynomial p, const BLSF
|
|||
return C_KZG_OK;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
unsigned int h[8];
|
||||
unsigned long long N;
|
||||
unsigned char buf[64];
|
||||
size_t off;
|
||||
} SHA256_CTX;
|
||||
|
||||
void sha256_init(SHA256_CTX *ctx);
|
||||
void sha256_update(SHA256_CTX *ctx, const void *_inp, size_t len);
|
||||
void sha256_final(unsigned char md[32], SHA256_CTX *ctx);
|
||||
|
||||
static void hash(uint8_t md[32], uint8_t input[], size_t n) {
|
||||
SHA256_CTX ctx;
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, input, n);
|
||||
sha256_final(md, &ctx);
|
||||
sha256_final(&ctx, md);
|
||||
}
|
||||
|
||||
static C_KZG_RET hash_to_bytes(uint8_t out[32],
|
||||
const uint8_t *initializer, const Polynomial polys[], const KZGCommitment comms[], size_t n) {
|
||||
printf("hash_to_bytes 1\n");
|
||||
size_t i; uint64_t j;
|
||||
size_t ni = initializer == NULL ? 0 : 32;
|
||||
size_t np = ni + n * FIELD_ELEMENTS_PER_BLOB * 32;
|
||||
|
||||
printf("hash_to_bytes 2\n");
|
||||
uint8_t* bytes = calloc(np + n * 48, sizeof(uint8_t));
|
||||
if (bytes == NULL) return C_KZG_MALLOC;
|
||||
|
||||
if (ni) memcpy(bytes, initializer, ni);
|
||||
|
||||
printf("hash_to_bytes 3\n");
|
||||
for (i = 0; i < n; i++)
|
||||
for (j = 0; j < FIELD_ELEMENTS_PER_BLOB; j++)
|
||||
bytes_from_bls_field(&bytes[ni + i * 32], &polys[i][j]);
|
||||
|
||||
printf("hash_to_bytes 5\n");
|
||||
for (i = 0; i < n; i++)
|
||||
bytes_from_g1(&bytes[np + i * 48], &comms[i]);
|
||||
|
||||
printf("hash_to_bytes 6\n");
|
||||
hash(out, bytes, np + n * 48);
|
||||
|
||||
printf("hash_to_bytes 7\n");
|
||||
free(bytes);
|
||||
return C_KZG_OK;
|
||||
}
|
||||
|
@ -1087,18 +1078,20 @@ static C_KZG_RET compute_aggregated_poly_and_commitment(Polynomial poly_out, KZG
|
|||
const Polynomial blobs[],
|
||||
const KZGCommitment kzg_commitments[],
|
||||
size_t n) {
|
||||
printf("compute_aggregated_poly_and_commitment 1\n");
|
||||
BLSFieldElement* r_powers = calloc(n, sizeof(BLSFieldElement));
|
||||
if (r_powers == NULL) return C_KZG_MALLOC;
|
||||
|
||||
printf("compute_aggregated_poly_and_commitment 2\n");
|
||||
C_KZG_RET ret;
|
||||
ret = hash_to_bytes(hash_out, NULL, blobs, kzg_commitments, n);
|
||||
if (ret != C_KZG_OK) { free(r_powers); return ret; }
|
||||
printf("compute_aggregated_poly_and_commitment 3\n");
|
||||
bytes_to_bls_field(&r_powers[1], hash_out);
|
||||
|
||||
printf("compute_aggregated_poly_and_commitment 4\n");
|
||||
compute_powers(r_powers, n);
|
||||
|
||||
printf("compute_aggregated_poly_and_commitment 5\n");
|
||||
vector_lincomb(poly_out, blobs, r_powers, n);
|
||||
|
||||
printf("compute_aggregated_poly_and_commitment 6\n");
|
||||
g1_lincomb(comm_out, kzg_commitments, r_powers, n);
|
||||
|
||||
free(r_powers);
|
||||
|
@ -1109,24 +1102,37 @@ C_KZG_RET compute_aggregate_kzg_proof(KZGProof *out,
|
|||
const Polynomial blobs[],
|
||||
size_t n,
|
||||
const KZGSettings *s) {
|
||||
printf("RUNNING compute_aggregate_kzg_proof 1");
|
||||
|
||||
KZGCommitment* commitments = calloc(n, sizeof(KZGCommitment));
|
||||
if (commitments == NULL) return C_KZG_MALLOC;
|
||||
|
||||
printf("RUNNING compute_aggregate_kzg_proof 2");
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
blob_to_kzg_commitment(&commitments[i], blobs[i], s);
|
||||
|
||||
printf("RUNNING compute_aggregate_kzg_proof 3");
|
||||
|
||||
Polynomial aggregated_poly;
|
||||
KZGCommitment aggregated_poly_commitment;
|
||||
C_KZG_RET ret;
|
||||
uint8_t hash[32];
|
||||
ret = compute_aggregated_poly_and_commitment(aggregated_poly, &aggregated_poly_commitment, hash, blobs, commitments, n);
|
||||
free(commitments);
|
||||
|
||||
printf("RUNNING compute_aggregate_kzg_proof 4");
|
||||
|
||||
if (ret != C_KZG_OK) return ret;
|
||||
|
||||
TRY(hash_to_bytes(hash, hash, &aggregated_poly, &aggregated_poly_commitment, 1));
|
||||
printf("RUNNING compute_aggregate_kzg_proof 5");
|
||||
|
||||
BLSFieldElement x;
|
||||
bytes_to_bls_field(&x, hash);
|
||||
|
||||
printf("RUNNING compute_aggregate_kzg_proof 6");
|
||||
|
||||
return compute_kzg_proof(out, aggregated_poly, &x, s);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
// https://github.com/B-Con/crypto-algorithms/blob/master/sha256.c
|
||||
/*********************************************************************
|
||||
* Filename: sha256.c
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Implementation of the SHA-256 hashing algorithm.
|
||||
SHA-256 is one of the three algorithms in the SHA2
|
||||
specification. The others, SHA-384 and SHA-512, are not
|
||||
offered in this implementation.
|
||||
Algorithm specification can be found here:
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
|
||||
This implementation uses little endian byte order.
|
||||
*********************************************************************/
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include "sha256.h"
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
|
||||
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
|
||||
|
||||
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
|
||||
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
|
||||
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
|
||||
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
|
||||
|
||||
/**************************** VARIABLES *****************************/
|
||||
static const WORD k[64] = {
|
||||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
|
||||
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
|
||||
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
||||
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
|
||||
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
|
||||
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
||||
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
|
||||
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||
};
|
||||
|
||||
/*********************** FUNCTION DEFINITIONS ***********************/
|
||||
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
|
||||
{
|
||||
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
|
||||
|
||||
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
||||
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
|
||||
for ( ; i < 64; ++i)
|
||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||
|
||||
a = ctx->state[0];
|
||||
b = ctx->state[1];
|
||||
c = ctx->state[2];
|
||||
d = ctx->state[3];
|
||||
e = ctx->state[4];
|
||||
f = ctx->state[5];
|
||||
g = ctx->state[6];
|
||||
h = ctx->state[7];
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
|
||||
t2 = EP0(a) + MAJ(a,b,c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
|
||||
ctx->state[0] += a;
|
||||
ctx->state[1] += b;
|
||||
ctx->state[2] += c;
|
||||
ctx->state[3] += d;
|
||||
ctx->state[4] += e;
|
||||
ctx->state[5] += f;
|
||||
ctx->state[6] += g;
|
||||
ctx->state[7] += h;
|
||||
}
|
||||
|
||||
void sha256_init(SHA256_CTX *ctx)
|
||||
{
|
||||
ctx->datalen = 0;
|
||||
ctx->bitlen = 0;
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
ctx->data[ctx->datalen] = data[i];
|
||||
ctx->datalen++;
|
||||
if (ctx->datalen == 64) {
|
||||
sha256_transform(ctx, ctx->data);
|
||||
ctx->bitlen += 512;
|
||||
ctx->datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
|
||||
{
|
||||
WORD i;
|
||||
|
||||
i = ctx->datalen;
|
||||
|
||||
// Pad whatever data is left in the buffer.
|
||||
if (ctx->datalen < 56) {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 56)
|
||||
ctx->data[i++] = 0x00;
|
||||
}
|
||||
else {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 64)
|
||||
ctx->data[i++] = 0x00;
|
||||
sha256_transform(ctx, ctx->data);
|
||||
memset(ctx->data, 0, 56);
|
||||
}
|
||||
|
||||
// Append to the padding the total message's length in bits and transform.
|
||||
ctx->bitlen += ctx->datalen * 8;
|
||||
ctx->data[63] = ctx->bitlen;
|
||||
ctx->data[62] = ctx->bitlen >> 8;
|
||||
ctx->data[61] = ctx->bitlen >> 16;
|
||||
ctx->data[60] = ctx->bitlen >> 24;
|
||||
ctx->data[59] = ctx->bitlen >> 32;
|
||||
ctx->data[58] = ctx->bitlen >> 40;
|
||||
ctx->data[57] = ctx->bitlen >> 48;
|
||||
ctx->data[56] = ctx->bitlen >> 56;
|
||||
sha256_transform(ctx, ctx->data);
|
||||
|
||||
// Since this implementation uses little endian byte ordering and SHA uses big endian,
|
||||
// reverse all the bytes when copying the final state to the output hash.
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*********************************************************************
|
||||
* Filename: sha256.h
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Defines the API for the corresponding SHA1 implementation.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef SHA256_H
|
||||
#define SHA256_H
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stddef.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
|
||||
|
||||
/**************************** DATA TYPES ****************************/
|
||||
typedef unsigned char BYTE; // 8-bit byte
|
||||
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
|
||||
typedef struct {
|
||||
BYTE data[64];
|
||||
WORD datalen;
|
||||
unsigned long long bitlen;
|
||||
WORD state[8];
|
||||
} SHA256_CTX;
|
||||
|
||||
/*********************** FUNCTION DECLARATIONS **********************/
|
||||
void sha256_init(SHA256_CTX *ctx);
|
||||
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
|
||||
void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
|
||||
|
||||
#endif // SHA256_H
|
Loading…
Reference in New Issue