Merge pull request #1 from flcl42/add-csharp-side-impls-as-tests
Add C# related files, rename dir, add impls
This commit is contained in:
commit
dd242cd93c
|
@ -1,97 +0,0 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
class ckzg {
|
||||
[DllImport("ckzg.dll", EntryPoint="bytes_to_bls_field_wrap")] // free result with free()
|
||||
public static extern IntPtr bytes_to_bls_field(byte[] bytes);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="compute_powers_wrap")] // free result with free()
|
||||
public static extern IntPtr compute_powers(IntPtr r, UInt64 n);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="vector_lincomb_wrap")] // free result with free_polynomial()
|
||||
public static extern IntPtr vector_lincomb(byte[] vectors, IntPtr scalars, UInt64 num_vectors, UInt64 vector_len);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="g1_lincomb_wrap")] // free result with free()
|
||||
public static extern IntPtr g1_lincomb(byte[] points, IntPtr scalars, UInt64 num_points);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="verify_kzg_proof_wrap")]
|
||||
public static extern int verify_kzg_proof(IntPtr c, IntPtr x, IntPtr y, byte[] p, IntPtr ts);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="evaluate_polynomial_wrap")]
|
||||
public static extern int evaluate_polynomial_in_evaluation_form(byte[] result, byte[] p, UInt64 n, byte[] z, IntPtr ts);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="load_trusted_setup_wrap")] // free result with free_trusted_setup()
|
||||
public static extern IntPtr load_trusted_setup(string filename);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="free_trusted_setup_wrap")]
|
||||
public static extern void free_trusted_setup(IntPtr ts);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="free_polynomial")]
|
||||
public static extern void free_polynomial(IntPtr p);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint="free")]
|
||||
private static extern void free(IntPtr p);
|
||||
}
|
||||
|
||||
class tests {
|
||||
// Convert.FromHexString replacement (since mono does not seem to have new enough C# libs)
|
||||
public static byte[] HexadecimalStringToByteArray(String hexadecimalString)
|
||||
{
|
||||
int length = hexadecimalString.Length;
|
||||
byte[] byteArray = new byte[length / 2];
|
||||
for (int i = 0; i < length; i += 2){
|
||||
byteArray[i / 2] = Convert.ToByte(hexadecimalString.Substring(i, 2), 16);
|
||||
}
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
/* TODO: update for new interface
|
||||
Console.WriteLine("Test 1: verify_kzg_proof");
|
||||
|
||||
IntPtr ts = ckzg.load_trusted_setup("../../src/trusted_setup.txt");
|
||||
System.Diagnostics.Trace.Assert(ts != IntPtr.Zero, "Failed to load trusted setup.");
|
||||
|
||||
byte[] c = HexadecimalStringToByteArray("b91c022acf7bd3b63be69a4c19b781ea7a3d5df1cd66ceb7dd0f399610f0ee04695dace82e04bfb83af2b17d7319f87f");
|
||||
byte[] x = HexadecimalStringToByteArray("0345f802a75a6c0d9cc5b8a1e71642b8fa80b0a78938edc6da1e591149578d1a");
|
||||
byte[] y = HexadecimalStringToByteArray("3b17cab634c3795d311380f3bc93ce8e768efc0e2b9e79496cfc8f351594b472");
|
||||
byte[] p = HexadecimalStringToByteArray("a5ddd6da04c47a9cd4628beb8d55ebd2e930a64dfa29f876ebf393cfd6574d48a3ce96ac5a2af4a4f9ec9caa47d304d3");
|
||||
int result = ckzg.verify_kzg_proof(c, x, y, p, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 1, "Verification failed");
|
||||
|
||||
x[0] = 0x42;
|
||||
result = ckzg.verify_kzg_proof(c, x, y, p, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 0, "Verification succeeded incorrectly");
|
||||
|
||||
ckzg.free_trusted_setup(ts);
|
||||
*/
|
||||
|
||||
/* TODO: update for new interface
|
||||
Console.WriteLine("Test 2: evaluate_polynomial_in_evaluation_form");
|
||||
|
||||
ts = ckzg.load_trusted_setup("../python/tiny_trusted_setup.txt");
|
||||
System.Diagnostics.Trace.Assert(ts != IntPtr.Zero, "Failed to load trusted setup.");
|
||||
|
||||
p = HexadecimalStringToByteArray("10000000000000000d00000000000000000000000000000000000000000000000a000000000000000d00000000000000000000000000000000000000000000000b000000000001000d000376020003ecd0040376cecc518d00000000000000000c000000fffffeff0b5cfb8900a4ba6734d39e93390be8a5477d9d2953a7ed73");
|
||||
x = HexadecimalStringToByteArray("0200000000000000000000000000000000000000000000000000000000000000");
|
||||
UInt64 n = Convert.ToUInt64(p.Length) / 32;
|
||||
result = ckzg.evaluate_polynomial_in_evaluation_form(y, p, n, x, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 0, "Evaluation failed");
|
||||
System.Diagnostics.Trace.Assert(y == HexadecimalStringToByteArray("1c000000000000000d0000000000000000000000000000000000000000000000"),
|
||||
"Evaluation produced incorrect value");
|
||||
|
||||
x[11] = 0x11;
|
||||
result = ckzg.evaluate_polynomial_in_evaluation_form(y, p, n, x, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 0, "Second evaluation failed");
|
||||
System.Diagnostics.Trace.Assert(y != HexadecimalStringToByteArray("1c000000000000000d0000000000000000000000000000000000000000000000"),
|
||||
"Second evaluation produced incorrect value");
|
||||
|
||||
ckzg.free_trusted_setup(ts);
|
||||
*/
|
||||
|
||||
Console.WriteLine("Tests passed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
bin/
|
||||
obj/
|
||||
.vs/
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>csharp</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32922.545
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "csharp", "csharp.csproj", "{108ACE4B-334D-4D63-9897-9895DFF35FEE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{108ACE4B-334D-4D63-9897-9895DFF35FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{108ACE4B-334D-4D63-9897-9895DFF35FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{108ACE4B-334D-4D63-9897-9895DFF35FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{108ACE4B-334D-4D63-9897-9895DFF35FEE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {1FCEC58A-285C-4F22-8B55-68B1A312EE7E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,226 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
class ckzg
|
||||
{
|
||||
[DllImport("ckzg.dll", EntryPoint = "bytes_to_bls_field_wrap")] // free result with free()
|
||||
public static extern byte[] bytes_to_bls_field(byte[] bytes);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "compute_powers_wrap")] // free result with free()
|
||||
public static extern byte[] compute_powers(byte[] r, UInt64 n);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "vector_lincomb_wrap")] // free result with free_polynomial()
|
||||
public static extern byte[] vector_lincomb(byte[] vectors, byte[] scalars, UInt64 num_vectors, UInt64 vector_len);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "g1_lincomb_wrap")] // free result with free()
|
||||
public static extern byte[] g1_lincomb(byte[] points, byte[] scalars, UInt64 num_points);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "verify_kzg_proof_wrap")]
|
||||
public static extern bool verify_kzg_proof(byte[] c, byte[] x, byte[] y, byte[] p, IntPtr ts);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "evaluate_polynomial_wrap")]
|
||||
public static extern bool evaluate_polynomial_in_evaluation_form(byte[] result, byte[] p, UInt64 n, byte[] z, IntPtr ts);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "load_trusted_setup_wrap")] // free result with free_trusted_setup()
|
||||
public static extern IntPtr load_trusted_setup(string filename);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "free_trusted_setup_wrap")]
|
||||
public static extern void free_trusted_setup(IntPtr ts);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "free_polynomial")]
|
||||
public static extern void free_polynomial(IntPtr p);
|
||||
|
||||
[DllImport("ckzg.dll", EntryPoint = "free")]
|
||||
private static extern void free(IntPtr p);
|
||||
}
|
||||
|
||||
class tests
|
||||
{
|
||||
IntPtr ts = ckzg.load_trusted_setup("../../src/trusted_setup.txt");
|
||||
|
||||
byte[] ssz_of(params object[] anything)
|
||||
{
|
||||
return new byte[1]; //mock
|
||||
}
|
||||
byte[] hash(byte[] data)
|
||||
{
|
||||
return data; //mock
|
||||
}
|
||||
byte[] flatten(byte[][] data)
|
||||
{
|
||||
return data[0]; //mock
|
||||
}
|
||||
|
||||
(byte[], byte[]) compute_aggregated_poly_and_commitment(byte[][] blobs, byte[][] kzg_commitments)
|
||||
{
|
||||
// Generate random linear combination challenges
|
||||
var r = hash_to_bls_field(ssz_of("BlobsAndCommitments", blobs, kzg_commitments));
|
||||
var r_powers = ckzg.compute_powers(r, (ulong)kzg_commitments.Length);
|
||||
|
||||
// Create aggregated polynomial in evaluation form
|
||||
byte[] aggregated_poly = ckzg.vector_lincomb(flatten(blobs), r_powers, (ulong)blobs.Length, (ulong)4096);
|
||||
|
||||
// Compute commitment to aggregated polynomial
|
||||
byte[] aggregated_poly_commitment = ckzg.g1_lincomb(flatten(kzg_commitments), r_powers, (ulong)kzg_commitments.Length);
|
||||
|
||||
return (aggregated_poly, aggregated_poly_commitment);
|
||||
}
|
||||
|
||||
byte[] hash_to_bls_field(byte[] data)
|
||||
{
|
||||
return ckzg.bytes_to_bls_field(hash(data));
|
||||
}
|
||||
|
||||
const byte BLOB_COMMITMENT_VERSION_KZG = 1;
|
||||
|
||||
byte[] kzg_to_versioned_hash(byte[] data_kzg)
|
||||
{
|
||||
var res = hash(data_kzg);
|
||||
res[0] = BLOB_COMMITMENT_VERSION_KZG;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool validate_blob_transaction_wrapper(
|
||||
byte[][] versioned_hashes,
|
||||
byte[][] commitments,
|
||||
byte[][] blobs
|
||||
)
|
||||
{
|
||||
if (versioned_hashes.Length != commitments.Length || commitments.Length != blobs.Length)
|
||||
{
|
||||
throw new ArgumentException("args");
|
||||
}
|
||||
var (aggregated_poly, aggregated_poly_commitment) = compute_aggregated_poly_and_commitment(
|
||||
blobs,
|
||||
commitments
|
||||
);
|
||||
|
||||
// Generate challenge `x` and evaluate the aggregated polynomial at `x`
|
||||
var x = hash_to_bls_field(
|
||||
ssz_of("PolynomialAndCommitment", aggregated_poly, aggregated_poly_commitment)
|
||||
);
|
||||
// Evaluate aggregated polynomial at `x` (evaluation function checks for div-by-zero)
|
||||
var y = ckzg.evaluate_polynomial_in_evaluation_form(aggregated_poly, x, "need to clarify", "need to clarify", ts);
|
||||
|
||||
// Verify aggregated proof
|
||||
if (!ckzg.verify_kzg_proof(aggregated_poly_commitment, x, y, "need to clarify", ts))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now that all commitments have been verified, check that versioned_hashes matches the commitments
|
||||
return versioned_hashes.Zip(commitments).All(x => Enumerable.SequenceEqual(x.First, kzg_to_versioned_hash(x.Second)));
|
||||
}
|
||||
readonly UInt256 BLS_MODULUS = UInt256.Parse("52435875175126190479447740508185965837690552500527637822603658699938581184513");
|
||||
|
||||
struct UInt256
|
||||
{
|
||||
public UInt256(params byte[] data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static bool operator >=(in UInt256 a, in UInt256 b) => true;
|
||||
public static bool operator <=(in UInt256 a, in UInt256 b) => false;
|
||||
|
||||
internal static UInt256 Parse(string v)
|
||||
{
|
||||
return new UInt256();
|
||||
}
|
||||
}
|
||||
|
||||
bool point_evaluation_precompile(byte[] input)
|
||||
{
|
||||
var versioned_hash = input[..32];
|
||||
// Evaluation point: next 32 bytes
|
||||
var x = input[32..64];
|
||||
if (new UInt256(x) >= BLS_MODULUS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Expected output: next 32 bytes
|
||||
var y = input[64..96];
|
||||
if (new UInt256(y) >= BLS_MODULUS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// The remaining data will always be the proof, including in future versions
|
||||
// input kzg point: next 48 bytes
|
||||
var data_kzg = input[96..144];
|
||||
if (!kzg_to_versioned_hash(data_kzg).SequenceEqual(versioned_hash))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Quotient kzg: next 48 bytes
|
||||
var quotient_kzg = input[144..192];
|
||||
if (!ckzg.verify_kzg_proof(data_kzg, x, y, quotient_kzg, ts))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Convert.FromHexString replacement (since mono does not seem to have new enough C# libs)
|
||||
public static byte[] HexadecimalStringToByteArray(String hexadecimalString)
|
||||
{
|
||||
int length = hexadecimalString.Length;
|
||||
byte[] byteArray = new byte[length / 2];
|
||||
for (int i = 0; i < length; i += 2)
|
||||
{
|
||||
byteArray[i / 2] = Convert.ToByte(hexadecimalString.Substring(i, 2), 16);
|
||||
}
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
/* TODO: update for new interface
|
||||
Console.WriteLine("Test 1: verify_kzg_proof");
|
||||
|
||||
IntPtr ts = ckzg.load_trusted_setup("../../src/trusted_setup.txt");
|
||||
System.Diagnostics.Trace.Assert(ts != IntPtr.Zero, "Failed to load trusted setup.");
|
||||
|
||||
byte[] c = HexadecimalStringToByteArray("b91c022acf7bd3b63be69a4c19b781ea7a3d5df1cd66ceb7dd0f399610f0ee04695dace82e04bfb83af2b17d7319f87f");
|
||||
byte[] x = HexadecimalStringToByteArray("0345f802a75a6c0d9cc5b8a1e71642b8fa80b0a78938edc6da1e591149578d1a");
|
||||
byte[] y = HexadecimalStringToByteArray("3b17cab634c3795d311380f3bc93ce8e768efc0e2b9e79496cfc8f351594b472");
|
||||
byte[] p = HexadecimalStringToByteArray("a5ddd6da04c47a9cd4628beb8d55ebd2e930a64dfa29f876ebf393cfd6574d48a3ce96ac5a2af4a4f9ec9caa47d304d3");
|
||||
int result = ckzg.verify_kzg_proof(c, x, y, p, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 1, "Verification failed");
|
||||
|
||||
x[0] = 0x42;
|
||||
result = ckzg.verify_kzg_proof(c, x, y, p, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 0, "Verification succeeded incorrectly");
|
||||
|
||||
ckzg.free_trusted_setup(ts);
|
||||
*/
|
||||
|
||||
/* TODO: update for new interface
|
||||
Console.WriteLine("Test 2: evaluate_polynomial_in_evaluation_form");
|
||||
|
||||
ts = ckzg.load_trusted_setup("../python/tiny_trusted_setup.txt");
|
||||
System.Diagnostics.Trace.Assert(ts != IntPtr.Zero, "Failed to load trusted setup.");
|
||||
|
||||
p = HexadecimalStringToByteArray("10000000000000000d00000000000000000000000000000000000000000000000a000000000000000d00000000000000000000000000000000000000000000000b000000000001000d000376020003ecd0040376cecc518d00000000000000000c000000fffffeff0b5cfb8900a4ba6734d39e93390be8a5477d9d2953a7ed73");
|
||||
x = HexadecimalStringToByteArray("0200000000000000000000000000000000000000000000000000000000000000");
|
||||
UInt64 n = Convert.ToUInt64(p.Length) / 32;
|
||||
result = ckzg.evaluate_polynomial_in_evaluation_form(y, p, n, x, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 0, "Evaluation failed");
|
||||
System.Diagnostics.Trace.Assert(y == HexadecimalStringToByteArray("1c000000000000000d0000000000000000000000000000000000000000000000"),
|
||||
"Evaluation produced incorrect value");
|
||||
|
||||
x[11] = 0x11;
|
||||
result = ckzg.evaluate_polynomial_in_evaluation_form(y, p, n, x, ts);
|
||||
System.Diagnostics.Trace.Assert(result == 0, "Second evaluation failed");
|
||||
System.Diagnostics.Trace.Assert(y != HexadecimalStringToByteArray("1c000000000000000d0000000000000000000000000000000000000000000000"),
|
||||
"Second evaluation produced incorrect value");
|
||||
|
||||
ckzg.free_trusted_setup(ts);
|
||||
*/
|
||||
|
||||
Console.WriteLine("Tests passed");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue