mirror of
https://github.com/status-im/c-kzg-4844.git
synced 2025-02-22 14:58:22 +00:00
Add C# wrapper & YAML tests (#46)
This commit is contained in:
parent
410eed4db6
commit
7c0bd867d5
67
.github/workflows/csharp-bindings-build.yml
vendored
67
.github/workflows/csharp-bindings-build.yml
vendored
@ -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
|
||||
|
62
bindings/csharp/Ckzg.Bindings/Ckzg.Bindings.cs
Normal file
62
bindings/csharp/Ckzg.Bindings/Ckzg.Bindings.cs
Normal 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
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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
|
||||
}
|
@ -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>
|
||||
|
@ -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")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
337
bindings/csharp/Ckzg.Test/ReferenceTests.cs
Normal file
337
bindings/csharp/Ckzg.Test/ReferenceTests.cs
Normal 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
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user