Skip to content

Commit

Permalink
Ethereum KZG polynomial commitments / EIP-4844 (part 1) (#239)
Browse files Browse the repository at this point in the history
* common error model for serialization of BLS signatures and KZG objects

* [KZG] add Ethereum's test vectors [skip ci]

* dump progress on KZG

* Stash: trusted setup generator

* implement cache optimized bit-reversal-permutation

* Add generator for the Ethereum test trusted setups

* implement naive deserialization for the trusted setup interchange format

* implement verify_kzg_proof

* Add test skeleton of verify KZG proof

* rebase import fixes
  • Loading branch information
mratsim authored Aug 13, 2023
1 parent 47b4f48 commit f57d071
Show file tree
Hide file tree
Showing 277 changed files with 4,937 additions and 755 deletions.
39 changes: 16 additions & 23 deletions benchmarks/bench_ethereum_bls_signatures.nim
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,15 @@ proc demoKeyGen(): tuple[seckey: SecretKey, pubkey: PublicKey] =
# The API for keygen is not ready in ethereum_bls_signatures
let ikm = rng.random_byte_seq(32)
doAssert cast[ptr BigInt[255]](result.seckey.addr)[].derive_master_secretKey(ikm)
let ok = result.pubkey.derive_pubkey(result.seckey)
doAssert ok == cttBLS_Success
result.pubkey.derive_pubkey(result.seckey)

proc benchDeserPubkey*(iters: int) =
let (sk, pk) = demoKeyGen()
var pk_comp{.noInit.}: array[48, byte]

# Serialize compressed
let ok = pk_comp.serialize_pubkey_compressed(pk)
doAssert ok == cttBLS_Success
let status = pk_comp.serialize_pubkey_compressed(pk)
doAssert status == cttCodecEcc_Success

var pk2{.noInit.}: PublicKey

Expand All @@ -57,8 +56,8 @@ proc benchDeserPubkeyUnchecked*(iters: int) =
var pk_comp{.noInit.}: array[48, byte]

# Serialize compressed
let ok = pk_comp.serialize_pubkey_compressed(pk)
doAssert ok == cttBLS_Success
let status = pk_comp.serialize_pubkey_compressed(pk)
doAssert status == cttCodecEcc_Success

var pk2{.noInit.}: PublicKey

Expand All @@ -73,12 +72,11 @@ proc benchDeserSig*(iters: int) =
sig_comp{.noInit.}: array[96, byte]
sig {.noInit.}: Signature

let status = sig.sign(sk, msg)
doAssert status == cttBLS_Success
sig.sign(sk, msg)

# Serialize compressed
let ok = sig_comp.serialize_signature_compressed(sig)
doAssert ok == cttBLS_Success
let status = sig_comp.serialize_signature_compressed(sig)
doAssert status == cttCodecEcc_Success

var sig2{.noInit.}: Signature

Expand All @@ -93,12 +91,11 @@ proc benchDeserSigUnchecked*(iters: int) =
sig_comp{.noInit.}: array[96, byte]
sig {.noInit.}: Signature

let status = sig.sign(sk, msg)
doAssert status == cttBLS_Success
sig.sign(sk, msg)

# Serialize compressed
let ok = sig_comp.serialize_signature_compressed(sig)
doAssert ok == cttBLS_Success
let status = sig_comp.serialize_signature_compressed(sig)
doAssert status == cttCodecEcc_Success

var sig2{.noInit.}: Signature

Expand All @@ -112,15 +109,14 @@ proc benchSign*(iters: int) =
var sig: Signature

bench("BLS signature", "BLS12_381 G2", iters):
let status = sig.sign(sk, msg)
sig.sign(sk, msg)

proc benchVerify*(iters: int) =
let (sk, pk) = demoKeyGen()
let msg = "Mr F was here"

var sig: Signature
let ok = sig.sign(sk, msg)
doAssert ok == cttBLS_Success
sig.sign(sk, msg)

bench("BLS verification", "BLS12_381", iters):
let valid = pk.verify(msg, sig)
Expand All @@ -136,8 +132,7 @@ proc benchFastAggregateVerify*(numKeys, iters: int) =
for i in 0 ..< numKeys:
let (sk, pk) = demoKeyGen()
validators[i] = pk
let status = sigs[i].sign(sk, msg)
doAssert status == cttBLS_Success
sigs[i].sign(sk, msg)

aggSig.aggregate_signatures_unstable_api(sigs)

Expand All @@ -155,8 +150,7 @@ proc benchVerifyMulti*(numSigs, iters: int) =
for i in 0 ..< numSigs:
let (sk, pk) = demoKeyGen()
sha256.hash(hashedMsg, "msg" & $i)
let status = sig.sign(sk, hashedMsg)
doAssert status == cttBLS_Success
sig.sign(sk, hashedMsg)
triplets.add (pk, hashedMsg, sig)

bench("BLS verif of " & $numSigs & " msgs by "& $numSigs & " pubkeys", "BLS12_381", iters):
Expand All @@ -178,8 +172,7 @@ proc benchVerifyBatched*(numSigs, iters: int) =
for i in 0 ..< numSigs:
let (sk, pk) = demoKeyGen()
sha256.hash(hashedMsg, "msg" & $i)
let status = sig.sign(sk, hashedMsg)
doAssert status == cttBLS_Success
sig.sign(sk, hashedMsg)

pubkeys.add pk
messages.add hashedMsg
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/bench_evm_modexp_dos.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import
../constantine/ethereum_evm_precompiles,
./platforms, ./bench_blueprint,

../constantine/platforms/codecs
../constantine/serialization/codecs

proc report(op: string, elapsedNs: int64, elapsedCycles: int64, iters: int) =
let ns = elapsedNs div iters
Expand Down
3 changes: 2 additions & 1 deletion benchmarks/bench_powmod.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import
../constantine/math/arithmetic,
../constantine/math/io/[io_bigints, io_fields],
../constantine/math/config/curves,
../constantine/platforms/[abstractions, codecs],
../constantine/platforms/abstractions,
../constantine/serialization/codecs,
../constantine/math_arbitrary_precision/arithmetic/bigints_views,
../helpers/prng_unsafe,
./platforms, ./bench_blueprint
Expand Down
4 changes: 2 additions & 2 deletions bindings_generators/gen_bindings.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ template genBindingsField*(Field: untyped) =
else:
{.push noconv, exportc, raises: [].} # No exceptions allowed

func `ctt _ Field _ unmarshalBE`(dst: var Field, src: openarray[byte]) =
func `ctt _ Field _ unmarshalBE`(dst: var Field, src: openarray[byte]): bool =
## Deserialize
unmarshalBE(dst, src)

func `ctt _ Field _ marshalBE`(dst: var openarray[byte], src: Field) =
func `ctt _ Field _ marshalBE`(dst: var openarray[byte], src: Field): bool =
marshalBE(dst, src)
# --------------------------------------------------------------------------------------
func `ctt _ Field _ is_eq`(a, b: Field): SecretBool =
Expand Down
12 changes: 11 additions & 1 deletion bindings_generators/gen_header.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ typedef __UINT64_TYPE__ uint64_t;
#else
#include <stdint.h>
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901
# define bool _Bool
#else
# define bool unsigned char
#endif
"""

proc genCttBaseTypedef*(): string =
Expand Down Expand Up @@ -115,6 +121,7 @@ void ctt_{libName}_init_NimMain(void);"""
# -------------------------------------------

let TypeMap {.compileTime.} = newStringTable({
"bool": "bool",
"SecretBool": "secret_bool",
"SecretWord": "secret_word"
})
Expand Down Expand Up @@ -201,7 +208,10 @@ macro collectBindings*(cBindingsStr: untyped, body: typed): untyped =
var name = $paramDef[j]
cBindings &= toCparam(name.split('`')[0], pType)

cBindings &= ");"
if fnDef.params[0].eqIdent"bool":
cBindings &= ") __attribute__((warn_unused_result));"
else:
cBindings &= ");"

if defined(CTT_GENERATE_HEADERS):
result = newConstStmt(cBindingsStr, newLit cBindings)
Expand Down
2 changes: 1 addition & 1 deletion constantine.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
packageName = "constantine"
version = "0.0.1"
author = "Status Research & Development GmbH"
author = "Mamy Ratsimbazafy"
description = "This library provides thoroughly tested and highly-optimized implementations of cryptography protocols."
license = "MIT or Apache License 2.0"

Expand Down
4 changes: 3 additions & 1 deletion constantine/ciphers/chacha20.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.

import ../platforms/[endians, views]
import
../platforms/views,
../serialization/endians

# ############################################################
#
Expand Down
27 changes: 27 additions & 0 deletions constantine/commitments/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Commitment schemes

https://en.wikipedia.org/wiki/Commitment_scheme

> A commitment scheme is a cryptographic primitive that allows one to commit to a chosen value (or chosen statement) while keeping it hidden to others, with the ability to reveal the committed value later. Commitment schemes are designed so that a party cannot change the value or statement after they have committed to it: that is, commitment schemes are binding.
## Use-cases

An important use-case missing from the Wikipedia article is:

"There exists a bundle of transactions that change the state of my database/ledger/blockchain to this state.". The whole bundle is not needed, only a short proof.

## KZG Polynomial Commitments

- Constant-Size Commitments to Polynomials and Their Applications\
Kate, Zaverucha, Goldberg, 2010\
https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf\
https://cacr.uwaterloo.ca/techreports/2010/cacr2010-10.pdf

- KZG commitments from the Lagrange basis without FFTs
Drake, 2020
https://ethresear.ch/t/kate-commitments-from-the-lagrange-basis-without-ffts/6950

- KZG Multiproofs
Feist, Khovratovich, 2020
https://dankradfeist.de/ethereum/2021/06/18/pcs-multiproofs.html\
https://github.com/khovratovich/Kate/blob/master/Kate_amortized.pdf
Loading

0 comments on commit f57d071

Please sign in to comment.