Skip to content

Commit

Permalink
KZG C API + namespace Ethereum BLS signature
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim committed Nov 23, 2023
1 parent d77bb79 commit 19cd5ef
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 93 deletions.
6 changes: 3 additions & 3 deletions benchmarks/bench_ethereum_bls_signatures.nim
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ proc benchVerifyMulti*(numSigs, iters: int) =
bench("BLS verif of " & $numSigs & " msgs by "& $numSigs & " pubkeys", "BLS12_381", iters):
for i in 0 ..< triplets.len:
let ok = triplets[i].pubkey.verify(triplets[i].msg, triplets[i].sig)
doAssert ok == cttBLS_Success
doAssert ok == cttEthBLS_Success

proc benchVerifyBatched*(numSigs, iters: int) =
## Verification of N pubkeys signing for N messages
Expand All @@ -185,7 +185,7 @@ proc benchVerifyBatched*(numSigs, iters: int) =

bench("BLS serial batch verify of " & $numSigs & " msgs by "& $numSigs & " pubkeys (with blinding)", "BLS12_381", iters):
let ok = batch_verify(pubkeys, messages, signatures, secureBlindingBytes)
doAssert ok == cttBLS_Success
doAssert ok == cttEthBLS_Success

proc benchVerifyBatchedParallel*(numSigs, iters: int) =
## Verification of N pubkeys signing for N messages
Expand Down Expand Up @@ -220,7 +220,7 @@ proc benchVerifyBatchedParallel*(numSigs, iters: int) =

bench("BLS parallel batch verify (" & $tp.numThreads & " threads) of " & $numSigs & " msgs by "& $numSigs & " pubkeys (with blinding)", "BLS12_381", iters):
let ok = tp.batch_verify_parallel(pubkeys, messages, signatures, secureBlindingBytes)
doAssert ok == cttBLS_Success, "invalid status: " & $ok
doAssert ok == cttEthBLS_Success, "invalid status: " & $ok

tp.shutdown()

Expand Down
3 changes: 2 additions & 1 deletion bindings/lib_constantine.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ import
./lib_hashes,
./lib_curves,
# Protocols
../constantine/ethereum_bls_signatures
../constantine/ethereum_bls_signatures,
../constantine/ethereum_eip4844_kzg
10 changes: 5 additions & 5 deletions constantine-rust/constantine-sys/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3725,11 +3725,11 @@ fn bindgen_test_layout_ctt_eth_bls_signature() {
#[repr(u8)]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub enum ctt_eth_bls_status {
cttBLS_Success = 0,
cttBLS_VerificationFailure = 1,
cttBLS_PointAtInfinity = 2,
cttBLS_ZeroLengthAggregation = 3,
cttBLS_InconsistentLengthsOfInputs = 4,
cttEthBLS_Success = 0,
cttEthBLS_VerificationFailure = 1,
cttEthBLS_PointAtInfinity = 2,
cttEthBLS_ZeroLengthAggregation = 3,
cttEthBLS_InconsistentLengthsOfInputs = 4,
}
extern "C" {
#[must_use]
Expand Down
86 changes: 43 additions & 43 deletions constantine/ethereum_bls_signatures.nim
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ type
## A BLS12_381 signature for BLS signature schemes with public keys on G1 and signatures on G2
raw: ECP_ShortW_Aff[Fp2[BLS12_381], G2]

CttBLSStatus* = enum
cttBLS_Success
cttBLS_VerificationFailure
cttBLS_PointAtInfinity
cttBLS_ZeroLengthAggregation
cttBLS_InconsistentLengthsOfInputs
CttEthBLSStatus* = enum
cttEthBLS_Success
cttEthBLS_VerificationFailure
cttEthBLS_PointAtInfinity
cttEthBLS_ZeroLengthAggregation
cttEthBLS_InconsistentLengthsOfInputs

# Comparisons
# ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -162,7 +162,7 @@ func serialize_pubkey_compressed*(dst: var array[48, byte], public_key: PublicKe
func serialize_signature_compressed*(dst: var array[96, byte], signature: Signature): CttCodecEccStatus {.libPrefix: prefix_ffi.} =
## Serialize a signature in compressed (Zcash) format
##
## Returns cttBLS_Success if successful
## Returns cttEthBLS_Success if successful
return dst.serialize_g2_compressed(signature.raw)

func deserialize_seckey*(dst: var SecretKey, src: array[32, byte]): CttCodecScalarStatus {.libPrefix: prefix_ffi.} =
Expand Down Expand Up @@ -232,7 +232,7 @@ func sign*(signature: var Signature, secret_key: SecretKey, message: openArray[b
## with the scheme
coreSign(signature.raw, secretKey.raw, message, sha256, 128, augmentation = "", DomainSeparationTag)

func verify*(public_key: PublicKey, message: openArray[byte], signature: Signature): CttBLSStatus {.libPrefix: prefix_ffi, genCharAPI.} =
func verify*(public_key: PublicKey, message: openArray[byte], signature: Signature): CttEthBLSStatus {.libPrefix: prefix_ffi, genCharAPI.} =
## Check that a signature is valid for a message
## under the provided public key.
## returns `true` if the signature is valid, `false` otherwise.
Expand All @@ -254,12 +254,12 @@ func verify*(public_key: PublicKey, message: openArray[byte], signature: Signatu

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
if bool(public_key.raw.isInf() or signature.raw.isInf()):
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = coreVerify(public_key.raw, message, signature.raw, sha256, 128, augmentation = "", DomainSeparationTag)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure

template unwrap[T: PublicKey|Signature](elems: openArray[T]): auto =
# Unwrap collection of high-level type into collection of low-level type
Expand Down Expand Up @@ -287,7 +287,7 @@ func aggregate_signatures_unstable_api*(aggregate_sig: var Signature, signatures
return
aggregate_sig.raw.aggregate(signatures.unwrap())

func fast_aggregate_verify*(pubkeys: openArray[PublicKey], message: openArray[byte], aggregate_sig: Signature): CttBLSStatus {.libPrefix: prefix_ffi, genCharAPI.} =
func fast_aggregate_verify*(pubkeys: openArray[PublicKey], message: openArray[byte], aggregate_sig: Signature): CttEthBLSStatus {.libPrefix: prefix_ffi, genCharAPI.} =
## Check that a signature is valid for a message
## under the aggregate of provided public keys.
## returns `true` if the signature is valid, `false` otherwise.
Expand All @@ -305,29 +305,29 @@ func fast_aggregate_verify*(pubkeys: openArray[PublicKey], message: openArray[by

if pubkeys.len == 0:
# IETF spec precondition
return cttBLS_ZeroLengthAggregation
return cttEthBLS_ZeroLengthAggregation

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
if aggregate_sig.raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

for i in 0 ..< pubkeys.len:
if pubkeys[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = fastAggregateVerify(
pubkeys.unwrap(),
message, aggregate_sig.raw,
sha256, 128, DomainSeparationTag)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure

# C FFI
func aggregate_verify*(pubkeys: ptr UncheckedArray[PublicKey],
messages: ptr UncheckedArray[View[byte]],
len: int,
aggregate_sig: Signature): CttBLSStatus {.libPrefix: prefix_ffi.} =
aggregate_sig: Signature): CttEthBLSStatus {.libPrefix: prefix_ffi.} =
## Verify the aggregated signature of multiple (pubkey, message) pairs
## returns `true` if the signature is valid, `false` otherwise.
##
Expand All @@ -348,27 +348,27 @@ func aggregate_verify*(pubkeys: ptr UncheckedArray[PublicKey],

if len == 0:
# IETF spec precondition
return cttBLS_ZeroLengthAggregation
return cttEthBLS_ZeroLengthAggregation

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
if aggregate_sig.raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

for i in 0 ..< len:
if pubkeys[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = aggregateVerify(
pubkeys.toOpenArray(len).unwrap(),
messages.toOpenArray(len),
aggregate_sig.raw,
sha256, 128, DomainSeparationTag)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure

# Nim
func aggregate_verify*[Msg](pubkeys: openArray[PublicKey], messages: openArray[Msg], aggregate_sig: Signature): CttBLSStatus =
func aggregate_verify*[Msg](pubkeys: openArray[PublicKey], messages: openArray[Msg], aggregate_sig: Signature): CttEthBLSStatus =
## Verify the aggregated signature of multiple (pubkey, message) pairs
## returns `true` if the signature is valid, `false` otherwise.
##
Expand All @@ -389,33 +389,33 @@ func aggregate_verify*[Msg](pubkeys: openArray[PublicKey], messages: openArray[M

if pubkeys.len == 0:
# IETF spec precondition
return cttBLS_ZeroLengthAggregation
return cttEthBLS_ZeroLengthAggregation

if pubkeys.len != messages.len:
return cttBLS_InconsistentLengthsOfInputs
return cttEthBLS_InconsistentLengthsOfInputs

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
if aggregate_sig.raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

for i in 0 ..< pubkeys.len:
if pubkeys[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = aggregateVerify(
pubkeys.unwrap(),
messages, aggregate_sig.raw,
sha256, 128, DomainSeparationTag)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure

# C FFI
func batch_verify*[Msg](pubkeys: ptr UncheckedArray[PublicKey],
messages: ptr UncheckedArray[View[byte]],
signatures: ptr UncheckedArray[Signature],
len: int,
secureRandomBytes: array[32, byte]): CttBLSStatus {.libPrefix: prefix_ffi.} =
secureRandomBytes: array[32, byte]): CttEthBLSStatus {.libPrefix: prefix_ffi.} =
## Verify that all (pubkey, message, signature) triplets are valid
## returns `true` if all signatures are valid, `false` if at least one is invalid.
##
Expand All @@ -441,28 +441,28 @@ func batch_verify*[Msg](pubkeys: ptr UncheckedArray[PublicKey],

if len == 0:
# IETF spec precondition
return cttBLS_ZeroLengthAggregation
return cttEthBLS_ZeroLengthAggregation

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
for i in 0 ..< len:
if pubkeys[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

for i in 0 ..< len:
if signatures[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = batchVerify(
pubkeys.toOpenArray(len).unwrap(),
messages,
signatures.toOpenArray(len).unwrap(),
sha256, 128, DomainSeparationTag, secureRandomBytes)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure

# Nim
func batch_verify*[Msg](pubkeys: openArray[PublicKey], messages: openarray[Msg], signatures: openArray[Signature], secureRandomBytes: array[32, byte]): CttBLSStatus =
func batch_verify*[Msg](pubkeys: openArray[PublicKey], messages: openarray[Msg], signatures: openArray[Signature], secureRandomBytes: array[32, byte]): CttEthBLSStatus =
## Verify that all (pubkey, message, signature) triplets are valid
## returns `true` if all signatures are valid, `false` if at least one is invalid.
##
Expand All @@ -488,25 +488,25 @@ func batch_verify*[Msg](pubkeys: openArray[PublicKey], messages: openarray[Msg],

if pubkeys.len == 0:
# IETF spec precondition
return cttBLS_ZeroLengthAggregation
return cttEthBLS_ZeroLengthAggregation

if pubkeys.len != messages.len or pubkeys.len != signatures.len:
return cttBLS_InconsistentLengthsOfInputs
return cttEthBLS_InconsistentLengthsOfInputs

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
for i in 0 ..< pubkeys.len:
if pubkeys[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

for i in 0 ..< signatures.len:
if signatures[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = batchVerify(
pubkeys.unwrap(),
messages,
signatures.unwrap(),
sha256, 128, DomainSeparationTag, secureRandomBytes)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure
26 changes: 13 additions & 13 deletions constantine/ethereum_bls_signatures_parallel.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ proc batch_verify_parallel*[Msg](
messages: ptr UncheckedArray[View[byte]],
signatures: ptr UncheckedArray[Signature],
len: int,
secureRandomBytes: array[32, byte]): CttBLSStatus {.libPrefix: prefix_ffi.} =
secureRandomBytes: array[32, byte]): CttEthBLSStatus {.libPrefix: prefix_ffi.} =
## Verify that all (pubkey, message, signature) triplets are valid
## returns `true` if all signatures are valid, `false` if at least one is invalid.
##
Expand Down Expand Up @@ -67,33 +67,33 @@ proc batch_verify_parallel*[Msg](

if len == 0:
# IETF spec precondition
return cttBLS_ZeroLengthAggregation
return cttEthBLS_ZeroLengthAggregation

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
for i in 0 ..< len:
if pubkeys[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

for i in 0 ..< len:
if signatures[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = tp.batchVerify_parallel(
pubkeys.toOpenArray(len).unwrap(),
messages,
signatures.toOpenArray(len).unwrap(),
sha256, 128, DomainSeparationTag, secureRandomBytes)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure

# Nim
proc batch_verify_parallel*[Msg](
tp: Threadpool,
pubkeys: openArray[PublicKey],
messages: openarray[Msg],
signatures: openArray[Signature],
secureRandomBytes: array[32, byte]): CttBLSStatus =
secureRandomBytes: array[32, byte]): CttEthBLSStatus =
## Verify that all (pubkey, message, signature) triplets are valid
## returns `true` if all signatures are valid, `false` if at least one is invalid.
##
Expand Down Expand Up @@ -122,25 +122,25 @@ proc batch_verify_parallel*[Msg](

if pubkeys.len == 0:
# IETF spec precondition
return cttBLS_ZeroLengthAggregation
return cttEthBLS_ZeroLengthAggregation

if pubkeys.len != messages.len or pubkeys.len != signatures.len:
return cttBLS_InconsistentLengthsOfInputs
return cttEthBLS_InconsistentLengthsOfInputs

# Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example
for i in 0 ..< pubkeys.len:
if pubkeys[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

for i in 0 ..< signatures.len:
if signatures[i].raw.isInf().bool:
return cttBLS_PointAtInfinity
return cttEthBLS_PointAtInfinity

let verified = tp.batchVerify_parallel(
pubkeys.unwrap(),
messages,
signatures.unwrap(),
sha256, 128, DomainSeparationTag, secureRandomBytes)
if verified:
return cttBLS_Success
return cttBLS_VerificationFailure
return cttEthBLS_Success
return cttEthBLS_VerificationFailure
Loading

0 comments on commit 19cd5ef

Please sign in to comment.