Add C# wrapper & YAML tests (#46)

This commit is contained in:
Alexey 2023-03-07 00:46:00 +03:00 committed by GitHub
parent 410eed4db6
commit 7c0bd867d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 691 additions and 419 deletions

View File

@ -1,11 +1,17 @@
name: C# bindings test and build
on:
workflow_dispatch:
inputs:
version:
description: "Binding version override"
push:
branches:
- main
pull_request:
branches:
- main
env:
binding_build_number_based_version: 0.1.1.${{ github.run_number }}
jobs:
build-ckzg:
@ -13,29 +19,48 @@ jobs:
strategy:
matrix:
target:
- native: linux-x64
host: ubuntu-latest
- native: linux-arm64
host: ubuntu-latest
- native: osx-arm64
- arch: x86_64-linux-gnu
location: linux-x64
host: ubuntu-22.04
ext: .so
reqs:
- arch: aarch64-linux-gnu
location: linux-arm64
host: ubuntu-22.04
ext: .so
reqs: sudo apt install -y clang binutils-aarch64-linux-gnu libc6-arm64-cross libc6-dev-arm64-cross crossbuild-essential-arm64
- arch: arm64-darwin
location: osx-arm64
host: macos-latest
- native: osx-x64
ext: .so
reqs:
- arch: x86_64-darwin
location: osx-x64
host: macos-latest
- native: win-x64
ext: .so
reqs:
#TODO: support arch: x86_64-v2-win
- arch:
location: win-x64
host: windows-latest
ext: .dll
reqs:
steps:
- uses: ilammy/msvc-dev-cmd@v1
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Build native library for ${{ matrix.target.native }}
run: cd bindings/csharp && make -B ckzg CSHARP_PLATFORM=${{ matrix.target.native }}
- name: Install requirements
if: ${{ matrix.target.reqs }}
run: ${{ matrix.target.reqs }}
- name: Build native library for ${{ matrix.target.location }} using native capabilities
run: make ckzg -C bindings/csharp CC=clang EXTENSION=${{matrix.target.ext}} LOCATION=${{matrix.target.location}} ARCH=${{matrix.target.arch}}
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: ckzg-library-${{ matrix.target.native }}
path: bindings/csharp/Ckzg.Bindings/runtimes/${{ matrix.target.native }}/native
name: ckzg-library-wrapper-${{ matrix.target.location }}
path: bindings/csharp/Ckzg.Bindings/runtimes/${{ matrix.target.location }}/native
build-ckzg-dotnet:
runs-on: ubuntu-latest
needs: build-ckzg
@ -43,37 +68,35 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: ckzg-library-linux-x64
name: ckzg-library-wrapper-linux-x64
path: bindings/csharp/Ckzg.Bindings/runtimes/linux-x64/native
- uses: actions/download-artifact@v3
with:
name: ckzg-library-osx-x64
name: ckzg-library-wrapper-osx-x64
path: bindings/csharp/Ckzg.Bindings/runtimes/osx-x64/native
- uses: actions/download-artifact@v3
with:
name: ckzg-library-win-x64
name: ckzg-library-wrapper-win-x64
path: bindings/csharp/Ckzg.Bindings/runtimes/win-x64/native
- uses: actions/download-artifact@v3
with:
name: ckzg-library-osx-arm64
name: ckzg-library-wrapper-osx-arm64
path: bindings/csharp/Ckzg.Bindings/runtimes/osx-arm64/native
- uses: actions/download-artifact@v3
with:
name: ckzg-library-linux-arm64
name: ckzg-library-wrapper-linux-arm64
path: bindings/csharp/Ckzg.Bindings/runtimes/linux-arm64/native
- name: Setup .NET Core SDK ${{ matrix.dotnet-version }}
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Install dependencies
run: cd bindings/csharp && dotnet restore
- name: Test
run: cd bindings/csharp && dotnet test --configuration Release --no-restore
- name: Build
run: cd bindings/csharp && dotnet build -p:Version=0.1.1.${{github.run_number}} --configuration Release --no-restore
run: cd bindings/csharp && dotnet build -p:Version=${{ inputs.version || env.binding_build_number_based_version }} --configuration Release --no-restore
- name: Upload package
uses: actions/upload-artifact@v3
with:
name: Ckzg.Bindings
name: Ckzg.Bindings-${{ inputs.version || env.binding_build_number_based_version }}
path: bindings/csharp/build/Ckzg.Bindings.*.nupkg

View File

@ -0,0 +1,62 @@
using System.Runtime.InteropServices;
using System.Runtime.Loader;
namespace Ckzg;
public static partial class Ckzg
{
static Ckzg()
{
AssemblyLoadContext.Default.ResolvingUnmanagedDll += (_, path) =>
path.Contains("ckzg", StringComparison.OrdinalIgnoreCase)
? NativeLibrary.Load($"runtimes/{(
RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "linux" :
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "osx" :
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win" : "")}-{RuntimeInformation.ProcessArchitecture switch
{
Architecture.X64 => "x64",
Architecture.Arm64 => "arm64",
_ => ""
}}/native/{path}.{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "dll" : "so")}")
: IntPtr.Zero;
}
[DllImport("ckzg", EntryPoint = "load_trusted_setup_wrap")]
private static extern IntPtr InternalLoadTrustedSetup(string filename);
[DllImport("ckzg", EntryPoint = "free_trusted_setup_wrap", CallingConvention = CallingConvention.Cdecl)]
private static extern void InternalFreeTrustedSetup(IntPtr ts);
[DllImport("ckzg", EntryPoint = "blob_to_kzg_commitment", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult BlobToKzgCommitment(byte* commitment, byte* blob, IntPtr ts);
[DllImport("ckzg", EntryPoint = "compute_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult ComputeKzgProof(byte* proof, byte* blob, byte* z, IntPtr ts);
[DllImport("ckzg", EntryPoint = "compute_blob_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult ComputeBlobKzgProof(byte* proof, byte* blob, IntPtr ts);
[DllImport("ckzg", EntryPoint = "verify_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult VerifyKzgProof(out bool result, byte* commitment, byte* z,
byte* y, byte* proof, IntPtr ts);
[DllImport("ckzg", EntryPoint = "verify_blob_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult VerifyBlobKzgProof(out bool result, byte* blob, byte* commitment,
byte* proof, IntPtr ts);
[DllImport("ckzg", EntryPoint = "verify_blob_kzg_proof_batch", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe KzgResult VerifyBlobKzgProofBatch(out bool result, byte* blobs, byte* commitments,
byte* proofs, int count, IntPtr ts);
private enum KzgResult
{
// Success!
Ok,
// The supplied data is invalid in some way.
BadArgs,
// Internal error - this should never occur.
Error,
// Could not allocate memory.
Malloc
}
}

View File

@ -1,32 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Ckzg</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>Ckzg.Bindings</Title>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>0.1.0.0</Version>
</PropertyGroup>
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Ckzg</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>Ckzg.Bindings</Title>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>0.1.0.0</Version>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\..\LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/win-x64/native/ckzg.dll')" Include="runtimes/win-x64/native/ckzg.dll" Pack="true" PackagePath="runtimes/win-x64/native/ckzg.dll" />
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/linux-x64/native/ckzg.so')" Include="runtimes/linux-x64/native/ckzg.so" Pack="true" PackagePath="runtimes/linux-x64/native/ckzg.so" />
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/linux-arm64/native/ckzg.so')" Include="runtimes/linux-arm64/native/ckzg.so" Pack="true" PackagePath="runtimes/linux-arm64/native/ckzg.so" />
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/osx-x64/native/ckzg.so')" Include="runtimes/osx-x64/native/ckzg.so" Pack="true" PackagePath="runtimes/osx-x64/native/ckzg.so" />
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/osx-arm64/native/ckzg.so')" Include="runtimes/osx-arm64/native/ckzg.so" Pack="true" PackagePath="runtimes/osx-arm64/native/ckzg.so" />
</ItemGroup>
<ItemGroup>
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/win-x64/native/ckzg.dll')" Include="runtimes/win-x64/native/ckzg.dll" Pack="true" PackagePath="runtimes/win-x64/native/ckzg.dll"/>
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/linux-x64/native/ckzg.so')" Include="runtimes/linux-x64/native/ckzg.so" Pack="true" PackagePath="runtimes/linux-x64/native/ckzg.so"/>
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/linux-arm64/native/ckzg.so')" Include="runtimes/linux-arm64/native/ckzg.so" Pack="true" PackagePath="runtimes/linux-arm64/native/ckzg.so"/>
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/osx-x64/native/ckzg.so')" Include="runtimes/osx-x64/native/ckzg.so" Pack="true" PackagePath="runtimes/osx-x64/native/ckzg.so"/>
<Content CopyToOutputDirectory="PreserveNewest" Condition="Exists('runtimes/osx-arm64/native/ckzg.so')" Include="runtimes/osx-arm64/native/ckzg.so" Pack="true" PackagePath="runtimes/osx-arm64/native/ckzg.so"/>
</ItemGroup>
</Project>

View File

@ -1,115 +1,222 @@
using System.Runtime.InteropServices;
using System.Runtime.Loader;
namespace Ckzg;
public class Ckzg
public static partial class Ckzg
{
public const int BytesPerFieldElement = 32;
public const int BytesPerBlob = BytesPerFieldElement * 4096;
public const int FieldElementsPerBlob = 4096;
public const int BytesPerBlob = BytesPerFieldElement * FieldElementsPerBlob;
public const int BytesPerCommitment = 48;
public const int BytesPerProof = 48;
public enum Ret
{
Ok,
BadArgs,
Error,
Malloc
}
static Ckzg() => AssemblyLoadContext.Default.ResolvingUnmanagedDll += (assembly, path) => NativeLibrary.Load($"runtimes/{(
RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "linux" :
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "osx" :
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win" : "")}-{RuntimeInformation.ProcessArchitecture switch
{
Architecture.X64 => "x64",
Architecture.Arm64 => "arm64",
_ => ""
}}/native/{path}.{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "dll" : "so")}");
/// <summary>
/// Load trusted setup settings from file
/// Loads trusted setup settings from file.
/// </summary>
/// <param name="filename">Settings file path</param>
/// <returns>Trusted setup settings as a pointer or <c>0</c> in case of failure</returns>
[DllImport("ckzg", EntryPoint = "load_trusted_setup_wrap")]
public static extern IntPtr LoadTrustedSetup(string filename);
/// <exception cref="ArgumentException">Thrown when the file path is not correct </exception>
/// <exception cref="InvalidOperationException">Thrown when unable to load the setup</exception>
/// <returns>Trusted setup settings as a pointer</returns>
public static IntPtr LoadTrustedSetup(string filepath)
{
if (!File.Exists(filepath)) throw new ArgumentException("Trusted setup file does not exist", nameof(filepath));
IntPtr ckzgSetup = InternalLoadTrustedSetup(filepath);
if (ckzgSetup == IntPtr.Zero) throw new InvalidOperationException("Unable to load trusted setup");
return ckzgSetup;
}
/// <summary>
/// Frees memory allocated for trusted setup settings
/// Frees memory allocated for trusted setup settings.
/// </summary>
/// <param name="ts">Trusted setup settings</param>
[DllImport("ckzg", EntryPoint = "free_trusted_setup_wrap", CallingConvention = CallingConvention.Cdecl)]
public static extern void FreeTrustedSetup(IntPtr ts);
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when settings are not correct</exception>
public static void FreeTrustedSetup(IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
InternalFreeTrustedSetup(ckzgSetup);
}
/// <summary>
/// Calculates commitment for the blob
/// Calculates commitment for the blob.
/// </summary>
/// <param name="commitment">Preallocated buffer of <inheritdoc cref="CommitmentLength"/> bytes to receive the commitment</param>
/// <param name="commitment">Preallocated buffer of <inheritdoc cref="CommitmentLength" /> bytes to receive the commitment</param>
/// <param name="blob">Flatten array of blob elements</param>
/// <param name="ts">Trusted setup settings</param>
/// <returns>Returns error code or <c>0</c> if successful</returns>
[DllImport("ckzg", EntryPoint = "blob_to_kzg_commitment", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern Ret BlobToKzgCommitment(byte* commitment, byte* blob, IntPtr ts);
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when length of an argument is not correct or settings are not correct</exception>
/// <exception cref="ApplicationException">Thrown when the library returns unexpected Error code</exception>
/// <exception cref="InsufficientMemoryException">Thrown when the library has no enough memory to process</exception>
public static unsafe void BlobToKzgCommitment(Span<byte> commitment, ReadOnlySpan<byte> blob, IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(blob, nameof(blob), BytesPerBlob);
ThrowOnInvalidLength(commitment, nameof(commitment), BytesPerCommitment);
fixed (byte* commitmentPtr = commitment, blobPtr = blob)
{
KzgResult result = BlobToKzgCommitment(commitmentPtr, blobPtr, ckzgSetup);
ThrowOnError(result);
}
}
/// <summary>
/// Compute KZG proof at point `z` for the polynomial represented by `blob`.
/// Compute KZG proof at point `z` for the polynomial represented by `blob`.
/// </summary>
/// <param name="proof">Preallocated buffer of <inheritdoc cref="ProofLength"/> bytes to receive the proof</param>
/// <param name="blob">Blob byte array</param>
/// <param name="z_bytes"></param>
/// <param name="ts">Trusted setup settings</param>
/// <returns>Returns error code or <c>0</c> if successful</returns>
[DllImport("ckzg", EntryPoint = "compute_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern Ret ComputeKzgProof(byte* proof, byte* blob, byte* z_bytes, IntPtr ts);
/// <param name="proof">Preallocated buffer of <inheritdoc cref="ProofLength" /> bytes to receive the proof</param>
/// <param name="blob">Blob bytes</param>
/// <param name="z">Z point</param>
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when length of an argument is not correct or settings are not correct</exception>
/// <exception cref="ApplicationException">Thrown when the library returns unexpected Error code</exception>
/// <exception cref="InsufficientMemoryException">Thrown when the library has no enough memory to process</exception>
public static unsafe void ComputeKzgProof(Span<byte> proof, ReadOnlySpan<byte> blob, ReadOnlySpan<byte> z,
IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(proof, nameof(proof), BytesPerProof);
ThrowOnInvalidLength(blob, nameof(blob), BytesPerBlob);
ThrowOnInvalidLength(z, nameof(z), BytesPerFieldElement);
if (z.Length != BytesPerFieldElement) throw new ArgumentException("Invalid z size", nameof(z));
fixed (byte* proofPtr = proof, blobPtr = blob, zPtr = z)
{
KzgResult result = ComputeKzgProof(proofPtr, blobPtr, zPtr, ckzgSetup);
ThrowOnError(result);
}
}
/// <summary>
/// Given a blob, return the KZG proof that is used to verify it against the commitment.
/// Given a blob, return the KZG proof that is used to verify it against the commitment.
/// </summary>
/// <param name="proof">Preallocated buffer of <inheritdoc cref="ProofLength"/> bytes to receive the proof</param>
/// <param name="blob">Blob byte array</param>
/// <param name="ts">Trusted setup settings</param>
/// <returns>Returns error code or <c>0</c> if successful</returns>
[DllImport("ckzg", EntryPoint = "compute_blob_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern Ret ComputeBlobKzgProof(byte* proof, byte* blob, IntPtr ts);
/// <param name="proof">Preallocated buffer of <inheritdoc cref="ProofLength" /> bytes to receive the proof</param>
/// <param name="blob">Blob bytes</param>
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when length of an argument is not correct or settings are not correct</exception>
/// <exception cref="ApplicationException">Thrown when the library returns unexpected Error code</exception>
/// <exception cref="InsufficientMemoryException">Thrown when the library has no enough memory to process</exception>
public static unsafe void ComputeBlobKzgProof(Span<byte> proof, ReadOnlySpan<byte> blob, IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(proof, nameof(proof), BytesPerProof);
ThrowOnInvalidLength(blob, nameof(blob), BytesPerBlob);
fixed (byte* proofPtr = proof, blobPtr = blob)
{
KzgResult result = ComputeBlobKzgProof(proofPtr, blobPtr, ckzgSetup);
ThrowOnError(result);
}
}
/// <summary>
///
/// Given a blob and a KZG proof, verify that the blob data corresponds to the provided commitment.
/// </summary>
/// <param name="result">True if the proof is valid</param>
/// <param name="commitment_bytes"></param>
/// <param name="z_bytes"></param>
/// <param name="y_bytes"></param>
/// <param name="proof_bytes"></param>
/// <param name="ts">Trusted setup settings</param>
/// <returns></returns>
[DllImport("ckzg", EntryPoint = "verify_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern Ret VerifyKzgProof(bool* result, byte* commitment_bytes, byte* z_bytes, byte* y_bytes, byte* proof_bytes, IntPtr ts);
/// <summary>
/// Given a blob and a KZG proof, verify that the blob data corresponds to the provided commitment.
/// </summary>
/// <param name="result">True if the proof is valid</param>
/// <param name="blob"></param>
/// <param name="commitment"></param>
/// <param name="proof"></param>
/// <param name="ts">Trusted setup settings</param>
/// <returns></returns>
[DllImport("ckzg", EntryPoint = "verify_blob_kzg_proof", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern Ret VerifyBlobKzgProof(bool* result, byte* blob, byte* commitment_bytes, byte* proof_bytes, IntPtr ts);
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when length of an argument is not correct or settings are not correct</exception>
/// <exception cref="ApplicationException">Thrown when the library returns unexpected Error code</exception>
/// <exception cref="InsufficientMemoryException">Thrown when the library has no enough memory to process</exception>
/// <returns>Verification result</returns>
public static unsafe bool VerifyKzgProof(ReadOnlySpan<byte> commitment, ReadOnlySpan<byte> z, ReadOnlySpan<byte> y,
ReadOnlySpan<byte> proof, IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(commitment, nameof(commitment), BytesPerCommitment);
ThrowOnInvalidLength(z, nameof(z), BytesPerFieldElement);
ThrowOnInvalidLength(y, nameof(y), BytesPerFieldElement);
ThrowOnInvalidLength(proof, nameof(proof), BytesPerProof);
fixed (byte* commitmentPtr = commitment, zPtr = z, yPtr = y, proofPtr = proof)
{
KzgResult kzgResult = VerifyKzgProof(out var result, commitmentPtr, zPtr, yPtr, proofPtr, ckzgSetup);
ThrowOnError(kzgResult);
return result;
}
}
/// <summary>
/// Given a list of blobs and blob KZG proofs, verify that they correspond to the provided commitments.
/// Given a blob and a KZG proof, verify that the blob data corresponds to the provided commitment.
/// </summary>
/// <param name="blob">Blob bytes</param>
/// <param name="commitment">Commitment bytes</param>
/// <param name="proof">Proof bytes</param>
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when length of an argument is not correct or settings are not correct</exception>
/// <exception cref="ApplicationException">Thrown when the library returns unexpected Error code</exception>
/// <exception cref="InsufficientMemoryException">Thrown when the library has no enough memory to process</exception>
/// <returns>Verification result</returns>
public static unsafe bool VerifyBlobKzgProof(ReadOnlySpan<byte> blob, ReadOnlySpan<byte> commitment,
ReadOnlySpan<byte> proof, IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(blob, nameof(blob), BytesPerBlob);
ThrowOnInvalidLength(commitment, nameof(proof), BytesPerCommitment);
ThrowOnInvalidLength(proof, nameof(proof), BytesPerProof);
fixed (byte* blobPtr = blob, commitmentPtr = commitment, proofPtr = proof)
{
KzgResult kzgResult = VerifyBlobKzgProof(out var result, blobPtr, commitmentPtr, proofPtr, ckzgSetup);
ThrowOnError(kzgResult);
return result;
}
}
/// <summary>
/// Given a list of blobs and blob KZG proofs, verify that they correspond to the provided commitments.
/// </summary>
/// <param name="result">True if the proofs are valid</param>
/// <param name="blobs">Blobs as a flattened byte array</param>
/// <param name="commitments">Commitments as a flattened byte array</param>
/// <param name="proofs">Proofs as a flattened byte array</param>
/// <param name="count">The number of blobs/commitments/proofs</param>
/// <param name="ts">Trusted setup settings</param>
/// <returns></returns>
[DllImport("ckzg", EntryPoint = "verify_blob_kzg_proof_batch", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern Ret VerifyBlobKzgProofBatch(bool* result, byte* blobs, byte* commitments_bytes, byte* proofs_bytes, int count, IntPtr ts);
}
/// <param name="ckzgSetup">Trusted setup settings</param>
/// <exception cref="ArgumentException">Thrown when length of an argument is not correct or settings are not correct</exception>
/// <exception cref="ApplicationException">Thrown when the library returns unexpected Error code</exception>
/// <exception cref="InsufficientMemoryException">Thrown when the library has no enough memory to process</exception>
/// <returns>Verification result</returns>
public static unsafe bool VerifyBlobKzgProofBatch(ReadOnlySpan<byte> blobs, ReadOnlySpan<byte> commitments,
ReadOnlySpan<byte> proofs, int count, IntPtr ckzgSetup)
{
ThrowOnUninitializedTrustedSetup(ckzgSetup);
ThrowOnInvalidLength(blobs, nameof(blobs), BytesPerBlob * count);
ThrowOnInvalidLength(commitments, nameof(proofs), BytesPerCommitment * count);
ThrowOnInvalidLength(proofs, nameof(proofs), BytesPerProof * count);
fixed (byte* blobsPtr = blobs, commitmentsPtr = commitments, proofsPtr = proofs)
{
KzgResult kzgResult =
VerifyBlobKzgProofBatch(out var result, blobsPtr, commitmentsPtr, proofsPtr, count, ckzgSetup);
ThrowOnError(kzgResult);
return result;
}
}
#region Argument verification helpers
private static void ThrowOnError(KzgResult result)
{
switch (result)
{
case KzgResult.BadArgs: throw new ArgumentException();
case KzgResult.Malloc: throw new InsufficientMemoryException();
case KzgResult.Ok:
return;
default:
throw new ApplicationException("KZG returned unexpected result");
}
}
private static void ThrowOnUninitializedTrustedSetup(IntPtr ckzgSetup)
{
if (ckzgSetup == IntPtr.Zero)
throw new ArgumentException("Trusted setup is not initialized", nameof(ckzgSetup));
}
private static void ThrowOnInvalidLength(ReadOnlySpan<byte> data, string fieldName, int expectedLength)
{
if (data.Length != expectedLength)
throw new ArgumentException("Invalid data size", fieldName);
}
#endregion
}

View File

@ -1,29 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="YamlDotNet" Version="13.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ckzg.Bindings\Ckzg.Bindings.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ckzg.Bindings\Ckzg.Bindings.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\src\trusted_setup.txt" Link="trusted_setup.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\src\trusted_setup.txt" Link="trusted_setup.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -1,218 +0,0 @@
using NUnit.Framework;
using System.IO;
namespace Ckzg.Test;
[TestFixture]
public class BasicKzgTests
{
private IntPtr ts;
const string TestDir = "../../../../../../tests";
string BlobToKZGCommitmentTests = Path.Join(TestDir, "blob_to_kzg_commitment");
string ComputeKzgProofTests = Path.Join(TestDir, "compute_kzg_proof");
string ComputeBlobKzgProofTests = Path.Join(TestDir, "compute_blob_kzg_proof");
string VerifyKzgProofTests = Path.Join(TestDir, "verify_kzg_proof");
string VerifyBlobKzgProofTests = Path.Join(TestDir, "verify_blob_kzg_proof");
string VerifyBlobKzgProofBatchTests = Path.Join(TestDir, "verify_blob_kzg_proof_batch");
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static byte[] GetBytes(String path)
{
string hex = System.IO.File.ReadAllText(path);
return StringToByteArray(hex);
}
public static byte[] GetFlatBytes(String path)
{
List<String> files = Directory.GetFiles(path).ToList();
files.Sort();
List<byte[]> filesBytes = new List<byte[]>();
foreach (String file in files)
{
filesBytes.Add(GetBytes(file));
}
byte[] flatBytes = new byte[filesBytes.Sum(b => b.Length)];
int offset = 0;
foreach (byte[] bytes in filesBytes)
{
System.Buffer.BlockCopy(bytes, 0, flatBytes, offset, bytes.Length);
offset += bytes.Length;
}
return flatBytes;
}
public static bool GetBoolean(String path)
{
return System.IO.File.ReadAllText(path).Contains("true");
}
[SetUp]
public void Setup()
{
ts = Ckzg.LoadTrustedSetup("trusted_setup.txt");
Assert.That(ts, Is.Not.EqualTo(IntPtr.Zero));
}
[TearDown]
public void Teardown()
{
Ckzg.FreeTrustedSetup(ts);
}
[TestCase]
public unsafe void TestBlobToKzgCommitment()
{
foreach (String test in Directory.GetDirectories(BlobToKZGCommitmentTests))
{
byte[] commitment = new byte[48];
byte[] blob = GetBytes(Path.Join(test, "blob.txt"));
fixed (byte *pCommitment = commitment, pBlob = blob)
{
Ckzg.Ret ret = Ckzg.BlobToKzgCommitment(pCommitment, pBlob, ts);
if (ret == Ckzg.Ret.Ok)
{
byte[] expectedCommitment = GetBytes(Path.Join(test, "commitment.txt"));
Assert.That(commitment, Is.EqualTo(expectedCommitment));
}
else
{
Assert.False(System.IO.File.Exists(Path.Join(test, "commitment.txt")));
}
}
}
}
[TestCase]
public unsafe void TestComputeKzgProof()
{
foreach (String test in Directory.GetDirectories(ComputeKzgProofTests))
{
byte[] proof = new byte[48];
byte[] blob = GetBytes(Path.Join(test, "blob.txt"));
byte[] inputPoint = GetBytes(Path.Join(test, "input_point.txt"));
fixed (byte *pProof = proof, pBlob = blob, pInputPoint = inputPoint)
{
Ckzg.Ret ret = Ckzg.ComputeKzgProof(pProof, pBlob, pInputPoint, ts);
if (ret == Ckzg.Ret.Ok)
{
byte[] expectedProof = GetBytes(Path.Join(test, "proof.txt"));
Assert.That(proof, Is.EqualTo(expectedProof));
}
else
{
Assert.False(System.IO.File.Exists(Path.Join(test, "proof.txt")));
}
}
}
}
[TestCase]
public unsafe void TestComputeBlobKzgProof()
{
foreach (String test in Directory.GetDirectories(ComputeBlobKzgProofTests))
{
byte[] proof = new byte[48];
byte[] blob = GetBytes(Path.Join(test, "blob.txt"));
fixed (byte *pProof = proof, pBlob = blob)
{
Ckzg.Ret ret = Ckzg.ComputeBlobKzgProof(pProof, pBlob, ts);
if (ret == Ckzg.Ret.Ok)
{
byte[] expectedProof = GetBytes(Path.Join(test, "proof.txt"));
Assert.That(proof, Is.EqualTo(expectedProof));
}
else
{
Assert.False(System.IO.File.Exists(Path.Join(test, "proof.txt")));
}
}
}
}
[TestCase]
public unsafe void TestVerifyKzgProof()
{
foreach (String test in Directory.GetDirectories(VerifyKzgProofTests))
{
bool ok = false;
byte[] commitment = GetBytes(Path.Join(test, "commitment.txt"));
byte[] inputPoint = GetBytes(Path.Join(test, "input_point.txt"));
byte[] claimedValue = GetBytes(Path.Join(test, "claimed_value.txt"));
byte[] proof = GetBytes(Path.Join(test, "proof.txt"));
fixed (byte *pCommitment = commitment, pInputPoint = inputPoint, pClaimedValue = claimedValue, pProof = proof)
{
Ckzg.Ret ret = Ckzg.VerifyKzgProof(&ok, pCommitment, pInputPoint, pClaimedValue, pProof, ts);
if (ret == Ckzg.Ret.Ok)
{
bool expectedOk = GetBoolean(Path.Join(test, "ok.txt"));
Assert.That(ok, Is.EqualTo(expectedOk));
}
else
{
Assert.False(System.IO.File.Exists(Path.Join(test, "ok.txt")));
}
}
}
}
[TestCase]
public unsafe void TestVerifyBlobKzgProof()
{
foreach (String test in Directory.GetDirectories(VerifyBlobKzgProofTests))
{
bool ok = false;
byte[] blob = GetBytes(Path.Join(test, "blob.txt"));
byte[] commitment = GetBytes(Path.Join(test, "commitment.txt"));
byte[] proof = GetBytes(Path.Join(test, "proof.txt"));
fixed (byte *pBlob = blob, pCommitment = commitment, pProof = proof)
{
Ckzg.Ret ret = Ckzg.VerifyBlobKzgProof(&ok, pBlob, pCommitment, pProof, ts);
if (ret == Ckzg.Ret.Ok)
{
bool expectedOk = GetBoolean(Path.Join(test, "ok.txt"));
Assert.That(ok, Is.EqualTo(expectedOk));
}
else
{
Assert.False(System.IO.File.Exists(Path.Join(test, "ok.txt")));
}
}
}
}
[TestCase]
public unsafe void TestVerifyBlobKzgProofBatch()
{
foreach (String test in Directory.GetDirectories(VerifyBlobKzgProofBatchTests))
{
bool ok = false;
byte[] blobs = GetFlatBytes(Path.Join(test, "blobs"));
byte[] commitments = GetFlatBytes(Path.Join(test, "commitments"));
byte[] proofs = GetFlatBytes(Path.Join(test, "proofs"));
int count = blobs.Length / Ckzg.BytesPerBlob;
fixed (byte *pBlobs = blobs, pCommitments = commitments, pProofs = proofs)
{
Ckzg.Ret ret = Ckzg.VerifyBlobKzgProofBatch(&ok, pBlobs, pCommitments, pProofs, count, ts);
if (ret == Ckzg.Ret.Ok)
{
bool expectedOk = GetBoolean(Path.Join(test, "ok.txt"));
Assert.That(ok, Is.EqualTo(expectedOk));
}
else
{
Assert.False(System.IO.File.Exists(Path.Join(test, "ok.txt")));
}
}
}
}
}

View File

@ -0,0 +1,337 @@
using Microsoft.Extensions.FileSystemGlobbing;
using NUnit.Framework;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace Ckzg.Test;
[TestFixture]
public class ReferenceTests
{
[OneTimeSetUp]
public void Setup()
{
_ts = Ckzg.LoadTrustedSetup("trusted_setup.txt");
_deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
}
[OneTimeTearDown]
public void Teardown()
{
Ckzg.FreeTrustedSetup(_ts);
}
[TestCase]
public void TestSetupLoaded()
{
Assert.That(_ts, Is.Not.EqualTo(IntPtr.Zero));
}
private IntPtr _ts;
private const string TestDir = "../../../../../../tests";
private readonly string _blobToKzgCommitmentTests = Path.Join(TestDir, "blob_to_kzg_commitment");
private readonly string _computeKzgProofTests = Path.Join(TestDir, "compute_kzg_proof");
private readonly string _computeBlobKzgProofTests = Path.Join(TestDir, "compute_blob_kzg_proof");
private readonly string _verifyKzgProofTests = Path.Join(TestDir, "verify_kzg_proof");
private readonly string _verifyBlobKzgProofTests = Path.Join(TestDir, "verify_blob_kzg_proof");
private readonly string _verifyBlobKzgProofBatchTests = Path.Join(TestDir, "verify_blob_kzg_proof_batch");
private IDeserializer _deserializer;
#region Helper Functions
private static byte[] GetBytes(string hex)
{
return Convert.FromHexString(hex[2..]);
}
private static byte[] GetFlatBytes(List<string> strings)
{
List<byte[]> stringBytes = strings.Select(GetBytes).ToList();
byte[] flatBytes = new byte[stringBytes.Sum(b => b.Length)];
int offset = 0;
foreach (byte[] bytes in stringBytes)
{
Buffer.BlockCopy(bytes, 0, flatBytes, offset, bytes.Length);
offset += bytes.Length;
}
return flatBytes;
}
#endregion
#region BlobToKzgCommitment
private class BlobToKzgCommitmentInput
{
public string Blob { get; set; } = null!;
}
private class BlobToKzgCommitmentTest
{
public BlobToKzgCommitmentInput Input { get; set; } = null!;
public string? Output { get; set; } = null!;
}
[TestCase]
public void TestBlobToKzgCommitment()
{
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*/*/data.yaml" });
foreach (string testFile in matcher.GetResultsInFullPath(_blobToKzgCommitmentTests))
{
string yaml = File.ReadAllText(testFile);
BlobToKzgCommitmentTest test = _deserializer.Deserialize<BlobToKzgCommitmentTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));
byte[] commitment = new byte[48];
byte[] blob = GetBytes(test.Input.Blob);
try
{
Ckzg.BlobToKzgCommitment(commitment, blob, _ts);
string? commitmentStr = test.Output;
Assert.That(commitmentStr, Is.Not.EqualTo(null));
byte[] expectedCommitment = GetBytes(commitmentStr);
Assert.That(commitment, Is.EqualTo(expectedCommitment));
}
catch
{
Assert.That(test.Output, Is.EqualTo(null));
}
}
}
#endregion
#region ComputeKzgProof
private class ComputeKzgProofInput
{
public string Blob { get; set; } = null!;
public string Z { get; set; } = null!;
}
private class ComputeKzgProofTest
{
public ComputeKzgProofInput Input { get; set; } = null!;
public string? Output { get; set; } = null!;
}
[TestCase]
public void TestComputeKzgProof()
{
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*/*/data.yaml" });
foreach (string testFile in matcher.GetResultsInFullPath(_computeKzgProofTests))
{
string yaml = File.ReadAllText(testFile);
ComputeKzgProofTest test = _deserializer.Deserialize<ComputeKzgProofTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));
byte[] proof = new byte[48];
byte[] blob = GetBytes(test.Input.Blob);
byte[] z = GetBytes(test.Input.Z);
try
{
Ckzg.ComputeKzgProof(proof, blob, z, _ts);
string? proofStr = test.Output;
Assert.That(proofStr, Is.Not.EqualTo(null));
byte[] expectedProof = GetBytes(proofStr);
Assert.That(proof, Is.EqualTo(expectedProof));
}
catch
{
Assert.That(test.Output, Is.EqualTo(null));
}
}
}
#endregion
#region ComputeBlobKzgProof
private class ComputeBlobKzgProofInput
{
public string Blob { get; set; } = null!;
}
private class ComputeBlobKzgProofTest
{
public ComputeBlobKzgProofInput Input { get; set; } = null!;
public string? Output { get; set; } = null!;
}
[TestCase]
public void TestComputeBlobKzgProof()
{
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*/*/data.yaml" });
foreach (string testFile in matcher.GetResultsInFullPath(_computeBlobKzgProofTests))
{
string yaml = File.ReadAllText(testFile);
ComputeBlobKzgProofTest test = _deserializer.Deserialize<ComputeBlobKzgProofTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));
byte[] proof = new byte[48];
byte[] blob = GetBytes(test.Input.Blob);
try
{
Ckzg.ComputeBlobKzgProof(proof, blob, _ts);
string? proofStr = test.Output;
Assert.That(proofStr, Is.Not.EqualTo(null));
byte[] expectedProof = GetBytes(proofStr);
Assert.That(proof, Is.EqualTo(expectedProof));
}
catch
{
Assert.That(test.Output, Is.EqualTo(null));
}
}
}
#endregion
#region VerifyKzgProof
private class VerifyKzgProofInput
{
public string Commitment { get; set; } = null!;
public string Z { get; set; } = null!;
public string Y { get; set; } = null!;
public string Proof { get; set; } = null!;
}
private class VerifyKzgProofTest
{
public VerifyKzgProofInput Input { get; set; } = null!;
public bool? Output { get; set; } = null!;
}
[TestCase]
public void TestVerifyKzgProof()
{
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*/*/data.yaml" });
foreach (string testFile in matcher.GetResultsInFullPath(_verifyKzgProofTests))
{
string yaml = File.ReadAllText(testFile);
VerifyKzgProofTest test = _deserializer.Deserialize<VerifyKzgProofTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));
byte[] commitment = GetBytes(test.Input.Commitment);
byte[] z = GetBytes(test.Input.Z);
byte[] y = GetBytes(test.Input.Y);
byte[] proof = GetBytes(test.Input.Proof);
try
{
bool isCorrect = Ckzg.VerifyKzgProof(commitment, z, y, proof, _ts);
Assert.That(isCorrect, Is.EqualTo(test.Output));
}
catch
{
Assert.That(test.Output, Is.EqualTo(null));
}
}
}
#endregion
#region VerifyBlobKzgProof
private class VerifyBlobKzgProofInput
{
public string Blob { get; set; } = null!;
public string Commitment { get; set; } = null!;
public string Proof { get; set; } = null!;
}
private class VerifyBlobKzgProofTest
{
public VerifyBlobKzgProofInput Input { get; set; } = null!;
public bool? Output { get; set; } = null!;
}
[TestCase]
public void TestVerifyBlobKzgProof()
{
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*/*/data.yaml" });
foreach (string testFile in matcher.GetResultsInFullPath(_verifyBlobKzgProofTests))
{
string yaml = File.ReadAllText(testFile);
VerifyBlobKzgProofTest test = _deserializer.Deserialize<VerifyBlobKzgProofTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));
byte[] blob = GetBytes(test.Input.Blob);
byte[] commitment = GetBytes(test.Input.Commitment);
byte[] proof = GetBytes(test.Input.Proof);
try
{
bool isCorrect = Ckzg.VerifyBlobKzgProof(blob, commitment, proof, _ts);
Assert.That(isCorrect, Is.EqualTo(test.Output));
}
catch
{
Assert.That(test.Output, Is.EqualTo(null));
}
}
}
#endregion
#region VerifyBlobKzgProofBatch
private class VerifyBlobKzgProofBatchInput
{
public List<string> Blobs { get; set; } = null!;
public List<string> Commitments { get; set; } = null!;
public List<string> Proofs { get; set; } = null!;
}
private class VerifyBlobKzgProofBatchTest
{
public VerifyBlobKzgProofBatchInput Input { get; set; } = null!;
public bool? Output { get; set; } = null!;
}
[TestCase]
public void TestVerifyBlobKzgProofBatch()
{
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*/*/data.yaml" });
foreach (string testFile in matcher.GetResultsInFullPath(_verifyBlobKzgProofBatchTests))
{
string yaml = File.ReadAllText(testFile);
VerifyBlobKzgProofBatchTest test = _deserializer.Deserialize<VerifyBlobKzgProofBatchTest>(yaml);
Assert.That(test, Is.Not.EqualTo(null));
byte[] blobs = GetFlatBytes(test.Input.Blobs);
byte[] commitments = GetFlatBytes(test.Input.Commitments);
byte[] proofs = GetFlatBytes(test.Input.Proofs);
int count = blobs.Length / Ckzg.BytesPerBlob;
try
{
bool isCorrect = Ckzg.VerifyBlobKzgProofBatch(blobs, commitments, proofs, count, _ts);
Assert.That(isCorrect, Is.EqualTo(test.Output));
}
catch
{
Assert.That(test.Output, Is.EqualTo(null));
}
}
}
#endregion
}

View File

@ -1,9 +1,9 @@
ifeq ($(OS),Windows_NT)
BLST_BUILDSCRIPT = ./build.bat
BLST_OBJ = blst.lib
CSHARP_PLATFORM ?= win-x64
LOCATION ?= win-x64
CLANG_EXECUTABLE = clang
CKZG_LIBRARY_PATH = Ckzg.Bindings\runtimes\$(CSHARP_PLATFORM)\native\ckzg.dll
CKZG_LIBRARY_PATH = Ckzg.Bindings\runtimes\$(LOCATION)\native\ckzg.dll
else
BLST_BUILDSCRIPT = ./build.sh
BLST_OBJ = libblst.a
@ -13,20 +13,20 @@ else
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_S),Linux)
ifeq ($(UNAME_M),x86_64)
CSHARP_PLATFORM ?= linux-x64
LOCATION ?= linux-x64
else
CSHARP_PLATFORM ?= linux-arm64
LOCATION ?= linux-arm64
endif
endif
ifeq ($(UNAME_S),Darwin)
ifeq ($(UNAME_M),arm64)
CSHARP_PLATFORM ?= osx-arm64
LOCATION ?= osx-arm64
else
CSHARP_PLATFORM ?= osx-x64
LOCATION ?= osx-x64
endif
endif
CKZG_LIBRARY_PATH = Ckzg.Bindings/runtimes/$(CSHARP_PLATFORM)/native/ckzg.so
CKZG_LIBRARY_PATH = Ckzg.Bindings/runtimes/$(LOCATION)/native/ckzg.so
endif
FIELD_ELEMENTS_PER_BLOB ?= 4096
@ -36,13 +36,17 @@ TARGETS = ckzg.c ../../src/c_kzg_4844.c ../../blst/$(BLST_OBJ)
CFLAGS += -O2 -Wall -Wextra -shared
CFLAGS += -DFIELD_ELEMENTS_PER_BLOB=$(FIELD_ELEMENTS_PER_BLOB)
CFLAGS += ${addprefix -I,${INCLUDE_DIRS}}
ifdef ARCH
CFLAGS += --target=$(ARCH)
BLST_BUILDSCRIPT_FLAGS += --target=$(ARCH)
endif
.PHONY: all
all: blst ckzg ckzg-dotnet
.PHONY: blst
blst:
cd ../../blst && $(BLST_BUILDSCRIPT)
cd ../../blst && $(BLST_BUILDSCRIPT) $(BLST_BUILDSCRIPT_FLAGS)
.PHONY: ckzg
ckzg: blst

View File

@ -1,45 +0,0 @@
// RUN: make run-test
#include "ckzg.h"
#include <stdio.h>
void calculate_proof_and_commitment(char * trusted_setup_path){
KZGSettings *s = load_trusted_setup_wrap(trusted_setup_path);
size_t n = 1;
uint8_t *commitment = (uint8_t *)calloc(48, 1);
uint8_t *proof = (uint8_t *)calloc(48, 1);
uint8_t *blob = (uint8_t *)calloc(4096, 32);
uint8_t *blobHash = (uint8_t *)calloc(32, 1);
n = 0;
for(int i = 0; i < 5875; i++){
if((n + 1) % 32 == 0)n++;
blob[n] = i % 250;
n++;
}
int res0 = compute_aggregate_kzg_proof(proof, blob, 1, s);
int res1 = blob_to_kzg_commitment(commitment, blob, s);
FILE *f = fopen("output.txt", "wt");
// commitment
for(int i = 0; i < 48; i++){
fprintf(f, "%02x", commitment[i]);
}
fprintf(f, "\n");
// proof
for(int i = 0; i < 48; i++){
fprintf(f, "%02x", proof[i]);
}
fprintf(f, "\n");
fclose(f);
free(blob);
free(commitment);
free(proof);
free_trusted_setup_wrap(s);
}
int main() {
calculate_proof_and_commitment("../../src/trusted_setup.txt");
return 0;
}