Update go bindings (#142)

* Update go bindings

* Fix some nits
This commit is contained in:
Justin Traglia 2023-02-20 10:01:31 -06:00 committed by GitHub
parent daa5f79fe3
commit a231d5354b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 239 additions and 83 deletions

View File

@ -159,6 +159,26 @@ func ComputeKZGProof(blob Blob, zBytes Bytes32) (KZGProof, CKzgRet) {
return proof, CKzgRet(ret)
}
/*
ComputeBlobKZGProof is the binding for:
C_KZG_RET compute_blob_kzg_proof(
KZGProof *out,
const Blob *blob,
const KZGSettings *s);
*/
func ComputeBlobKZGProof(blob Blob) (KZGProof, CKzgRet) {
if !loaded {
panic("trusted setup isn't loaded")
}
proof := KZGProof{}
ret := C.compute_blob_kzg_proof(
(*C.KZGProof)(unsafe.Pointer(&proof)),
(*C.Blob)(unsafe.Pointer(&blob)),
&settings)
return proof, CKzgRet(ret)
}
/*
VerifyKZGProof is the binding for:
@ -186,52 +206,54 @@ func VerifyKZGProof(commitmentBytes Bytes48, zBytes, yBytes Bytes32, proofBytes
}
/*
ComputeAggregateKZGProof is the binding for:
VerifyBlobKZGProof is the binding for:
C_KZG_RET compute_aggregate_kzg_proof(
KZGProof *out,
const Blob *blobs,
size_t n,
C_KZG_RET verify_blob_kzg_proof(
bool *out,
const Blob *blob,
const Bytes48 *commitment_bytes,
const Bytes48 *proof_bytes,
const KZGSettings *s);
*/
func ComputeAggregateKZGProof(blobs []Blob) (KZGProof, CKzgRet) {
func VerifyBlobKZGProof(blob Blob, commitmentBytes, proofBytes Bytes48) (bool, CKzgRet) {
if !loaded {
panic("trusted setup isn't loaded")
}
proof := KZGProof{}
ret := C.compute_aggregate_kzg_proof(
(*C.KZGProof)(unsafe.Pointer(&proof)),
*(**C.Blob)(unsafe.Pointer(&blobs)),
(C.size_t)(len(blobs)),
var result C.bool
ret := C.verify_blob_kzg_proof(
&result,
(*C.Blob)(unsafe.Pointer(&blob)),
(*C.Bytes48)(unsafe.Pointer(&commitmentBytes)),
(*C.Bytes48)(unsafe.Pointer(&proofBytes)),
&settings)
return proof, CKzgRet(ret)
return bool(result), CKzgRet(ret)
}
/*
VerifyAggregateKZGProof is the binding for:
VerifyBlobKZGProofBatch is the binding for:
C_KZG_RET verify_aggregate_kzg_proof(
C_KZG_RET verify_blob_kzg_proof_batch(
bool *out,
const Blob *blobs,
const Bytes48 *commitments_bytes,
size_t n,
const Bytes48 *aggregated_proof_bytes,
const Bytes48 *proofs_bytes,
const KZGSettings *s);
*/
func VerifyAggregateKZGProof(blobs []Blob, commitmentsBytes []Bytes48, aggregatedProofBytes Bytes48) (bool, CKzgRet) {
func VerifyBlobKZGProofBatch(blobs []Blob, commitmentsBytes, proofsBytes []Bytes48) (bool, CKzgRet) {
if !loaded {
panic("trusted setup isn't loaded")
}
if len(blobs) != len(commitmentsBytes) {
panic("len(blobs) != len(commitments)")
if len(blobs) != len(commitmentsBytes) || len(blobs) != len(proofsBytes) {
panic("the number of blobs/commitments/proofs should be equal")
}
var result C.bool
ret := C.verify_aggregate_kzg_proof(
ret := C.verify_blob_kzg_proof_batch(
&result,
*(**C.Blob)(unsafe.Pointer(&blobs)),
*(**C.Bytes48)(unsafe.Pointer(&commitmentsBytes)),
*(**C.Bytes48)(unsafe.Pointer(&proofsBytes)),
(C.size_t)(len(blobs)),
(*C.Bytes48)(unsafe.Pointer(&aggregatedProofBytes)),
&settings)
return bool(result), CKzgRet(ret)
}

View File

@ -2,11 +2,12 @@ package cgokzg4844
import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math/rand"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/require"
@ -103,60 +104,189 @@ func HumanBytes(b int64) string {
return fmt.Sprintf("%v%cB", float64(b)/float64(div), "KMGTPE"[exp])
}
///////////////////////////////////////////////////////////////////////////////
// Test Helper Functions
///////////////////////////////////////////////////////////////////////////////
func getBlob(path string) Blob {
inputBytes, err := os.ReadFile(path)
if err != nil {
panic(err)
}
var blob Blob
err = blob.UnmarshalText(inputBytes)
if err != nil {
panic(err)
}
return blob
}
func getBytes32(path string) Bytes32 {
inputBytes, err := os.ReadFile(path)
if err != nil {
panic(err)
}
var bytes32 Bytes32
err = bytes32.UnmarshalText(inputBytes)
if err != nil {
panic(err)
}
return bytes32
}
func getBytes48(path string) Bytes48 {
inputBytes, err := os.ReadFile(path)
if err != nil {
panic(err)
}
var bytes48 Bytes48
err = bytes48.UnmarshalText(inputBytes)
if err != nil {
panic(err)
}
return bytes48
}
func getBoolean(path string) bool {
inputBytes, err := os.ReadFile(path)
if err != nil {
panic(err)
}
return strings.Contains(string(inputBytes), "true")
}
///////////////////////////////////////////////////////////////////////////////
// Tests
///////////////////////////////////////////////////////////////////////////////
func TestComputeAggregateKZGProof(t *testing.T) {
type Test struct {
TestCases []struct {
Polynomials []Blob `json:"Polynomials"`
Proof Bytes48 `json:"Proof"`
Commitments []Bytes48 `json:"Commitments"`
var (
testDir = "../../tests"
blobToKZGCommitmentTests = filepath.Join(testDir, "blob_to_kzg_commitment/*")
computeKZGProofTests = filepath.Join(testDir, "compute_kzg_proof/*")
computeBlobKZGProofTests = filepath.Join(testDir, "compute_blob_kzg_proof/*")
verifyKZGProofTests = filepath.Join(testDir, "verify_kzg_proof/*")
verifyBlobKZGProofTests = filepath.Join(testDir, "verify_blob_kzg_proof/*")
verifyBlobKZGProofBatchTests = filepath.Join(testDir, "verify_blob_kzg_proof_batch/*")
)
func TestBlobToKZGCommitment(t *testing.T) {
tests, err := filepath.Glob(blobToKZGCommitmentTests)
require.NoError(t, err)
for _, test := range tests {
blob := getBlob(filepath.Join(test, "blob.txt"))
commitment, ret := BlobToKZGCommitment(blob)
if ret == C_KZG_OK {
expectedCommitment := KZGCommitment(getBytes48(filepath.Join(test, "commitment.txt")))
require.Equal(t, commitment, expectedCommitment, test)
} else {
require.NoFileExists(t, filepath.Join(test, "commitment.txt"))
}
}
}
testFile, err := os.Open("../rust/test_vectors/public_agg_proof.json")
require.NoError(t, err)
defer testFile.Close()
test := Test{}
err = json.NewDecoder(testFile).Decode(&test)
func TestComputeKZGProof(t *testing.T) {
tests, err := filepath.Glob(computeKZGProofTests)
require.NoError(t, err)
for _, test := range tests {
blob := getBlob(filepath.Join(test, "blob.txt"))
inputPoint := getBytes32(filepath.Join(test, "input_point.txt"))
for _, tc := range test.TestCases {
proof, ret := ComputeAggregateKZGProof(tc.Polynomials)
require.Zero(t, ret)
require.Equal(t, tc.Proof[:], proof[:])
for i := range tc.Polynomials {
commitment, ret := BlobToKZGCommitment(tc.Polynomials[i])
require.Equal(t, C_KZG_OK, ret)
require.Equal(t, tc.Commitments[i][:], commitment[:])
proof, ret := ComputeKZGProof(blob, inputPoint)
if ret == C_KZG_OK {
expectedProof := KZGProof(getBytes48(filepath.Join(test, "proof.txt")))
require.Equal(t, proof, expectedProof, test)
} else {
require.NoFileExists(t, filepath.Join(test, "proof.txt"))
}
}
}
func TestComputeBlobKZGProof(t *testing.T) {
tests, err := filepath.Glob(computeBlobKZGProofTests)
require.NoError(t, err)
for _, test := range tests {
blob := getBlob(filepath.Join(test, "blob.txt"))
proof, ret := ComputeBlobKZGProof(blob)
if ret == C_KZG_OK {
expectedProof := KZGProof(getBytes48(filepath.Join(test, "proof.txt")))
require.Equal(t, proof, expectedProof, test)
} else {
require.NoFileExists(t, filepath.Join(test, "proof.txt"))
}
}
}
func TestVerifyKZGProof(t *testing.T) {
type Test struct {
TestCases []struct {
Polynomial Blob `json:"Polynomial"`
Proof Bytes48 `json:"Proof"`
Commitment Bytes48 `json:"Commitment"`
InputPoint Bytes32 `json:"InputPoint"`
ClaimedValue Bytes32 `json:"ClaimedValue"`
tests, err := filepath.Glob(verifyKZGProofTests)
require.NoError(t, err)
for _, test := range tests {
commitment := getBytes48(filepath.Join(test, "commitment.txt"))
inputPoint := getBytes32(filepath.Join(test, "input_point.txt"))
claimedValue := getBytes32(filepath.Join(test, "claimed_value.txt"))
proof := getBytes48(filepath.Join(test, "proof.txt"))
ok, ret := VerifyKZGProof(commitment, inputPoint, claimedValue, proof)
if ret == C_KZG_OK {
expectedOk := getBoolean(filepath.Join(test, "ok.txt"))
require.Equal(t, ok, expectedOk, test)
} else {
require.NoFileExists(t, filepath.Join(test, "ok.txt"))
}
}
}
testFile, err := os.Open("../rust/test_vectors/public_verify_kzg_proof.json")
require.NoError(t, err)
defer testFile.Close()
test := Test{}
err = json.NewDecoder(testFile).Decode(&test)
func TestVerifyBlobKZGProof(t *testing.T) {
tests, err := filepath.Glob(verifyBlobKZGProofTests)
require.NoError(t, err)
for _, test := range tests {
blob := getBlob(filepath.Join(test, "blob.txt"))
commitment := getBytes48(filepath.Join(test, "commitment.txt"))
proof := getBytes48(filepath.Join(test, "proof.txt"))
for _, tc := range test.TestCases {
result, ret := VerifyKZGProof(tc.Commitment, tc.InputPoint, tc.ClaimedValue, tc.Proof)
require.Equal(t, C_KZG_OK, ret)
require.True(t, result)
ok, ret := VerifyBlobKZGProof(blob, commitment, proof)
if ret == C_KZG_OK {
expectedOk := getBoolean(filepath.Join(test, "ok.txt"))
require.Equal(t, ok, expectedOk, test)
} else {
require.NoFileExists(t, filepath.Join(test, "ok.txt"))
}
}
}
func TestVerifyBlobKZGProofBatch(t *testing.T) {
tests, err := filepath.Glob(verifyBlobKZGProofBatchTests)
require.NoError(t, err)
for _, test := range tests {
blobFiles, err := filepath.Glob(filepath.Join(test, "blobs/*"))
require.NoError(t, err)
blobs := make([]Blob, len(blobFiles))
for i, blobFile := range blobFiles {
blobs[i] = getBlob(blobFile)
}
commitmentFiles, err := filepath.Glob(filepath.Join(test, "commitments/*"))
require.NoError(t, err)
commitments := make([]Bytes48, len(commitmentFiles))
for i, commitmentFile := range commitmentFiles {
commitments[i] = getBytes48(commitmentFile)
}
proofFiles, err := filepath.Glob(filepath.Join(test, "proofs/*"))
require.NoError(t, err)
proofs := make([]Bytes48, len(proofFiles))
for i, proofFile := range proofFiles {
proofs[i] = getBytes48(proofFile)
}
require.Len(t, commitments, len(blobs))
require.Len(t, proofs, len(blobs))
ok, ret := VerifyBlobKZGProofBatch(blobs, commitments, proofs)
if ret == C_KZG_OK {
expectedOk := getBoolean(filepath.Join(test, "ok.txt"))
require.Equal(t, ok, expectedOk, test)
} else {
require.NoFileExists(t, filepath.Join(test, "ok.txt"))
}
}
}
@ -168,15 +298,20 @@ func Benchmark(b *testing.B) {
const length = 64
blobs := [length]Blob{}
commitments := [length]Bytes48{}
proofs := [length]Bytes48{}
fields := [length]Bytes32{}
for i := 0; i < length; i++ {
blobs[i] = GetRandBlob(int64(i))
commitment, _ := BlobToKZGCommitment(blobs[i])
blob := GetRandBlob(int64(i))
commitment, ret := BlobToKZGCommitment(blob)
require.Equal(b, ret, C_KZG_OK)
proof, ret := ComputeBlobKZGProof(blob)
require.Equal(b, ret, C_KZG_OK)
blobs[i] = blob
commitments[i] = Bytes48(commitment)
proofs[i] = Bytes48(proof)
fields[i] = GetRandFieldElement(int64(i))
}
z := Bytes32{1, 2, 3}
y := Bytes32{4, 5, 6}
trustedProof, _ := ComputeAggregateKZGProof(blobs[:1])
proof := Bytes48(trustedProof)
///////////////////////////////////////////////////////////////////////////
// Public functions
@ -184,39 +319,38 @@ func Benchmark(b *testing.B) {
b.Run("BlobToKZGCommitment", func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, ret := BlobToKZGCommitment(blobs[0])
require.Equal(b, C_KZG_OK, ret)
BlobToKZGCommitment(blobs[0])
}
})
b.Run("ComputeKZGProof", func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, ret := ComputeKZGProof(blobs[0], z)
require.Equal(b, C_KZG_OK, ret)
ComputeKZGProof(blobs[0], fields[0])
}
})
b.Run("ComputeBlobKZGProof", func(b *testing.B) {
for n := 0; n < b.N; n++ {
ComputeBlobKZGProof(blobs[0])
}
})
b.Run("VerifyKZGProof", func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, ret := VerifyKZGProof(commitments[0], z, y, proof)
require.Equal(b, C_KZG_OK, ret)
VerifyKZGProof(commitments[0], fields[0], fields[1], proofs[0])
}
})
b.Run("VerifyBlobKZGProof", func(b *testing.B) {
for n := 0; n < b.N; n++ {
VerifyBlobKZGProof(blobs[0], commitments[0], proofs[0])
}
})
for i := 1; i <= len(blobs); i *= 2 {
b.Run(fmt.Sprintf("ComputeAggregateKZGProof(blobs=%v)", i), func(b *testing.B) {
b.Run(fmt.Sprintf("VerifyBlobKZGProofBatch(count=%v)", i), func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, ret := ComputeAggregateKZGProof(blobs[:i])
require.Equal(b, C_KZG_OK, ret)
}
})
}
for i := 1; i <= len(blobs); i *= 2 {
b.Run(fmt.Sprintf("VerifyAggregateKZGProof(blobs=%v)", i), func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, ret := VerifyAggregateKZGProof(blobs[:i], commitments[:i], proof)
require.Equal(b, C_KZG_OK, ret)
VerifyBlobKZGProofBatch(blobs[:i], commitments[:i], proofs[:i])
}
})
}
@ -226,8 +360,8 @@ func Benchmark(b *testing.B) {
///////////////////////////////////////////////////////////////////////////
for i := 2; i <= 20; i += 2 {
var numBytes = int64(1 << i)
var bytes = make([]byte, numBytes)
numBytes := int64(1 << i)
bytes := make([]byte, numBytes)
b.Run(fmt.Sprintf("sha256(size=%v)", HumanBytes(numBytes)), func(b *testing.B) {
b.SetBytes(numBytes)
for n := 0; n < b.N; n++ {