initial commit
This commit is contained in:
commit
d0af4143e2
|
@ -0,0 +1,162 @@
|
|||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- os: linux
|
||||
cpu: amd64
|
||||
- os: linux
|
||||
cpu: i386
|
||||
- os: macos
|
||||
cpu: amd64
|
||||
- os: windows
|
||||
cpu: amd64
|
||||
- os: windows
|
||||
cpu: i386
|
||||
branch: [version-1-2, version-1-4, version-1-6, devel]
|
||||
include:
|
||||
- target:
|
||||
os: linux
|
||||
builder: ubuntu-20.04
|
||||
shell: bash
|
||||
- target:
|
||||
os: macos
|
||||
builder: macos-12
|
||||
shell: bash
|
||||
- target:
|
||||
os: windows
|
||||
builder: windows-2019
|
||||
shell: msys2 {0}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
|
||||
name: '${{ matrix.target.os }}-${{ matrix.target.cpu }} (Nim ${{ matrix.branch }})'
|
||||
runs-on: ${{ matrix.builder }}
|
||||
steps:
|
||||
- name: Checkout nim-kzg4844
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install build dependencies (Linux i386)
|
||||
if: runner.os == 'Linux' && matrix.target.cpu == 'i386'
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-fast update -qq
|
||||
sudo DEBIAN_FRONTEND='noninteractive' apt-fast install \
|
||||
--no-install-recommends -yq gcc-multilib g++-multilib \
|
||||
libssl-dev:i386
|
||||
mkdir -p external/bin
|
||||
cat << EOF > external/bin/gcc
|
||||
#!/bin/bash
|
||||
exec $(which gcc) -m32 "\$@"
|
||||
EOF
|
||||
cat << EOF > external/bin/g++
|
||||
#!/bin/bash
|
||||
exec $(which g++) -m32 "\$@"
|
||||
EOF
|
||||
chmod 755 external/bin/gcc external/bin/g++
|
||||
echo '${{ github.workspace }}/external/bin' >> $GITHUB_PATH
|
||||
|
||||
- name: MSYS2 (Windows i386)
|
||||
if: runner.os == 'Windows' && matrix.target.cpu == 'i386'
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
path-type: inherit
|
||||
msystem: MINGW32
|
||||
install: >-
|
||||
base-devel
|
||||
git
|
||||
mingw-w64-i686-toolchain
|
||||
|
||||
- name: MSYS2 (Windows amd64)
|
||||
if: runner.os == 'Windows' && matrix.target.cpu == 'amd64'
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
path-type: inherit
|
||||
install: >-
|
||||
base-devel
|
||||
git
|
||||
mingw-w64-x86_64-toolchain
|
||||
|
||||
- name: Restore Nim DLLs dependencies (Windows) from cache
|
||||
if: runner.os == 'Windows'
|
||||
id: windows-dlls-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: external/dlls
|
||||
key: 'dlls'
|
||||
|
||||
- name: Install DLL dependencies (Windows)
|
||||
if: >
|
||||
steps.windows-dlls-cache.outputs.cache-hit != 'true' &&
|
||||
runner.os == 'Windows'
|
||||
run: |
|
||||
mkdir external
|
||||
curl -L "https://nim-lang.org/download/windeps.zip" -o external/windeps.zip
|
||||
7z x external/windeps.zip -oexternal/dlls
|
||||
|
||||
- name: Path to cached dependencies (Windows)
|
||||
if: >
|
||||
runner.os == 'Windows'
|
||||
run: |
|
||||
echo '${{ github.workspace }}'"/external/dlls" >> $GITHUB_PATH
|
||||
|
||||
- name: Derive environment variables
|
||||
run: |
|
||||
if [[ '${{ matrix.target.cpu }}' == 'amd64' ]]; then
|
||||
PLATFORM=x64
|
||||
else
|
||||
PLATFORM=x86
|
||||
fi
|
||||
echo "PLATFORM=$PLATFORM" >> $GITHUB_ENV
|
||||
|
||||
ncpu=
|
||||
MAKE_CMD="make"
|
||||
case '${{ runner.os }}' in
|
||||
'Linux')
|
||||
ncpu=$(nproc)
|
||||
;;
|
||||
'macOS')
|
||||
ncpu=$(sysctl -n hw.ncpu)
|
||||
;;
|
||||
'Windows')
|
||||
ncpu=$NUMBER_OF_PROCESSORS
|
||||
MAKE_CMD="mingw32-make"
|
||||
;;
|
||||
esac
|
||||
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
|
||||
echo "ncpu=$ncpu" >> $GITHUB_ENV
|
||||
echo "MAKE_CMD=${MAKE_CMD}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build Nim and Nimble
|
||||
run: |
|
||||
curl -O -L -s -S https://raw.githubusercontent.com/status-im/nimbus-build-system/master/scripts/build_nim.sh
|
||||
env MAKE="${MAKE_CMD} -j${ncpu}" ARCH_OVERRIDE=${PLATFORM} NIM_COMMIT=${{ matrix.branch }} \
|
||||
QUICK_AND_DIRTY_COMPILER=1 QUICK_AND_DIRTY_NIMBLE=1 CC=gcc \
|
||||
bash build_nim.sh nim csources dist/nimble NimBinaries
|
||||
echo '${{ github.workspace }}/nim/bin' >> $GITHUB_PATH
|
||||
|
||||
- name: Run nim-kzg4844 tests
|
||||
run: |
|
||||
if [[ "${{ matrix.target.os }}" == "windows" ]]; then
|
||||
# https://github.com/status-im/nimbus-eth2/issues/3121
|
||||
export NIMFLAGS="-d:nimRawSetjmp"
|
||||
fi
|
||||
nim --version
|
||||
nimble --version
|
||||
nimble install -y --depsOnly
|
||||
rm -f nimble.lock
|
||||
env TEST_LANG="c" nimble test
|
||||
env TEST_LANG="cpp" nimble test
|
|
@ -0,0 +1,4 @@
|
|||
/build
|
||||
nimble.develop
|
||||
nimble.paths
|
||||
*.exe
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "kzg4844/csources"]
|
||||
path = kzg4844/csources
|
||||
url = https://github.com/ethereum/c-kzg-4844
|
|
@ -0,0 +1,17 @@
|
|||
# kzg4844 wrapper in nim
|
||||
|
||||
![Github action](https://github.com/status-im/nim-kzg4844/workflows/CI/badge.svg)
|
||||
|
||||
This is a Nim wrapper of original C implementation of [c-kzg-4844](https://github.com/ethereum/c-kzg-4844)
|
||||
|
||||
## License
|
||||
|
||||
Licensed and distributed under either of
|
||||
|
||||
* MIT license: [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT
|
||||
|
||||
or
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHEv2](LICENSE-APACHEv2) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
at your option. These files may not be copied, modified, or distributed except according to those terms.
|
|
@ -0,0 +1,15 @@
|
|||
# nim-kzg4844
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
import
|
||||
kzg4844/kzg
|
||||
|
||||
export
|
||||
kzg
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# nim-kzg4844
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
mode = ScriptMode.Verbose
|
||||
|
||||
packageName = "kzg4844"
|
||||
version = "0.1.0"
|
||||
author = "Status Research & Development GmbH"
|
||||
description = "c-kzg-4844 wrapper in Nim"
|
||||
license = "Apache License 2.0"
|
||||
skipDirs = @["tests"]
|
||||
|
||||
requires "nim >= 1.2.0"
|
||||
requires "stew >= 0.1.0"
|
||||
requires "unittest2"
|
||||
|
||||
# Helper functions
|
||||
proc test(args, path: string) =
|
||||
if not dirExists "build":
|
||||
mkDir "build"
|
||||
exec "nim " & getEnv("TEST_LANG", "c") & " " & getEnv("NIMFLAGS") & " " & args &
|
||||
" --outdir:build -r -f --hints:off --warnings:off --skipParentCfg " & path
|
||||
|
||||
task test, "Run all tests":
|
||||
test "-d:debug", "tests/test_all"
|
||||
test "-d:release", "tests/test_all"
|
||||
test "--threads:on -d:release", "tests/test_all"
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 5cfbc341352f12330aaf8e5f5c4df14dca829f1a
|
|
@ -0,0 +1,190 @@
|
|||
# nim-kzg4844
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
import
|
||||
std/[streams, strutils],
|
||||
kzg_abi,
|
||||
stew/[results, byteutils]
|
||||
|
||||
export
|
||||
results,
|
||||
kzg_abi
|
||||
|
||||
type
|
||||
KzgCtx* = ref object
|
||||
val: KzgSettings
|
||||
|
||||
G1Data* = array[48, byte]
|
||||
G2Data* = array[96, byte]
|
||||
|
||||
Bytes32 = array[32, byte]
|
||||
|
||||
when (NimMajor, NimMinor) < (1, 4):
|
||||
{.push raises: [Defect].}
|
||||
else:
|
||||
{.push raises: [].}
|
||||
|
||||
##############################################################
|
||||
# Private helpers
|
||||
##############################################################
|
||||
|
||||
proc destroy(x: KzgCtx) =
|
||||
free_trusted_setup(x.val)
|
||||
|
||||
proc newKzgCtx(): KzgCtx =
|
||||
new(result, destroy)
|
||||
|
||||
template getPtr(x: untyped): auto =
|
||||
when (NimMajor, NimMinor) <= (1,6):
|
||||
unsafeAddr(x)
|
||||
else:
|
||||
addr(x)
|
||||
|
||||
template verify(res: KZG_RET) =
|
||||
if res != KZG_OK:
|
||||
return err($res)
|
||||
|
||||
##############################################################
|
||||
# Public functions
|
||||
##############################################################
|
||||
|
||||
proc loadTrustedSetup*(input: File): Result[KzgCtx, string] =
|
||||
let
|
||||
ctx = newKzgCtx()
|
||||
res = load_trusted_setup_file(ctx.val, input)
|
||||
|
||||
verify(res)
|
||||
ok(ctx)
|
||||
|
||||
proc loadTrustedSetup*(fileName: string): Result[KzgCtx, string] =
|
||||
try:
|
||||
let file = open(fileName)
|
||||
result = file.loadTrustedSetup()
|
||||
file.close()
|
||||
except IOError as ex:
|
||||
return err(ex.msg)
|
||||
|
||||
proc loadTrustedSetup*(g1: openArray[G1Data],
|
||||
g2: openArray[G2Data]):
|
||||
Result[KzgCtx, string] =
|
||||
if g1.len == 0 or g2.len == 0:
|
||||
return err($KZG_BADARGS)
|
||||
|
||||
let
|
||||
ctx = newKzgCtx()
|
||||
res = load_trusted_setup(ctx.val,
|
||||
g1[0][0].getPtr,
|
||||
g1.len.csize_t,
|
||||
g2[0][0].getPtr,
|
||||
g2.len.csize_t)
|
||||
|
||||
verify(res)
|
||||
ok(ctx)
|
||||
|
||||
proc loadTrustedSetupFromString*(input: string): Result[KzgCtx, string] =
|
||||
var
|
||||
s = newStringStream(input)
|
||||
g1: array[FIELD_ELEMENTS_PER_BLOB, G1Data]
|
||||
g2: array[65, G2Data]
|
||||
|
||||
try:
|
||||
let fieldElems = s.readLine().parseInt()
|
||||
doAssert fieldElems == FIELD_ELEMENTS_PER_BLOB
|
||||
let numG2 = s.readLine().parseInt()
|
||||
doAssert numG2 == 65
|
||||
|
||||
for i in 0 ..< FIELD_ELEMENTS_PER_BLOB:
|
||||
g1[i] = hexToByteArray[48](s.readLine())
|
||||
|
||||
for i in 0 ..< 65:
|
||||
g2[i] = hexToByteArray[96](s.readLine())
|
||||
except ValueError as ex:
|
||||
return err(ex.msg)
|
||||
except OSError as ex:
|
||||
return err(ex.msg)
|
||||
except IOError as ex:
|
||||
return err(ex.msg)
|
||||
|
||||
loadTrustedSetup(g1, g2)
|
||||
|
||||
proc toCommitment*(ctx: KzgCtx,
|
||||
blob: KzgBlob):
|
||||
Result[KzgCommitment, string] =
|
||||
var kate: KzgCommitment
|
||||
let res = blob_to_kzg_commitment(kate, blob, ctx.val)
|
||||
verify(res)
|
||||
ok(kate)
|
||||
|
||||
proc computeProof*(ctx: KzgCtx,
|
||||
blobs: openArray[KzgBlob]):
|
||||
Result[KzgProof, string] =
|
||||
var proof: KzgProof
|
||||
let res = compute_aggregate_kzg_proof(
|
||||
proof,
|
||||
blobs[0].getPtr,
|
||||
blobs.len.csize_t,
|
||||
ctx.val)
|
||||
verify(res)
|
||||
ok(proof)
|
||||
|
||||
proc verifyProof*(ctx: KzgCtx,
|
||||
blobs: openArray[KzgBlob],
|
||||
commitments: openArray[KzgCommitment],
|
||||
proof: KzgProof): Result[void, string] =
|
||||
|
||||
if blobs.len == 0 or commitments.len == 0:
|
||||
return err($KZG_BADARGS)
|
||||
|
||||
if blobs.len != commitments.len:
|
||||
return err($KZG_BADARGS)
|
||||
|
||||
var ok: bool
|
||||
let res = verify_aggregate_kzg_proof(
|
||||
ok,
|
||||
blobs[0].getPtr,
|
||||
commitments[0].getPtr,
|
||||
blobs.len.csize_t,
|
||||
proof,
|
||||
ctx.val)
|
||||
verify(res)
|
||||
if not ok:
|
||||
return err($KZG_ERROR)
|
||||
ok()
|
||||
|
||||
proc computeProof*(ctx: KzgCtx,
|
||||
blob: KzgBlob,
|
||||
z: Bytes32): Result[KzgProof, string] =
|
||||
var proof: KzgProof
|
||||
let res = compute_kzg_proof(
|
||||
proof,
|
||||
blob,
|
||||
z,
|
||||
ctx.val)
|
||||
verify(res)
|
||||
ok(proof)
|
||||
|
||||
proc verifyProof*(ctx: KzgCtx,
|
||||
commitment: KzgCommitment,
|
||||
z: Bytes32, # Input Point
|
||||
y: Bytes32, # Claimed Value
|
||||
proof: KzgProof): Result[void, string] =
|
||||
var ok: bool
|
||||
let res = verify_kzg_proof(
|
||||
ok,
|
||||
commitment,
|
||||
z,
|
||||
y,
|
||||
proof,
|
||||
ctx.val)
|
||||
verify(res)
|
||||
if not ok:
|
||||
return err($KZG_ERROR)
|
||||
ok()
|
||||
|
||||
{. pop .}
|
|
@ -0,0 +1,118 @@
|
|||
# nim-kzg4844
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
import
|
||||
std/strformat,
|
||||
strutils
|
||||
|
||||
from os import DirSep
|
||||
|
||||
const FIELD_ELEMENTS_PER_BLOB*{.strdefine.} = 4096
|
||||
|
||||
const
|
||||
ckzgPath = currentSourcePath.rsplit(DirSep, 1)[0] & "/csources/"
|
||||
blstPath = ckzgPath & "blst/"
|
||||
srcPath = ckzgPath & "src/"
|
||||
bindingsPath = blstPath & "bindings"
|
||||
|
||||
when not defined(externalBlst):
|
||||
{.compile: blstPath & "build/assembly.S".}
|
||||
{.compile: blstPath & "src/server.c"}
|
||||
|
||||
{.compile: srcPath & "c_kzg_4844.c"}
|
||||
|
||||
{.passc: "-I" & bindingsPath &
|
||||
" -DFIELD_ELEMENTS_PER_BLOB=" &
|
||||
fmt"{FIELD_ELEMENTS_PER_BLOB}".}
|
||||
{.passc: "-I" & srcPath .}
|
||||
|
||||
const
|
||||
BYTES_PER_FIELD_ELEMENT* = 32
|
||||
KzgBlobSize* = FIELD_ELEMENTS_PER_BLOB*BYTES_PER_FIELD_ELEMENT
|
||||
|
||||
type
|
||||
KZG_RET* = distinct cint
|
||||
|
||||
const
|
||||
KZG_OK* = (0).KZG_RET
|
||||
KZG_BADARGS* = (1).KZG_RET
|
||||
KZG_ERROR* = (2).KZG_RET
|
||||
KZG_MALLOC* = (3).KZG_RET
|
||||
|
||||
proc `$`*(x: KZG_RET): string =
|
||||
case x
|
||||
of KZG_OK: "ok"
|
||||
of KZG_BADARGS: "kzg badargs"
|
||||
of KZG_ERROR: "kzg error"
|
||||
of KZG_MALLOC: "kzg malloc"
|
||||
else: "kzg unknown error"
|
||||
|
||||
proc `==`*(a, b: KZG_RET): bool =
|
||||
a.cint == b.cint
|
||||
|
||||
type
|
||||
KzgBlob* = array[KzgBlobSize, byte]
|
||||
|
||||
KzgSettings* {.importc: "KZGSettings",
|
||||
header: "c_kzg_4844.h", byref.} = object
|
||||
|
||||
Bytes48 = array[48, byte]
|
||||
Bytes32 = array[32, byte]
|
||||
|
||||
KzgCommitment* = Bytes48
|
||||
KzgProof* = Bytes48
|
||||
|
||||
{.pragma: kzg_abi, cdecl, header: "c_kzg_4844.h".}
|
||||
|
||||
proc load_trusted_setup*(res: KzgSettings,
|
||||
g1Bytes: ptr byte, # n1 * 48 bytes
|
||||
n1: csize_t,
|
||||
g2Bytes: ptr byte, # n2 * 96 bytes
|
||||
n2: csize_t): KZG_RET {.kzg_abi,
|
||||
importc: "load_trusted_setup".}
|
||||
|
||||
proc load_trusted_setup_file*(res: KzgSettings,
|
||||
input: File): KZG_RET {.kzg_abi,
|
||||
importc: "load_trusted_setup_file" .}
|
||||
|
||||
proc free_trusted_setup*(s: KzgSettings) {.kzg_abi,
|
||||
importc: "free_trusted_setup" .}
|
||||
|
||||
proc blob_to_kzg_commitment*(res: var KzgCommitment,
|
||||
blob: KzgBlob,
|
||||
s: KzgSettings): KZG_RET {.kzg_abi,
|
||||
importc: "blob_to_kzg_commitment" .}
|
||||
|
||||
proc compute_aggregate_kzg_proof*(res: var KzgProof,
|
||||
blobs: ptr KzgBlob,
|
||||
n: csize_t,
|
||||
s: KzgSettings): KZG_RET {.kzg_abi,
|
||||
importc: "compute_aggregate_kzg_proof" .}
|
||||
|
||||
proc verify_aggregate_kzg_proof*(re: var bool,
|
||||
blobs: ptr KzgBlob,
|
||||
commitmentsBytes: ptr KzgCommitment,
|
||||
n: csize_t,
|
||||
aggregatedProofBytes: KzgProof,
|
||||
s: KzgSettings): KZG_RET {.kzg_abi,
|
||||
importc: "verify_aggregate_kzg_proof" .}
|
||||
|
||||
proc compute_kzg_proof*(res: var KzgProof,
|
||||
blob: KzgBlob,
|
||||
zBytes: Bytes32,
|
||||
s: KzgSettings): KZG_RET {.kzg_abi,
|
||||
importc: "compute_kzg_proof" .}
|
||||
|
||||
proc verify_kzg_proof*(res: var bool,
|
||||
commitmentBytes: KzgCommitment,
|
||||
zBytes: Bytes32,
|
||||
yBytes: Bytes32,
|
||||
proofBytes: KzgProof,
|
||||
s: KzgSettings): KZG_RET {.kzg_abi,
|
||||
importc: "verify_kzg_proof" .}
|
|
@ -0,0 +1,2 @@
|
|||
--styleCheck:usages
|
||||
--styleCheck:error
|
|
@ -0,0 +1,118 @@
|
|||
# nim-kzg4844
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
{.used.}
|
||||
|
||||
import
|
||||
std/[sysrand, streams, strutils],
|
||||
unittest2,
|
||||
stew/byteutils,
|
||||
../kzg4844/kzg_abi,
|
||||
./types
|
||||
|
||||
proc readSetup(): KzgSettings =
|
||||
var
|
||||
s = newFileStream(trustedSetupFile)
|
||||
g1Bytes: array[FIELD_ELEMENTS_PER_BLOB * 48, byte]
|
||||
g2Bytes: array[65 * 96, byte]
|
||||
|
||||
doAssert(s.isNil.not,
|
||||
"FAILED TO OPEN: " & trustedSetupFile)
|
||||
|
||||
let fieldElems = s.readLine().parseInt()
|
||||
doAssert fieldElems == FIELD_ELEMENTS_PER_BLOB
|
||||
let numG2 = s.readLine().parseInt()
|
||||
doAssert numG2 == 65
|
||||
|
||||
for i in 0 ..< FIELD_ELEMENTS_PER_BLOB:
|
||||
let z = hexToByteArray[48](s.readLine())
|
||||
g1Bytes[i*48 ..< i*48+48] = z[0..<48]
|
||||
|
||||
for i in 0 ..< 65:
|
||||
let z = hexToByteArray[96](s.readLine())
|
||||
g2Bytes[i*96 ..< i*96+96] = z[0..<96]
|
||||
|
||||
let res = load_trusted_setup(result,
|
||||
g1Bytes[0].addr, FIELD_ELEMENTS_PER_BLOB,
|
||||
g2Bytes[0].addr, 65)
|
||||
|
||||
doAssert(res == KZG_OK,
|
||||
"ERROR: " & $res)
|
||||
|
||||
proc readSetup(filename: string): KzgSettings =
|
||||
var file = open(filename)
|
||||
let ret = load_trusted_setup_file(result, file)
|
||||
doAssert ret == KZG_OK
|
||||
file.close()
|
||||
|
||||
proc createKateBlobs(s: KzgSettings, n: int): KateBlobs =
|
||||
for i in 0..<n:
|
||||
var blob: KzgBlob
|
||||
discard urandom(blob)
|
||||
for i in 0..<len(blob):
|
||||
# don't overflow modulus
|
||||
if blob[i] > MAX_TOP_BYTE and i %% BYTES_PER_FIELD_ELEMENT == 31:
|
||||
blob[i] = MAX_TOP_BYTE
|
||||
result.blobs.add(blob)
|
||||
|
||||
for i in 0..<n:
|
||||
var kate: KzgCommitment
|
||||
doAssert blob_to_kzg_commitment(kate, result.blobs[i], s) == KZG_OK
|
||||
result.kates.add(kate)
|
||||
|
||||
let
|
||||
kzgs = readSetup()
|
||||
|
||||
suite "verify proof (abi)":
|
||||
let
|
||||
settings = readSetup(trustedSetupFile)
|
||||
|
||||
test "verify agg proof success":
|
||||
var kb = kzgs.createKateBlobs(nblobs)
|
||||
var kp: KzgProof
|
||||
var res = compute_aggregate_kzg_proof(kp, kb.blobs[0].addr,
|
||||
csize_t(nblobs), kzgs)
|
||||
check res == KZG_OK
|
||||
|
||||
var ok: bool
|
||||
res = verify_aggregate_kzg_proof(ok, kb.blobs[0].addr,
|
||||
kb.kates[0].addr, csize_t(nblobs), kp, kzgs)
|
||||
check res == KZG_OK
|
||||
check ok
|
||||
|
||||
test "verify agg proof failure":
|
||||
var kb = kzgs.createKateBlobs(nblobs)
|
||||
var kp: KzgProof
|
||||
var res = compute_aggregate_kzg_proof(kp, kb.blobs[0].addr,
|
||||
csize_t(nblobs), kzgs)
|
||||
check res == KZG_OK
|
||||
|
||||
var other = kzgs.createKateBlobs(nblobs)
|
||||
res = compute_aggregate_kzg_proof(kp, other.blobs[0].addr,
|
||||
csize_t(nblobs), kzgs)
|
||||
check res == KZG_OK
|
||||
|
||||
var ok: bool
|
||||
res = verify_aggregate_kzg_proof(ok, kb.blobs[0].addr,
|
||||
kb.kates[0].addr, csize_t(nblobs), kp, kzgs)
|
||||
check res == KZG_OK
|
||||
check ok == false
|
||||
|
||||
test "verify proof":
|
||||
var kp: KzgProof
|
||||
var res = compute_kzg_proof(kp, blob, inputPoint, kzgs)
|
||||
check res == KZG_OK
|
||||
check kp == proof
|
||||
|
||||
var ok: bool
|
||||
res = verify_kzg_proof(ok, commitment, inputPoint, claimedValue, kp, kzgs)
|
||||
check res == KZG_OK
|
||||
check ok
|
||||
|
||||
free_trusted_setup(settings)
|
|
@ -0,0 +1,12 @@
|
|||
# nim-kzg4844
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
import
|
||||
test_abi,
|
||||
test_kzg
|
|
@ -0,0 +1,69 @@
|
|||
# nim-kzg4844
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
# at your option.
|
||||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
{.used.}
|
||||
|
||||
import
|
||||
std/[sysrand],
|
||||
unittest2,
|
||||
../kzg4844/kzg,
|
||||
./types
|
||||
|
||||
proc createKateBlobs(ctx: KzgCtx, n: int): KateBlobs =
|
||||
var blob: KzgBlob
|
||||
for i in 0..<n:
|
||||
discard urandom(blob)
|
||||
for i in 0..<len(blob):
|
||||
# don't overflow modulus
|
||||
if blob[i] > MAX_TOP_BYTE and i %% BYTES_PER_FIELD_ELEMENT == 31:
|
||||
blob[i] = MAX_TOP_BYTE
|
||||
result.blobs.add(blob)
|
||||
|
||||
for i in 0..<n:
|
||||
let res = ctx.toCommitment(result.blobs[i])
|
||||
doAssert res.isOk
|
||||
result.kates.add(res.get)
|
||||
|
||||
suite "verify proof (high-level)":
|
||||
const
|
||||
trustedSetup = staticRead("../" & trustedSetupFile)
|
||||
|
||||
var ctx: KzgCtx
|
||||
|
||||
test "load trusted setup from string":
|
||||
let res = loadTrustedSetupFromString(trustedSetup)
|
||||
check res.isOk
|
||||
ctx = res.get
|
||||
|
||||
test "verify proof success":
|
||||
let kb = ctx.createKateBlobs(nblobs)
|
||||
let pres = ctx.computeProof(kb.blobs)
|
||||
check pres.isOk
|
||||
let res = ctx.verifyProof(kb.blobs, kb.kates, pres.get)
|
||||
check res.isOk
|
||||
|
||||
test "verify proof failure":
|
||||
let kb = ctx.createKateBlobs(nblobs)
|
||||
let pres = ctx.computeProof(kb.blobs)
|
||||
check pres.isOk
|
||||
|
||||
let other = ctx.createKateBlobs(nblobs)
|
||||
let badProof = ctx.computeProof(other.blobs)
|
||||
check badProof.isOk
|
||||
|
||||
let res = ctx.verifyProof(kb.blobs, kb.kates, badProof.get)
|
||||
check res.isErr
|
||||
|
||||
test "verify proof":
|
||||
let kp = ctx.computeProof(blob, inputPoint)
|
||||
check kp.isOk
|
||||
check kp.get == proof
|
||||
|
||||
let res = ctx.verifyProof(commitment, inputPoint, claimedValue, kp.get)
|
||||
check res.isOk
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue