Use Bytes48 for commitments/proofs (#86)
* Start to use bytes48 type * Update java bindings * Update variable names * Update csharp bindings * Update node.js bindings * Update python bindings * Fix mistake in python bindings * Add new functions * Fix nit in java bindings * Update variable names in java bindings * Compare to point at infinity * Update bytes_to_bls_field doc * Add todo * Do key validation * Remove bytes_to_g1 * Fix bug & add remark * Fix memcmp mistake * Fix nit in nodejs bindings * Fix another nit * Update nodejs parameter names * Remove to_proof() and to_commitment() * Fix bug
This commit is contained in:
parent
0a18868475
commit
03b90ef63f
|
@ -53,7 +53,7 @@ public class Ckzg
|
||||||
/// <param name="ts">Trusted setup settings</param>
|
/// <param name="ts">Trusted setup settings</param>
|
||||||
/// <returns>Returns error code or <c>0</c> if the proof is correct</returns>
|
/// <returns>Returns error code or <c>0</c> if the proof is correct</returns>
|
||||||
[DllImport("ckzg", EntryPoint = "verify_aggregate_kzg_proof_wrap", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("ckzg", EntryPoint = "verify_aggregate_kzg_proof_wrap", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public unsafe static extern int VerifyAggregatedKzgProof(byte* blobs, byte* commitments, int count, byte* proof, IntPtr ts);
|
public unsafe static extern int VerifyAggregatedKzgProof(byte* blobs, byte* commitments_bytes, int count, byte* aggregated_proof_bytes, IntPtr ts);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Verify the proof by point evaluation for the given commitment
|
/// Verify the proof by point evaluation for the given commitment
|
||||||
|
@ -65,7 +65,7 @@ public class Ckzg
|
||||||
/// <param name="ts">Trusted setup settings</param>
|
/// <param name="ts">Trusted setup settings</param>
|
||||||
/// <returns>Returns error code or <c>0</c> if the proof is correct</returns>
|
/// <returns>Returns error code or <c>0</c> if the proof is correct</returns>
|
||||||
[DllImport("ckzg", EntryPoint = "verify_kzg_proof_wrap", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("ckzg", EntryPoint = "verify_kzg_proof_wrap", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public unsafe static extern int VerifyKzgProof(byte* commitment, byte* z, byte* y, byte* proof, IntPtr ts);
|
public unsafe static extern int VerifyKzgProof(byte* commitment_bytes, byte* z_bytes, byte* y_bytes, byte* proof_bytes, IntPtr ts);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load trusted setup settings from file
|
/// Load trusted setup settings from file
|
||||||
|
|
|
@ -24,17 +24,17 @@ void free_trusted_setup_wrap(KZGSettings *s) {
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int verify_aggregate_kzg_proof_wrap(const Blob *blobs, const KZGCommitment *commitments, size_t n, const KZGProof *proof, const KZGSettings *s) {
|
int verify_aggregate_kzg_proof_wrap(const Blob *blobs, const Bytes48 *commitments_bytes, size_t n, const Bytes48 *aggregated_proof_bytes, const KZGSettings *s) {
|
||||||
bool b;
|
bool b;
|
||||||
C_KZG_RET ret = verify_aggregate_kzg_proof(&b, blobs, commitments, n, proof, s);
|
C_KZG_RET ret = verify_aggregate_kzg_proof(&b, blobs, commitments_bytes, n, aggregated_proof_bytes, s);
|
||||||
if (ret != C_KZG_OK) return -1;
|
if (ret != C_KZG_OK) return -1;
|
||||||
|
|
||||||
return b ? 0 : 1;
|
return b ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int verify_kzg_proof_wrap(const KZGCommitment *c, const Bytes32 *z, const Bytes32 *y, const KZGProof *p, KZGSettings *s) {
|
int verify_kzg_proof_wrap(const Bytes48 *commitment_bytes, const Bytes32 *z_bytes, const Bytes32 *y_bytes, const Bytes48 *proof_bytes, KZGSettings *s) {
|
||||||
bool out;
|
bool out;
|
||||||
if (verify_kzg_proof(&out, c, z, y, p, s) != C_KZG_OK)
|
if (verify_kzg_proof(&out, commitment_bytes, z_bytes, y_bytes, proof_bytes, s) != C_KZG_OK)
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
return out ? 0 : 1;
|
return out ? 0 : 1;
|
||||||
|
|
|
@ -15,8 +15,8 @@ DLLEXPORT void free_trusted_setup_wrap(KZGSettings *s);
|
||||||
|
|
||||||
DLLEXPORT C_KZG_RET blob_to_kzg_commitment(KZGCommitment *out, const Blob *blob, const KZGSettings *s);
|
DLLEXPORT C_KZG_RET blob_to_kzg_commitment(KZGCommitment *out, const Blob *blob, const KZGSettings *s);
|
||||||
|
|
||||||
DLLEXPORT int verify_aggregate_kzg_proof_wrap(const Blob blobs[], const KZGCommitment *commitments, size_t n, const KZGProof *proof, const KZGSettings *s);
|
DLLEXPORT int verify_aggregate_kzg_proof_wrap(const Blob blobs[], const Bytes48 *commitments_bytes, size_t n, const Bytes48 *aggregated_proof_bytes, const KZGSettings *s);
|
||||||
|
|
||||||
DLLEXPORT C_KZG_RET compute_aggregate_kzg_proof(KZGProof *out, const Blob blobs[], size_t n, const KZGSettings *s);
|
DLLEXPORT C_KZG_RET compute_aggregate_kzg_proof(KZGProof *out, const Blob blobs[], size_t n, const KZGSettings *s);
|
||||||
|
|
||||||
DLLEXPORT int verify_kzg_proof_wrap(const KZGCommitment *c, const Bytes32 *z, const Bytes32 *y, const KZGProof *p, KZGSettings *s);
|
DLLEXPORT int verify_kzg_proof_wrap(const Bytes48 *commitment_bytes, const Bytes32 *z_bytes, const Bytes32 *y_bytes, const Bytes48 *proof_bytes, KZGSettings *s);
|
||||||
|
|
|
@ -160,7 +160,7 @@ JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_computeAggregate
|
||||||
return proof;
|
return proof;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyAggregateKzgProof(JNIEnv *env, jclass thisCls, jbyteArray blobs, jbyteArray commitments, jlong count, jbyteArray proof)
|
JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyAggregateKzgProof(JNIEnv *env, jclass thisCls, jbyteArray blobs, jbyteArray commitments_bytes, jlong count, jbyteArray proof_bytes)
|
||||||
{
|
{
|
||||||
if (settings == NULL)
|
if (settings == NULL)
|
||||||
{
|
{
|
||||||
|
@ -178,7 +178,7 @@ JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyAggregateKzg
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t commitments_size = (size_t)(*env)->GetArrayLength(env, commitments);
|
size_t commitments_size = (size_t)(*env)->GetArrayLength(env, commitments_bytes);
|
||||||
size_t expected_commitments_size = BYTES_PER_COMMITMENT * count_native;
|
size_t expected_commitments_size = BYTES_PER_COMMITMENT * count_native;
|
||||||
if (commitments_size != expected_commitments_size)
|
if (commitments_size != expected_commitments_size)
|
||||||
{
|
{
|
||||||
|
@ -186,15 +186,15 @@ JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyAggregateKzg
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KZGProof *proof_native = (KZGProof *)(*env)->GetByteArrayElements(env, proof, NULL);
|
Bytes48 *proof_native = (Bytes48 *)(*env)->GetByteArrayElements(env, proof_bytes, NULL);
|
||||||
KZGCommitment *commitments_native = (KZGCommitment *)(*env)->GetByteArrayElements(env, commitments, NULL);
|
Bytes48 *commitments_native = (Bytes48 *)(*env)->GetByteArrayElements(env, commitments_bytes, NULL);
|
||||||
jbyte *blobs_native = (*env)->GetByteArrayElements(env, blobs, NULL);
|
jbyte *blobs_native = (*env)->GetByteArrayElements(env, blobs, NULL);
|
||||||
|
|
||||||
bool out;
|
bool out;
|
||||||
C_KZG_RET ret = verify_aggregate_kzg_proof(&out, (const Blob *)blobs_native, commitments_native, count_native, proof_native, settings);
|
C_KZG_RET ret = verify_aggregate_kzg_proof(&out, (const Blob *)blobs_native, commitments_native, count_native, proof_native, settings);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements(env, proof, (jbyte *)proof_native, JNI_ABORT);
|
(*env)->ReleaseByteArrayElements(env, proof_bytes, (jbyte *)proof_native, JNI_ABORT);
|
||||||
(*env)->ReleaseByteArrayElements(env, commitments, (jbyte *)commitments_native, JNI_ABORT);
|
(*env)->ReleaseByteArrayElements(env, commitments_bytes, (jbyte *)commitments_native, JNI_ABORT);
|
||||||
(*env)->ReleaseByteArrayElements(env, blobs, blobs_native, JNI_ABORT);
|
(*env)->ReleaseByteArrayElements(env, blobs, blobs_native, JNI_ABORT);
|
||||||
|
|
||||||
if (ret != C_KZG_OK)
|
if (ret != C_KZG_OK)
|
||||||
|
@ -239,7 +239,7 @@ JNIEXPORT jbyteArray JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_blobToKzgCommitm
|
||||||
return commitment;
|
return commitment;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyKzgProof(JNIEnv *env, jclass thisCls, jbyteArray commitment, jbyteArray z, jbyteArray y, jbyteArray proof)
|
JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyKzgProof(JNIEnv *env, jclass thisCls, jbyteArray commitment_bytes, jbyteArray z_bytes, jbyteArray y_bytes, jbyteArray proof_bytes)
|
||||||
{
|
{
|
||||||
if (settings == NULL)
|
if (settings == NULL)
|
||||||
{
|
{
|
||||||
|
@ -247,18 +247,18 @@ JNIEXPORT jboolean JNICALL Java_ethereum_ckzg4844_CKZG4844JNI_verifyKzgProof(JNI
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KZGCommitment *commitment_native = (KZGCommitment *)(*env)->GetByteArrayElements(env, commitment, NULL);
|
Bytes48 *commitment_native = (Bytes48 *)(*env)->GetByteArrayElements(env, commitment_bytes, NULL);
|
||||||
KZGProof *proof_native = (KZGProof *)(*env)->GetByteArrayElements(env, proof, NULL);
|
Bytes48 *proof_native = (Bytes48 *)(*env)->GetByteArrayElements(env, proof_bytes, NULL);
|
||||||
Bytes32 *z_native = (Bytes32 *)(*env)->GetByteArrayElements(env, z, NULL);
|
Bytes32 *z_native = (Bytes32 *)(*env)->GetByteArrayElements(env, z_bytes, NULL);
|
||||||
Bytes32 *y_native = (Bytes32 *)(*env)->GetByteArrayElements(env, y, NULL);
|
Bytes32 *y_native = (Bytes32 *)(*env)->GetByteArrayElements(env, y_bytes, NULL);
|
||||||
|
|
||||||
bool out;
|
bool out;
|
||||||
C_KZG_RET ret = verify_kzg_proof(&out, commitment_native, z_native, y_native, proof_native, settings);
|
C_KZG_RET ret = verify_kzg_proof(&out, commitment_native, z_native, y_native, proof_native, settings);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements(env, commitment, (jbyte *)commitment_native, JNI_ABORT);
|
(*env)->ReleaseByteArrayElements(env, commitment_bytes, (jbyte *)commitment_native, JNI_ABORT);
|
||||||
(*env)->ReleaseByteArrayElements(env, z, (jbyte *)z_native, JNI_ABORT);
|
(*env)->ReleaseByteArrayElements(env, z_bytes, (jbyte *)z_native, JNI_ABORT);
|
||||||
(*env)->ReleaseByteArrayElements(env, y, (jbyte *)y_native, JNI_ABORT);
|
(*env)->ReleaseByteArrayElements(env, y_bytes, (jbyte *)y_native, JNI_ABORT);
|
||||||
(*env)->ReleaseByteArrayElements(env, proof, (jbyte *)proof_native, JNI_ABORT);
|
(*env)->ReleaseByteArrayElements(env, proof_bytes, (jbyte *)proof_native, JNI_ABORT);
|
||||||
|
|
||||||
if (ret != C_KZG_OK)
|
if (ret != C_KZG_OK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -126,15 +126,15 @@ public class CKZG4844JNI {
|
||||||
/**
|
/**
|
||||||
* Verify aggregated proof and commitments for the given blobs
|
* Verify aggregated proof and commitments for the given blobs
|
||||||
*
|
*
|
||||||
* @param blobs blobs as flattened bytes
|
* @param blobs blobs as flattened bytes
|
||||||
* @param commitments commitments as flattened bytes
|
* @param commitments_bytes commitments as flattened bytes
|
||||||
* @param count the count of the blobs (should be same as the count of the commitments)
|
* @param count the count of the blobs (should be same as the count of the commitments)
|
||||||
* @param proof the proof that needs verifying
|
* @param proof_bytes the proof that needs verifying
|
||||||
* @return true if the proof is valid and false otherwise
|
* @return true if the proof is valid and false otherwise
|
||||||
* @throws CKZGException if there is a crypto error
|
* @throws CKZGException if there is a crypto error
|
||||||
*/
|
*/
|
||||||
public static native boolean verifyAggregateKzgProof(byte[] blobs, byte[] commitments, long count,
|
public static native boolean verifyAggregateKzgProof(byte[] blobs, byte[] commitments_bytes, long count,
|
||||||
byte[] proof);
|
byte[] aggregated_proof_bytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates commitment for a given blob
|
* Calculates commitment for a given blob
|
||||||
|
@ -148,13 +148,14 @@ public class CKZG4844JNI {
|
||||||
/**
|
/**
|
||||||
* Verify the proof by point evaluation for the given commitment
|
* Verify the proof by point evaluation for the given commitment
|
||||||
*
|
*
|
||||||
* @param commitment commitment bytes
|
* @param commitment_bytes commitment bytes
|
||||||
* @param z Z
|
* @param z_bytes Z
|
||||||
* @param y Y
|
* @param y_bytes Y
|
||||||
* @param proof the proof that needs verifying
|
* @param proof_bytes the proof that needs verifying
|
||||||
* @return true if the proof is valid and false otherwise
|
* @return true if the proof is valid and false otherwise
|
||||||
* @throws CKZGException if there is a crypto error
|
* @throws CKZGException if there is a crypto error
|
||||||
*/
|
*/
|
||||||
public static native boolean verifyKzgProof(byte[] commitment, byte[] z, byte[] y, byte[] proof);
|
public static native boolean verifyKzgProof(byte[] commitment_bytes, byte[] z_bytes, byte[] y_bytes,
|
||||||
|
byte[] proof_bytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ Napi::Value ComputeAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||||
return napi_typed_array_from_bytes((uint8_t *)(&proof), BYTES_PER_PROOF, env);
|
return napi_typed_array_from_bytes((uint8_t *)(&proof), BYTES_PER_PROOF, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyAggregateKzgProof: (blobs: Blob[], expectedKzgCommitments: KZGCommitment[], kzgAggregatedProof: KZGProof, setupHandle: SetupHandle) => boolean;
|
// verifyAggregateKzgProof: (blobs: Blob[], commitmentsBytes: Bytes48[], aggregatedProofBytes: Bytes48, setupHandle: SetupHandle) => boolean;
|
||||||
Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||||
auto env = info.Env();
|
auto env = info.Env();
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||||
return env.Null();
|
return env.Null();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto commitments = (KZGCommitment*)calloc(blobs_count, sizeof(KZGCommitment));
|
auto commitments = (Bytes48*)calloc(blobs_count, sizeof(Bytes48));
|
||||||
if (commitments == NULL) {
|
if (commitments == NULL) {
|
||||||
free(blobs);
|
free(blobs);
|
||||||
Napi::Error::New(env, "Error while allocating memory for commitments").ThrowAsJavaScriptException();
|
Napi::Error::New(env, "Error while allocating memory for commitments").ThrowAsJavaScriptException();
|
||||||
|
@ -248,7 +248,7 @@ Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||||
blobs,
|
blobs,
|
||||||
commitments,
|
commitments,
|
||||||
blobs_count,
|
blobs_count,
|
||||||
(KZGProof *)proof_bytes,
|
(Bytes48 *)proof_bytes,
|
||||||
kzg_settings
|
kzg_settings
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ Napi::Value VerifyAggregateKzgProof(const Napi::CallbackInfo& info) {
|
||||||
return Napi::Boolean::New(env, verification_result);
|
return Napi::Boolean::New(env, verification_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyKzgProof: (polynomialKzg: KZGCommitment, z: Bytes32, y: Bytes32, kzgProof: KZGProof, setupHandle: SetupHandle) => boolean;
|
// verifyKzgProof: (commitmentBytes: Bytes48, zBytes: Bytes32, yBytes: Bytes32, proofBytes: Bytes48, setupHandle: SetupHandle) => boolean;
|
||||||
Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
||||||
auto env = info.Env();
|
auto env = info.Env();
|
||||||
|
|
||||||
|
@ -276,10 +276,10 @@ Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
||||||
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
return throw_invalid_arguments_count(expected_argument_count, argument_count, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto polynomial_kzg = extract_byte_array_from_param(info, 0, "polynomialKzg");
|
auto commitment_bytes = extract_byte_array_from_param(info, 0, "commitmentBytes");
|
||||||
auto z = extract_byte_array_from_param(info, 1, "z");
|
auto z_bytes = extract_byte_array_from_param(info, 1, "zBytes");
|
||||||
auto y = extract_byte_array_from_param(info, 2, "y");
|
auto y_bytes = extract_byte_array_from_param(info, 2, "yBytes");
|
||||||
auto kzg_proof = extract_byte_array_from_param(info, 3, "kzgProof");
|
auto proof_bytes = extract_byte_array_from_param(info, 3, "proofBytes");
|
||||||
auto kzg_settings = info[4].As<Napi::External<KZGSettings>>().Data();
|
auto kzg_settings = info[4].As<Napi::External<KZGSettings>>().Data();
|
||||||
|
|
||||||
if (env.IsExceptionPending()) {
|
if (env.IsExceptionPending()) {
|
||||||
|
@ -289,10 +289,10 @@ Napi::Value VerifyKzgProof(const Napi::CallbackInfo& info) {
|
||||||
bool out;
|
bool out;
|
||||||
C_KZG_RET ret = verify_kzg_proof(
|
C_KZG_RET ret = verify_kzg_proof(
|
||||||
&out,
|
&out,
|
||||||
(KZGCommitment *)polynomial_kzg,
|
(Bytes48 *)commitment_bytes,
|
||||||
(Bytes32 *)z,
|
(Bytes32 *)z_bytes,
|
||||||
(Bytes32 *)y,
|
(Bytes32 *)y_bytes,
|
||||||
(KZGProof *)kzg_proof,
|
(Bytes48 *)proof_bytes,
|
||||||
kzg_settings
|
kzg_settings
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ const kzg: KZG = require("./kzg.node");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
|
||||||
export type Bytes32 = Uint8Array; // 32 bytes
|
export type Bytes32 = Uint8Array; // 32 bytes
|
||||||
|
export type Bytes48 = Uint8Array; // 48 bytes
|
||||||
export type KZGProof = Uint8Array; // 48 bytes
|
export type KZGProof = Uint8Array; // 48 bytes
|
||||||
export type KZGCommitment = Uint8Array; // 48 bytes
|
export type KZGCommitment = Uint8Array; // 48 bytes
|
||||||
export type Blob = Uint8Array; // 4096 * 32 bytes
|
export type Blob = Uint8Array; // 4096 * 32 bytes
|
||||||
|
@ -30,16 +31,16 @@ type KZG = {
|
||||||
|
|
||||||
verifyAggregateKzgProof: (
|
verifyAggregateKzgProof: (
|
||||||
blobs: Blob[],
|
blobs: Blob[],
|
||||||
expectedKzgCommitments: KZGCommitment[],
|
commitmentsBytes: Bytes48[],
|
||||||
kzgAggregatedProof: KZGProof,
|
aggregatedProofBytes: Bytes48,
|
||||||
setupHandle: SetupHandle,
|
setupHandle: SetupHandle,
|
||||||
) => boolean;
|
) => boolean;
|
||||||
|
|
||||||
verifyKzgProof: (
|
verifyKzgProof: (
|
||||||
polynomialKzg: KZGCommitment,
|
commitmentBytes: Bytes48,
|
||||||
z: Bytes32,
|
zBytes: Bytes32,
|
||||||
y: Bytes32,
|
yBytes: Bytes32,
|
||||||
kzgProof: KZGProof,
|
proofBytes: Bytes48,
|
||||||
setupHandle: SetupHandle,
|
setupHandle: SetupHandle,
|
||||||
) => boolean;
|
) => boolean;
|
||||||
};
|
};
|
||||||
|
@ -114,29 +115,29 @@ export function computeAggregateKzgProof(blobs: Blob[]): KZGProof {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyKzgProof(
|
export function verifyKzgProof(
|
||||||
polynomialKzg: KZGCommitment,
|
commitmentBytes: Bytes48,
|
||||||
z: Bytes32,
|
zBytes: Bytes32,
|
||||||
y: Bytes32,
|
yBytes: Bytes32,
|
||||||
kzgProof: KZGProof,
|
proofBytes: Bytes48,
|
||||||
): boolean {
|
): boolean {
|
||||||
return kzg.verifyKzgProof(
|
return kzg.verifyKzgProof(
|
||||||
polynomialKzg,
|
commitmentBytes,
|
||||||
z,
|
zBytes,
|
||||||
y,
|
yBytes,
|
||||||
kzgProof,
|
proofBytes,
|
||||||
requireSetupHandle(),
|
requireSetupHandle(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyAggregateKzgProof(
|
export function verifyAggregateKzgProof(
|
||||||
blobs: Blob[],
|
blobs: Blob[],
|
||||||
expectedKzgCommitments: KZGCommitment[],
|
commitmentsBytes: Bytes48[],
|
||||||
kzgAggregatedProof: KZGProof,
|
proofBytes: Bytes48,
|
||||||
): boolean {
|
): boolean {
|
||||||
return kzg.verifyAggregateKzgProof(
|
return kzg.verifyAggregateKzgProof(
|
||||||
blobs,
|
blobs,
|
||||||
expectedKzgCommitments,
|
commitmentsBytes,
|
||||||
kzgAggregatedProof,
|
proofBytes,
|
||||||
requireSetupHandle(),
|
requireSetupHandle(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,12 +106,12 @@ static PyObject* verify_aggregate_kzg_proof_wrap(PyObject *self, PyObject *args)
|
||||||
return PyErr_Format(PyExc_ValueError, "expected same number of commitments as polynomials");
|
return PyErr_Format(PyExc_ValueError, "expected same number of commitments as polynomials");
|
||||||
|
|
||||||
const Blob* blobs = (Blob *)PyBytes_AsString(b);
|
const Blob* blobs = (Blob *)PyBytes_AsString(b);
|
||||||
const KZGProof *proof = (KZGProof *)PyBytes_AsString(p);
|
const Bytes48 *proof_bytes = (Bytes48 *)PyBytes_AsString(p);
|
||||||
const KZGCommitment *commitments = (KZGCommitment *)PyBytes_AsString(c);
|
const Bytes48 *commitments_bytes = (Bytes48 *)PyBytes_AsString(c);
|
||||||
|
|
||||||
bool out;
|
bool out;
|
||||||
if (verify_aggregate_kzg_proof(&out,
|
if (verify_aggregate_kzg_proof(&out,
|
||||||
blobs, commitments, n, proof,
|
blobs, commitments_bytes, n, proof_bytes,
|
||||||
PyCapsule_GetPointer(s, "KZGSettings")) != C_KZG_OK) {
|
PyCapsule_GetPointer(s, "KZGSettings")) != C_KZG_OK) {
|
||||||
return PyErr_Format(PyExc_RuntimeError, "verify_aggregate_kzg_proof failed");
|
return PyErr_Format(PyExc_RuntimeError, "verify_aggregate_kzg_proof failed");
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,13 @@ struct blst_fr {
|
||||||
struct blst_fp {
|
struct blst_fp {
|
||||||
l: [limb_t; 6usize],
|
l: [limb_t; 6usize],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
struct blst_fp2 {
|
struct blst_fp2 {
|
||||||
fp: [blst_fp; 2usize],
|
fp: [blst_fp; 2usize],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
struct blst_fp6 {
|
struct blst_fp6 {
|
||||||
|
@ -90,6 +92,19 @@ impl Deref for Bytes32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct Bytes48 {
|
||||||
|
bytes: [u8; 48],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Bytes48 {
|
||||||
|
type Target = [u8; 48];
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct Blob {
|
pub struct Blob {
|
||||||
|
@ -207,9 +222,9 @@ extern "C" {
|
||||||
pub fn verify_aggregate_kzg_proof(
|
pub fn verify_aggregate_kzg_proof(
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
blobs: *const Blob,
|
blobs: *const Blob,
|
||||||
expected_kzg_commitments: *const KZGCommitment,
|
commitments_bytes: *const Bytes48,
|
||||||
n: usize,
|
n: usize,
|
||||||
kzg_aggregated_proof: *const KZGProof,
|
aggregated_proof_bytes: *const Bytes48,
|
||||||
s: *const KZGSettings,
|
s: *const KZGSettings,
|
||||||
) -> C_KZG_RET;
|
) -> C_KZG_RET;
|
||||||
|
|
||||||
|
@ -221,10 +236,10 @@ extern "C" {
|
||||||
|
|
||||||
pub fn verify_kzg_proof(
|
pub fn verify_kzg_proof(
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
polynomial_kzg: *const KZGCommitment,
|
commitment_bytes: *const Bytes48,
|
||||||
z: *const Bytes32,
|
z_bytes: *const Bytes32,
|
||||||
y: *const Bytes32,
|
y_bytes: *const Bytes32,
|
||||||
kzg_proof: *const KZGProof,
|
proof_bytes: *const Bytes48,
|
||||||
s: *const KZGSettings,
|
s: *const KZGSettings,
|
||||||
) -> C_KZG_RET;
|
) -> C_KZG_RET;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ const NUM_G2_POINTS: usize = 65;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// Wrong number of bytes.
|
||||||
|
InvalidBytesLength(String),
|
||||||
/// The KZG proof is invalid.
|
/// The KZG proof is invalid.
|
||||||
InvalidKzgProof(String),
|
InvalidKzgProof(String),
|
||||||
/// The KZG commitment is invalid.
|
/// The KZG commitment is invalid.
|
||||||
|
@ -105,6 +107,36 @@ impl Drop for KZGSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Bytes32 {
|
||||||
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
|
if bytes.len() != 32 {
|
||||||
|
return Err(Error::InvalidBytesLength(format!(
|
||||||
|
"Invalid byte length. Expected {} got {}",
|
||||||
|
32,
|
||||||
|
bytes.len(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
let mut new_bytes = [0; 32];
|
||||||
|
new_bytes.copy_from_slice(bytes);
|
||||||
|
Ok(Self { bytes: new_bytes })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bytes48 {
|
||||||
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
|
if bytes.len() != 48 {
|
||||||
|
return Err(Error::InvalidBytesLength(format!(
|
||||||
|
"Invalid byte length. Expected {} got {}",
|
||||||
|
48,
|
||||||
|
bytes.len(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
let mut new_bytes = [0; 48];
|
||||||
|
new_bytes.copy_from_slice(bytes);
|
||||||
|
Ok(Self { bytes: new_bytes })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl KZGProof {
|
impl KZGProof {
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
if bytes.len() != BYTES_PER_PROOF {
|
if bytes.len() != BYTES_PER_PROOF {
|
||||||
|
@ -119,12 +151,14 @@ impl KZGProof {
|
||||||
Ok(Self { bytes: proof_bytes })
|
Ok(Self { bytes: proof_bytes })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> [u8; BYTES_PER_G1_POINT] {
|
pub fn to_bytes(&self) -> Bytes48 {
|
||||||
self.bytes
|
let mut bytes = [0; 48];
|
||||||
|
bytes.copy_from_slice(&self.bytes);
|
||||||
|
Bytes48 { bytes }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_hex_string(&self) -> String {
|
pub fn as_hex_string(&self) -> String {
|
||||||
hex::encode(self.to_bytes())
|
hex::encode(self.bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_aggregate_kzg_proof(
|
pub fn compute_aggregate_kzg_proof(
|
||||||
|
@ -150,14 +184,14 @@ impl KZGProof {
|
||||||
pub fn verify_aggregate_kzg_proof(
|
pub fn verify_aggregate_kzg_proof(
|
||||||
&self,
|
&self,
|
||||||
blobs: &[Blob],
|
blobs: &[Blob],
|
||||||
expected_kzg_commitments: &[KZGCommitment],
|
commitments_bytes: &[Bytes48],
|
||||||
kzg_settings: &KZGSettings,
|
kzg_settings: &KZGSettings,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
if blobs.len() != expected_kzg_commitments.len() {
|
if blobs.len() != commitments_bytes.len() {
|
||||||
return Err(Error::MismatchLength(format!(
|
return Err(Error::MismatchLength(format!(
|
||||||
"There are {} blobs and {} commitments",
|
"There are {} blobs and {} commitments",
|
||||||
blobs.len(),
|
blobs.len(),
|
||||||
expected_kzg_commitments.len()
|
commitments_bytes.len()
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
let mut verified: MaybeUninit<bool> = MaybeUninit::uninit();
|
let mut verified: MaybeUninit<bool> = MaybeUninit::uninit();
|
||||||
|
@ -165,9 +199,9 @@ impl KZGProof {
|
||||||
let res = verify_aggregate_kzg_proof(
|
let res = verify_aggregate_kzg_proof(
|
||||||
verified.as_mut_ptr(),
|
verified.as_mut_ptr(),
|
||||||
blobs.as_ptr(),
|
blobs.as_ptr(),
|
||||||
expected_kzg_commitments.as_ptr(),
|
commitments_bytes.as_ptr(),
|
||||||
blobs.len(),
|
blobs.len(),
|
||||||
self,
|
&self.to_bytes(),
|
||||||
kzg_settings,
|
kzg_settings,
|
||||||
);
|
);
|
||||||
if let C_KZG_RET::C_KZG_OK = res {
|
if let C_KZG_RET::C_KZG_OK = res {
|
||||||
|
@ -180,19 +214,19 @@ impl KZGProof {
|
||||||
|
|
||||||
pub fn verify_kzg_proof(
|
pub fn verify_kzg_proof(
|
||||||
&self,
|
&self,
|
||||||
kzg_commitment: KZGCommitment,
|
commitment_bytes: Bytes48,
|
||||||
z: Bytes32,
|
z_bytes: Bytes32,
|
||||||
y: Bytes32,
|
y_bytes: Bytes32,
|
||||||
kzg_settings: &KZGSettings,
|
kzg_settings: &KZGSettings,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let mut verified: MaybeUninit<bool> = MaybeUninit::uninit();
|
let mut verified: MaybeUninit<bool> = MaybeUninit::uninit();
|
||||||
unsafe {
|
unsafe {
|
||||||
let res = verify_kzg_proof(
|
let res = verify_kzg_proof(
|
||||||
verified.as_mut_ptr(),
|
verified.as_mut_ptr(),
|
||||||
&kzg_commitment,
|
&commitment_bytes,
|
||||||
&z,
|
&z_bytes,
|
||||||
&y,
|
&y_bytes,
|
||||||
self,
|
&self.to_bytes(),
|
||||||
kzg_settings,
|
kzg_settings,
|
||||||
);
|
);
|
||||||
if let C_KZG_RET::C_KZG_OK = res {
|
if let C_KZG_RET::C_KZG_OK = res {
|
||||||
|
@ -218,12 +252,14 @@ impl KZGCommitment {
|
||||||
Ok(Self { bytes: commitment })
|
Ok(Self { bytes: commitment })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> [u8; BYTES_PER_G1_POINT] {
|
pub fn to_bytes(&self) -> Bytes48 {
|
||||||
self.bytes
|
let mut bytes = [0; 48];
|
||||||
|
bytes.copy_from_slice(&self.bytes);
|
||||||
|
Bytes48 { bytes }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_hex_string(&self) -> String {
|
pub fn as_hex_string(&self) -> String {
|
||||||
hex::encode(self.to_bytes())
|
hex::encode(self.bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blob_to_kzg_commitment(blob: Blob, kzg_settings: &KZGSettings) -> Self {
|
pub fn blob_to_kzg_commitment(blob: Blob, kzg_settings: &KZGSettings) -> Self {
|
||||||
|
@ -263,6 +299,12 @@ impl From<[u8; 32]> for Bytes32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<[u8; 48]> for Bytes48 {
|
||||||
|
fn from(value: [u8; 48]) -> Self {
|
||||||
|
Self { bytes: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -289,22 +331,23 @@ mod tests {
|
||||||
.map(|_| generate_random_blob(&mut rng))
|
.map(|_| generate_random_blob(&mut rng))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let kzg_commitments: Vec<KZGCommitment> = blobs
|
let commitments: Vec<Bytes48> = blobs
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|blob| KZGCommitment::blob_to_kzg_commitment(blob, &kzg_settings))
|
.map(|blob| KZGCommitment::blob_to_kzg_commitment(blob, &kzg_settings))
|
||||||
|
.map(|commitment| commitment.to_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let kzg_proof = KZGProof::compute_aggregate_kzg_proof(&blobs, &kzg_settings).unwrap();
|
let kzg_proof = KZGProof::compute_aggregate_kzg_proof(&blobs, &kzg_settings).unwrap();
|
||||||
|
|
||||||
assert!(kzg_proof
|
assert!(kzg_proof
|
||||||
.verify_aggregate_kzg_proof(&blobs, &kzg_commitments, &kzg_settings)
|
.verify_aggregate_kzg_proof(&blobs, &commitments, &kzg_settings)
|
||||||
.unwrap());
|
.unwrap());
|
||||||
|
|
||||||
blobs.pop();
|
blobs.pop();
|
||||||
|
|
||||||
let error = kzg_proof
|
let error = kzg_proof
|
||||||
.verify_aggregate_kzg_proof(&blobs, &kzg_commitments, &kzg_settings)
|
.verify_aggregate_kzg_proof(&blobs, &commitments, &kzg_settings)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert!(matches!(error, Error::MismatchLength(_)));
|
assert!(matches!(error, Error::MismatchLength(_)));
|
||||||
|
|
||||||
|
@ -312,7 +355,7 @@ mod tests {
|
||||||
blobs.push(incorrect_blob);
|
blobs.push(incorrect_blob);
|
||||||
|
|
||||||
assert!(!kzg_proof
|
assert!(!kzg_proof
|
||||||
.verify_aggregate_kzg_proof(&blobs, &kzg_commitments, &kzg_settings)
|
.verify_aggregate_kzg_proof(&blobs, &commitments, &kzg_settings)
|
||||||
.unwrap());
|
.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +384,7 @@ mod tests {
|
||||||
for test in tests.iter() {
|
for test in tests.iter() {
|
||||||
let expected_proof = test.get("Proof").unwrap().as_str().unwrap();
|
let expected_proof = test.get("Proof").unwrap().as_str().unwrap();
|
||||||
|
|
||||||
let expected_kzg_commitments = test
|
let expected_commitments = test
|
||||||
.get("Commitments")
|
.get("Commitments")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_array()
|
.as_array()
|
||||||
|
@ -372,7 +415,7 @@ mod tests {
|
||||||
let commitment = KZGCommitment::blob_to_kzg_commitment(blob, &kzg_settings);
|
let commitment = KZGCommitment::blob_to_kzg_commitment(blob, &kzg_settings);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
commitment.as_hex_string().as_str(),
|
commitment.as_hex_string().as_str(),
|
||||||
expected_kzg_commitments[i]
|
expected_commitments[i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,23 +437,20 @@ mod tests {
|
||||||
let proof = test.get("Proof").unwrap().as_str().unwrap();
|
let proof = test.get("Proof").unwrap().as_str().unwrap();
|
||||||
let kzg_proof = KZGProof::from_bytes(&hex::decode(proof).unwrap()).unwrap();
|
let kzg_proof = KZGProof::from_bytes(&hex::decode(proof).unwrap()).unwrap();
|
||||||
|
|
||||||
let commitment = test.get("Commitment").unwrap().as_str().unwrap();
|
let commitment_hex = test.get("Commitment").unwrap().as_str().unwrap();
|
||||||
let kzg_commitment =
|
let commitment = Bytes48::from_bytes(&hex::decode(commitment_hex).unwrap()).unwrap();
|
||||||
KZGCommitment::from_bytes(&hex::decode(commitment).unwrap()).unwrap();
|
|
||||||
|
|
||||||
let z = test.get("InputPoint").unwrap().as_str().unwrap();
|
let z_hex = test.get("InputPoint").unwrap().as_str().unwrap();
|
||||||
let mut z_bytes = [0; BYTES_PER_FIELD_ELEMENT];
|
let z_bytes = Bytes32::from_bytes(&hex::decode(z_hex).unwrap()).unwrap();
|
||||||
z_bytes.copy_from_slice(&hex::decode(z).unwrap());
|
|
||||||
|
|
||||||
let y = test.get("ClaimedValue").unwrap().as_str().unwrap();
|
let y_hex = test.get("ClaimedValue").unwrap().as_str().unwrap();
|
||||||
let mut y_bytes = [0; BYTES_PER_FIELD_ELEMENT];
|
let y_bytes = Bytes32::from_bytes(&hex::decode(y_hex).unwrap()).unwrap();
|
||||||
y_bytes.copy_from_slice(&hex::decode(y).unwrap());
|
|
||||||
|
|
||||||
assert!(kzg_proof
|
assert!(kzg_proof
|
||||||
.verify_kzg_proof(
|
.verify_kzg_proof(
|
||||||
kzg_commitment,
|
commitment,
|
||||||
z_bytes.into(),
|
z_bytes,
|
||||||
y_bytes.into(),
|
y_bytes,
|
||||||
&kzg_settings
|
&kzg_settings
|
||||||
)
|
)
|
||||||
.unwrap());
|
.unwrap());
|
||||||
|
|
155
src/c_kzg_4844.c
155
src/c_kzg_4844.c
|
@ -37,11 +37,11 @@ typedef struct { fr_t evals[FIELD_ELEMENTS_PER_BLOB]; } Polynomial;
|
||||||
// Constants
|
// Constants
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/** The G1 identity/infinity. */
|
/** Deserialized form of the G1 identity/infinity point. */
|
||||||
static const g1_t g1_identity = {{0L, 0L, 0L, 0L, 0L, 0L}, {0L, 0L, 0L, 0L, 0L, 0L}, {0L, 0L, 0L, 0L, 0L, 0L}};
|
static const g1_t G1_IDENTITY = {{0L, 0L, 0L, 0L, 0L, 0L}, {0L, 0L, 0L, 0L, 0L, 0L}, {0L, 0L, 0L, 0L, 0L, 0L}};
|
||||||
|
|
||||||
/** The G1 generator. */
|
/** The G1 generator. */
|
||||||
static const g1_t g1_generator = {{
|
static const g1_t G1_GENERATOR = {{
|
||||||
0x5cb38790fd530c16L, 0x7817fc679976fff5L, 0x154f95c7143ba1c1L, 0xf0ae6acdf3d0e747L,
|
0x5cb38790fd530c16L, 0x7817fc679976fff5L, 0x154f95c7143ba1c1L, 0xf0ae6acdf3d0e747L,
|
||||||
0xedce6ecc21dbf440L, 0x120177419e0bfb75L
|
0xedce6ecc21dbf440L, 0x120177419e0bfb75L
|
||||||
},
|
},
|
||||||
|
@ -56,7 +56,7 @@ static const g1_t g1_generator = {{
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The G2 generator. */
|
/** The G2 generator. */
|
||||||
static const g2_t g2_generator = {{{{
|
static const g2_t G2_GENERATOR = {{{{
|
||||||
0xf5f28fa202940a10L, 0xb3f5fb2687b4961aL, 0xa1a893b53e2ae580L, 0x9894999d1a3caee9L,
|
0xf5f28fa202940a10L, 0xb3f5fb2687b4961aL, 0xa1a893b53e2ae580L, 0x9894999d1a3caee9L,
|
||||||
0x6f67b7631863366bL, 0x058191924350bcd7L
|
0x6f67b7631863366bL, 0x058191924350bcd7L
|
||||||
},
|
},
|
||||||
|
@ -108,7 +108,7 @@ static const g2_t g2_generator = {{{{
|
||||||
* to create the roots of unity below. There are a lot of primitive roots:
|
* to create the roots of unity below. There are a lot of primitive roots:
|
||||||
* https://crypto.stanford.edu/pbc/notes/numbertheory/gen.html
|
* https://crypto.stanford.edu/pbc/notes/numbertheory/gen.html
|
||||||
*/
|
*/
|
||||||
static const uint64_t scale2_root_of_unity[][4] = {
|
static const uint64_t SCALE2_ROOT_OF_UNITY[][4] = {
|
||||||
{0x0000000000000001L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L},
|
{0x0000000000000001L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L},
|
||||||
{0xffffffff00000000L, 0x53bda402fffe5bfeL, 0x3339d80809a1d805L, 0x73eda753299d7d48L},
|
{0xffffffff00000000L, 0x53bda402fffe5bfeL, 0x3339d80809a1d805L, 0x73eda753299d7d48L},
|
||||||
{0x0001000000000000L, 0xec03000276030000L, 0x8d51ccce760304d0L, 0x0000000000000000L},
|
{0x0001000000000000L, 0xec03000276030000L, 0x8d51ccce760304d0L, 0x0000000000000000L},
|
||||||
|
@ -367,7 +367,7 @@ static void g1_mul(g1_t *out, const g1_t *a, const fr_t *b) {
|
||||||
int i = sizeof(blst_scalar);
|
int i = sizeof(blst_scalar);
|
||||||
while (i && !s.b[i - 1]) --i;
|
while (i && !s.b[i - 1]) --i;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
*out = g1_identity;
|
*out = G1_IDENTITY;
|
||||||
} else if (i == 1 && s.b[0] == 1) {
|
} else if (i == 1 && s.b[0] == 1) {
|
||||||
*out = *a;
|
*out = *a;
|
||||||
} else {
|
} else {
|
||||||
|
@ -482,36 +482,18 @@ static int log2_pow2(uint32_t n) {
|
||||||
* @param[out] out A 48-byte array to store the serialized G1 element
|
* @param[out] out A 48-byte array to store the serialized G1 element
|
||||||
* @param[in] in The G1 element to be serialized
|
* @param[in] in The G1 element to be serialized
|
||||||
*/
|
*/
|
||||||
static void bytes_from_g1(uint8_t out[48], const g1_t *in) {
|
static void bytes_from_g1(Bytes48 *out, const g1_t *in) {
|
||||||
blst_p1_compress(out, in);
|
blst_p1_compress(out->bytes, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deserialize bytes into a G1 group element.
|
|
||||||
*
|
|
||||||
* @param[out] out The G1 element to store the deserialized data
|
|
||||||
* @param[in] bytes A 48-byte array containing the serialized G1 element
|
|
||||||
* @retval C_KZG_OK Deserialization successful
|
|
||||||
* @retval C_KZG_BADARGS Input bytes were not a valid G1 element
|
|
||||||
*/
|
|
||||||
static C_KZG_RET bytes_to_g1(g1_t* out, const uint8_t bytes[48]) {
|
|
||||||
blst_p1_affine tmp;
|
|
||||||
if (blst_p1_uncompress(&tmp, bytes) != BLST_SUCCESS)
|
|
||||||
return C_KZG_BADARGS;
|
|
||||||
blst_p1_from_affine(out, &tmp);
|
|
||||||
return C_KZG_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize a BLS field element into bytes.
|
* Serialize a BLS field element into bytes.
|
||||||
*
|
*
|
||||||
* @param[out] out A 32-byte array to store the serialized field element
|
* @param[out] out A 32-byte array to store the serialized field element
|
||||||
* @param[in] in The field element to be serialized
|
* @param[in] in The field element to be serialized
|
||||||
*/
|
*/
|
||||||
static void bytes_from_bls_field(uint8_t out[32], const fr_t *in) {
|
static void bytes_from_bls_field(Bytes32 *out, const fr_t *in) {
|
||||||
blst_scalar_from_fr((blst_scalar*)out, in);
|
blst_scalar_from_fr((blst_scalar*)out->bytes, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -627,7 +609,7 @@ static void hash_to_bls_field(fr_t *out, const Bytes32 *b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserialize bytes into a BLS field element.
|
* Convert untrusted bytes to a trusted and validated BLS scalar field element.
|
||||||
*
|
*
|
||||||
* @param[out] out The field element to store the deserialized data
|
* @param[out] out The field element to store the deserialized data
|
||||||
* @param[in] bytes A 32-byte array containing the serialized field element
|
* @param[in] bytes A 32-byte array containing the serialized field element
|
||||||
|
@ -642,6 +624,62 @@ static C_KZG_RET bytes_to_bls_field(fr_t *out, const Bytes32 *b) {
|
||||||
return C_KZG_OK;
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform BLS validation required by the types KZGProof and KZGCommitment.
|
||||||
|
*
|
||||||
|
* @param[out] out The output g1 point
|
||||||
|
* @param[in] b The proof/commitment bytes
|
||||||
|
* @retval C_KZG_OK Deserialization successful
|
||||||
|
* @retval C_KZG_BADARGS Invalid input bytes
|
||||||
|
*
|
||||||
|
* @remark This function deviates from the spec because it returns (via an
|
||||||
|
* output argument) the g1 point. This way is more efficient (faster) but
|
||||||
|
* the function name is a bit misleading.
|
||||||
|
*/
|
||||||
|
static C_KZG_RET validate_kzg_g1(g1_t *out, const Bytes48 *b) {
|
||||||
|
/* Convert the bytes to a p1 point */
|
||||||
|
blst_p1_affine p1_affine;
|
||||||
|
if (blst_p1_uncompress(&p1_affine, b->bytes) != BLST_SUCCESS)
|
||||||
|
return C_KZG_BADARGS;
|
||||||
|
blst_p1_from_affine(out, &p1_affine);
|
||||||
|
|
||||||
|
/* Check if it's the point at infinity */
|
||||||
|
if (blst_p1_is_inf(out))
|
||||||
|
return C_KZG_OK;
|
||||||
|
|
||||||
|
/* Key validation */
|
||||||
|
if (!blst_p1_on_curve(out))
|
||||||
|
return C_KZG_BADARGS;
|
||||||
|
if (!blst_p1_in_g1(out))
|
||||||
|
return C_KZG_BADARGS;
|
||||||
|
|
||||||
|
return C_KZG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert untrusted bytes into a trusted and validated KZGCommitment.
|
||||||
|
*
|
||||||
|
* @param[out] out The output commitment
|
||||||
|
* @param[in] b The commitment bytes
|
||||||
|
* @retval C_KZG_OK Deserialization successful
|
||||||
|
* @retval C_KZG_BADARGS Invalid input bytes
|
||||||
|
*/
|
||||||
|
static C_KZG_RET bytes_to_kzg_commitment(g1_t *out, const Bytes48 *b) {
|
||||||
|
return validate_kzg_g1(out, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert untrusted bytes into a trusted and validated KZGProof.
|
||||||
|
*
|
||||||
|
* @param[out] out The output proof
|
||||||
|
* @param[in] b The proof bytes
|
||||||
|
* @retval C_KZG_OK Deserialization successful
|
||||||
|
* @retval C_KZG_BADARGS Invalid input bytes
|
||||||
|
*/
|
||||||
|
static C_KZG_RET bytes_to_kzg_proof(g1_t *out, const Bytes48 *b) {
|
||||||
|
return validate_kzg_g1(out, b);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserialize a Blob (array of bytes) into a Polynomial (array of field elements).
|
* Deserialize a Blob (array of bytes) into a Polynomial (array of field elements).
|
||||||
*
|
*
|
||||||
|
@ -686,7 +724,7 @@ static C_KZG_RET compute_challenges(fr_t *eval_challenge_out, fr_t *r_powers_out
|
||||||
uint8_t* bytes = calloc(nb, sizeof(uint8_t));
|
uint8_t* bytes = calloc(nb, sizeof(uint8_t));
|
||||||
if (bytes == NULL) return C_KZG_MALLOC;
|
if (bytes == NULL) return C_KZG_MALLOC;
|
||||||
|
|
||||||
/* Copy domain seperator */
|
/* Copy domain separator */
|
||||||
memcpy(bytes, FIAT_SHAMIR_PROTOCOL_DOMAIN, 16);
|
memcpy(bytes, FIAT_SHAMIR_PROTOCOL_DOMAIN, 16);
|
||||||
bytes_of_uint64(&bytes[16], FIELD_ELEMENTS_PER_BLOB);
|
bytes_of_uint64(&bytes[16], FIELD_ELEMENTS_PER_BLOB);
|
||||||
bytes_of_uint64(&bytes[16 + 8], n);
|
bytes_of_uint64(&bytes[16 + 8], n);
|
||||||
|
@ -694,11 +732,11 @@ static C_KZG_RET compute_challenges(fr_t *eval_challenge_out, fr_t *r_powers_out
|
||||||
/* Copy polynomials */
|
/* Copy polynomials */
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
for (j = 0; j < FIELD_ELEMENTS_PER_BLOB; j++)
|
for (j = 0; j < FIELD_ELEMENTS_PER_BLOB; j++)
|
||||||
bytes_from_bls_field(&bytes[ni + BYTES_PER_FIELD_ELEMENT * (i * FIELD_ELEMENTS_PER_BLOB + j)], &polys[i].evals[j]);
|
bytes_from_bls_field((Bytes32 *)&bytes[ni + BYTES_PER_FIELD_ELEMENT * (i * FIELD_ELEMENTS_PER_BLOB + j)], &polys[i].evals[j]);
|
||||||
|
|
||||||
/* Copy commitments */
|
/* Copy commitments */
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
bytes_from_g1(&bytes[np + i * 48], &comms[i]);
|
bytes_from_g1((Bytes48 *)&bytes[np + i * 48], &comms[i]);
|
||||||
|
|
||||||
/* Now let's create challenges! */
|
/* Now let's create challenges! */
|
||||||
uint8_t hashed_data[32] = {0};
|
uint8_t hashed_data[32] = {0};
|
||||||
|
@ -758,7 +796,7 @@ static C_KZG_RET g1_lincomb(g1_t *out, const g1_t *p, const fr_t *coeffs, const
|
||||||
if (len < 8) {
|
if (len < 8) {
|
||||||
// Direct approach
|
// Direct approach
|
||||||
g1_t tmp;
|
g1_t tmp;
|
||||||
*out = g1_identity;
|
*out = G1_IDENTITY;
|
||||||
for (uint64_t i = 0; i < len; i++) {
|
for (uint64_t i = 0; i < len; i++) {
|
||||||
g1_mul(&tmp, &p[i], &coeffs[i]);
|
g1_mul(&tmp, &p[i], &coeffs[i]);
|
||||||
blst_p1_add_or_double(out, out, &tmp);
|
blst_p1_add_or_double(out, out, &tmp);
|
||||||
|
@ -898,7 +936,6 @@ out:
|
||||||
// KZG Functions
|
// KZG Functions
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute a KZG commitment from a polynomial.
|
* Compute a KZG commitment from a polynomial.
|
||||||
*
|
*
|
||||||
|
@ -930,7 +967,7 @@ C_KZG_RET blob_to_kzg_commitment(KZGCommitment *out, const Blob *blob, const KZG
|
||||||
if (ret != C_KZG_OK) return ret;
|
if (ret != C_KZG_OK) return ret;
|
||||||
ret = poly_to_kzg_commitment(&commitment, &p, s);
|
ret = poly_to_kzg_commitment(&commitment, &p, s);
|
||||||
if (ret != C_KZG_OK) return ret;
|
if (ret != C_KZG_OK) return ret;
|
||||||
bytes_from_g1((uint8_t *)(out), &commitment);
|
bytes_from_g1(out, &commitment);
|
||||||
return C_KZG_OK;
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,25 +988,25 @@ static C_KZG_RET verify_kzg_proof_impl(bool *out, const g1_t *commitment, const
|
||||||
* @retval C_KZG_BADARGS Invalid inputs
|
* @retval C_KZG_BADARGS Invalid inputs
|
||||||
*/
|
*/
|
||||||
C_KZG_RET verify_kzg_proof(bool *out,
|
C_KZG_RET verify_kzg_proof(bool *out,
|
||||||
const KZGCommitment *commitment,
|
const Bytes48 *commitment_bytes,
|
||||||
const Bytes32 *z,
|
const Bytes32 *z_bytes,
|
||||||
const Bytes32 *y,
|
const Bytes32 *y_bytes,
|
||||||
const KZGProof *kzg_proof,
|
const Bytes48 *proof_bytes,
|
||||||
const KZGSettings *s) {
|
const KZGSettings *s) {
|
||||||
C_KZG_RET ret;
|
C_KZG_RET ret;
|
||||||
fr_t frz, fry;
|
fr_t z_fr, y_fr;
|
||||||
g1_t g1commitment, g1proof;
|
g1_t commitment_g1, proof_g1;
|
||||||
|
|
||||||
ret = bytes_to_g1(&g1commitment, commitment->bytes);
|
ret = bytes_to_kzg_commitment(&commitment_g1, commitment_bytes);
|
||||||
if (ret != C_KZG_OK) return ret;
|
if (ret != C_KZG_OK) return ret;
|
||||||
ret = bytes_to_bls_field(&frz, z);
|
ret = bytes_to_bls_field(&z_fr, z_bytes);
|
||||||
if (ret != C_KZG_OK) return ret;
|
if (ret != C_KZG_OK) return ret;
|
||||||
ret = bytes_to_bls_field(&fry, y);
|
ret = bytes_to_bls_field(&y_fr, y_bytes);
|
||||||
if (ret != C_KZG_OK) return ret;
|
if (ret != C_KZG_OK) return ret;
|
||||||
ret = bytes_to_g1(&g1proof, kzg_proof->bytes);
|
ret = bytes_to_kzg_proof(&proof_g1, proof_bytes);
|
||||||
if (ret != C_KZG_OK) return ret;
|
if (ret != C_KZG_OK) return ret;
|
||||||
|
|
||||||
return verify_kzg_proof_impl(out, &g1commitment, &frz, &fry, &g1proof, s);
|
return verify_kzg_proof_impl(out, &commitment_g1, &z_fr, &y_fr, &proof_g1, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -989,12 +1026,12 @@ static C_KZG_RET verify_kzg_proof_impl(bool *out, const g1_t *commitment, const
|
||||||
const g1_t *proof, const KZGSettings *ks) {
|
const g1_t *proof, const KZGSettings *ks) {
|
||||||
g2_t x_g2, s_minus_x;
|
g2_t x_g2, s_minus_x;
|
||||||
g1_t y_g1, commitment_minus_y;
|
g1_t y_g1, commitment_minus_y;
|
||||||
g2_mul(&x_g2, &g2_generator, z);
|
g2_mul(&x_g2, &G2_GENERATOR, z);
|
||||||
g2_sub(&s_minus_x, &ks->g2_values[1], &x_g2);
|
g2_sub(&s_minus_x, &ks->g2_values[1], &x_g2);
|
||||||
g1_mul(&y_g1, &g1_generator, y);
|
g1_mul(&y_g1, &G1_GENERATOR, y);
|
||||||
g1_sub(&commitment_minus_y, commitment, &y_g1);
|
g1_sub(&commitment_minus_y, commitment, &y_g1);
|
||||||
|
|
||||||
*out = pairings_verify(&commitment_minus_y, &g2_generator, proof, &s_minus_x);
|
*out = pairings_verify(&commitment_minus_y, &G2_GENERATOR, proof, &s_minus_x);
|
||||||
|
|
||||||
return C_KZG_OK;
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
@ -1012,14 +1049,14 @@ C_KZG_RET compute_kzg_proof_impl(KZGProof *out, const Polynomial *polynomial, co
|
||||||
* @retval C_KZG_OK All is well
|
* @retval C_KZG_OK All is well
|
||||||
* @retval C_KZG_MALLOC Memory allocation failed
|
* @retval C_KZG_MALLOC Memory allocation failed
|
||||||
*/
|
*/
|
||||||
C_KZG_RET compute_kzg_proof(KZGProof *out, const Blob *blob, const Bytes32 *z, const KZGSettings *s) {
|
C_KZG_RET compute_kzg_proof(KZGProof *out, const Blob *blob, const Bytes32 *z_bytes, const KZGSettings *s) {
|
||||||
C_KZG_RET ret;
|
C_KZG_RET ret;
|
||||||
Polynomial polynomial;
|
Polynomial polynomial;
|
||||||
fr_t frz;
|
fr_t frz;
|
||||||
|
|
||||||
ret = blob_to_polynomial(&polynomial, blob);
|
ret = blob_to_polynomial(&polynomial, blob);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
ret = bytes_to_bls_field(&frz, z);
|
ret = bytes_to_bls_field(&frz, z_bytes);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
ret = compute_kzg_proof_impl(out, &polynomial, &frz, s);
|
ret = compute_kzg_proof_impl(out, &polynomial, &frz, s);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
|
@ -1096,7 +1133,7 @@ C_KZG_RET compute_kzg_proof_impl(KZGProof *out, const Polynomial *polynomial, co
|
||||||
ret = g1_lincomb(&out_g1, s->g1_values, (const fr_t *)(&q.evals), FIELD_ELEMENTS_PER_BLOB);
|
ret = g1_lincomb(&out_g1, s->g1_values, (const fr_t *)(&q.evals), FIELD_ELEMENTS_PER_BLOB);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
|
|
||||||
bytes_from_g1(out->bytes, &out_g1);
|
bytes_from_g1(out, &out_g1);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(inverses_in);
|
free(inverses_in);
|
||||||
|
@ -1209,16 +1246,16 @@ out:
|
||||||
*/
|
*/
|
||||||
C_KZG_RET verify_aggregate_kzg_proof(bool *out,
|
C_KZG_RET verify_aggregate_kzg_proof(bool *out,
|
||||||
const Blob *blobs,
|
const Blob *blobs,
|
||||||
const KZGCommitment *expected_kzg_commitments,
|
const Bytes48 *commitments_bytes,
|
||||||
size_t n,
|
size_t n,
|
||||||
const KZGProof *kzg_aggregated_proof,
|
const Bytes48 *aggregated_proof_bytes,
|
||||||
const KZGSettings *s) {
|
const KZGSettings *s) {
|
||||||
C_KZG_RET ret;
|
C_KZG_RET ret;
|
||||||
g1_t* commitments = NULL;
|
g1_t* commitments = NULL;
|
||||||
Polynomial* polys = NULL;
|
Polynomial* polys = NULL;
|
||||||
|
|
||||||
g1_t proof;
|
g1_t proof;
|
||||||
ret = bytes_to_g1(&proof, kzg_aggregated_proof->bytes);
|
ret = bytes_to_kzg_proof(&proof, aggregated_proof_bytes);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
|
|
||||||
commitments = calloc(n, sizeof(g1_t));
|
commitments = calloc(n, sizeof(g1_t));
|
||||||
|
@ -1234,7 +1271,7 @@ C_KZG_RET verify_aggregate_kzg_proof(bool *out,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
ret = bytes_to_g1(&commitments[i], expected_kzg_commitments[i].bytes);
|
ret = bytes_to_kzg_commitment(&commitments[i], &commitments_bytes[i]);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
ret = blob_to_polynomial(&polys[i], &blobs[i]);
|
ret = blob_to_polynomial(&polys[i], &blobs[i]);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
|
@ -1383,8 +1420,8 @@ static C_KZG_RET new_fft_settings(FFTSettings *fs, unsigned int max_scale) {
|
||||||
fs->reverse_roots_of_unity = NULL;
|
fs->reverse_roots_of_unity = NULL;
|
||||||
fs->roots_of_unity = NULL;
|
fs->roots_of_unity = NULL;
|
||||||
|
|
||||||
CHECK((max_scale < sizeof scale2_root_of_unity / sizeof scale2_root_of_unity[0]));
|
CHECK((max_scale < sizeof SCALE2_ROOT_OF_UNITY / sizeof SCALE2_ROOT_OF_UNITY[0]));
|
||||||
blst_fr_from_uint64(&root_of_unity, scale2_root_of_unity[max_scale]);
|
blst_fr_from_uint64(&root_of_unity, SCALE2_ROOT_OF_UNITY[max_scale]);
|
||||||
|
|
||||||
// Allocate space for the roots of unity
|
// Allocate space for the roots of unity
|
||||||
ret = new_fr_array(&fs->expanded_roots_of_unity, fs->max_width + 1);
|
ret = new_fr_array(&fs->expanded_roots_of_unity, fs->max_width + 1);
|
||||||
|
@ -1474,7 +1511,7 @@ C_KZG_RET load_trusted_setup(KZGSettings *out, const uint8_t *g1_bytes, size_t n
|
||||||
if (ret != C_KZG_OK) goto out_error;
|
if (ret != C_KZG_OK) goto out_error;
|
||||||
|
|
||||||
for (i = 0; i < n1; i++) {
|
for (i = 0; i < n1; i++) {
|
||||||
ret = bytes_to_g1(&g1_projective[i], &g1_bytes[48 * i]);
|
ret = validate_kzg_g1(&g1_projective[i], (Bytes48 *)&g1_bytes[48 * i]);
|
||||||
if (ret != C_KZG_OK) goto out_error;
|
if (ret != C_KZG_OK) goto out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,12 @@ typedef blst_p2 g2_t; /**< Internal G2 group element type */
|
||||||
typedef blst_fr fr_t; /**< Internal Fr field element type */
|
typedef blst_fr fr_t; /**< Internal Fr field element type */
|
||||||
|
|
||||||
typedef struct { uint8_t bytes[32]; } Bytes32;
|
typedef struct { uint8_t bytes[32]; } Bytes32;
|
||||||
typedef struct { uint8_t bytes[BYTES_PER_COMMITMENT]; } KZGCommitment;
|
typedef struct { uint8_t bytes[48]; } Bytes48;
|
||||||
typedef struct { uint8_t bytes[BYTES_PER_PROOF]; } KZGProof;
|
|
||||||
typedef struct { uint8_t bytes[BYTES_PER_BLOB]; } Blob;
|
typedef struct { uint8_t bytes[BYTES_PER_BLOB]; } Blob;
|
||||||
|
|
||||||
|
typedef Bytes48 KZGCommitment;
|
||||||
|
typedef Bytes48 KZGProof;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The common return type for all routines in which something can go wrong.
|
* The common return type for all routines in which something can go wrong.
|
||||||
*/
|
*/
|
||||||
|
@ -101,9 +103,9 @@ C_KZG_RET compute_aggregate_kzg_proof(KZGProof *out,
|
||||||
|
|
||||||
C_KZG_RET verify_aggregate_kzg_proof(bool *out,
|
C_KZG_RET verify_aggregate_kzg_proof(bool *out,
|
||||||
const Blob *blobs,
|
const Blob *blobs,
|
||||||
const KZGCommitment *expected_kzg_commitments,
|
const Bytes48 *commitments_bytes,
|
||||||
size_t n,
|
size_t n,
|
||||||
const KZGProof *kzg_aggregated_proof,
|
const Bytes48 *aggregated_proof_bytes,
|
||||||
const KZGSettings *s);
|
const KZGSettings *s);
|
||||||
|
|
||||||
C_KZG_RET blob_to_kzg_commitment(KZGCommitment *out,
|
C_KZG_RET blob_to_kzg_commitment(KZGCommitment *out,
|
||||||
|
@ -111,15 +113,15 @@ C_KZG_RET blob_to_kzg_commitment(KZGCommitment *out,
|
||||||
const KZGSettings *s);
|
const KZGSettings *s);
|
||||||
|
|
||||||
C_KZG_RET verify_kzg_proof(bool *out,
|
C_KZG_RET verify_kzg_proof(bool *out,
|
||||||
const KZGCommitment *polynomial_kzg,
|
const Bytes48 *commitment_bytes,
|
||||||
const Bytes32 *z,
|
const Bytes32 *z_bytes,
|
||||||
const Bytes32 *y,
|
const Bytes32 *y_bytes,
|
||||||
const KZGProof *kzg_proof,
|
const Bytes48 *proof_bytes,
|
||||||
const KZGSettings *s);
|
const KZGSettings *s);
|
||||||
|
|
||||||
C_KZG_RET compute_kzg_proof(KZGProof *out,
|
C_KZG_RET compute_kzg_proof(KZGProof *out,
|
||||||
const Blob *p,
|
const Blob *blobs,
|
||||||
const Bytes32 *z,
|
const Bytes32 *z_bytes,
|
||||||
const KZGSettings *s);
|
const KZGSettings *s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue