mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
02107450d0
4e070243ae chore: bump version to 1.3.3 (#99) d93956254e ci: disable Go bindings CI for macos for now (#98) ae40c5c86d Merge pull request #97 from PastaPastaPasta/refac/pybind-bump-2.13.6 e835ece935 refactor: bump pybind version to 2.13.6 eda5d6a402 chore: change of gmp source (#95) 61f95aa80e chore: cleanup 6.2.1 left overs (#96) adbd094409 Merge pull request #92 from kwvg/darwin_gmp 062ee6726b Merge pull request #90 from UdjinM6/fix_aarch_arch 3538d8b033 fix: aarch64 is not supported, should set ARCH to RELIC_NONE e27a62f4a2 revert: disable gmp if targeting darwin on aarch64 when on 'auto' bb2fe6ee55 build: enforce minimum version of libgmp based on arch and platform 9832b7a132 build: replace deprecated macros `AC_PROG_CC_C99` and `AM_PROG_CC_C_O` b2428718b9 Merge pull request #91 from UdjinM6/fix_macos_test_build 3ffa7fa2b6 chore: bump version to 1.3.2 (#94) 0f4efc9327 Merge pull request #88 from HashEngineering/feat/support-android a181889489 fix: rust bindings build for macos (#89) 738d187359 fix: detect gmp via brew earlier ce4d6a47b6 fix: install libtool 4fa46ccaff fix: use macos-latest for test build 69bdc1aac7 Merge pull request #85 from kwvg/debug 39791d4e31 build: print build options after configure 73106a0121 build: use `-mbranch-protection=bti` on supporting `aarch64` compilers 6a3c28f6ca build: use stricter `-Werror` when testing compile flags 7a1b227637 build: rename {`NO`}`WARN_CFLAGS` to {`NO`}`WARN_FLAGS`, use with C{++} 28bea63838 build: set {`NO`}`WARN_CFLAGS` flags if not overridden and uniformly 32c2f0f5f8 trivial: rename `CORE_CXXFLAGS` to `CORE_FLAGS`, use with C{++} b630c2c323 build: append `HARDENED_FLAGS` to `AM_CFLAGS` e6008148e4 trivial: rename `HARDENED_CXXFLAGS` to `HARDENED_FLAGS` af0e3daef5 build: subsume `PI{C,E}_FLAGS` into `HARDENED_CXXFLAGS` 9ff8618a1b build: expand `--disable-optimizations` to include `-O0` and `-fwrapv` 3036b83181 build: expand `--enable-debug` to include `-O0`, `-ftrapv` and dbg info c90d43d43b build: add check to see if `CFLAGS` has been overridden 2d77f7ae49 build: remove vestigial `LIBTOOL_{CXX,CPP,LD}FLAGS`, `HARDENED_CPPFLAGS` 883a098868 build: autodetect i?86 and arm as 32-bit deb3269820 build: don't specify exact `{CPU_}ARCH` if optimizations are disabled 720d49a44b trivial: fix indentation for `want_backend` check f9328320af build: use `easy` backend if optimizations are disabled unless specified 3687cd59e0 build: define new flag `--enable-optimizations` f82bfee5dd build: ensure help string format matches Autotool defaults d68920063e build: define arguments as `--enable-[term]` instead of `--disable-[term]` 7f41e7dd16 fix: support android 1c2fc79c19 feat(rust): allow to move G1 and G2 elements between threads (#87) 3540b8bbed feat: debug with data hex (#86) git-subtree-dir: src/dashbls git-subtree-split: 4e070243aed142bc458472f8807ab77527dd879a |
||
---|---|---|
.. | ||
benchmark.py | ||
CMakeLists.txt | ||
pythonbindings.cpp | ||
README.md | ||
test.py |
Python bindings
Use the full power and efficiency of the C++ bls library, but in a few lines of python!
Install
pip3 install blspy
Alternatively, to install from source, run the following, in the project root directory:
pip3 install .
Cmake, a c++ compiler, and a recent version of pip3 (v18) are required for source install. GMP(speed) is an optional dependency. Public keys are G1Elements, and signatures are G2Elements.
Then, to use:
Import the library
from blspy import (PrivateKey, Util, AugSchemeMPL, PopSchemeMPL,
G1Element, G2Element)
Creating keys and signatures
# Example seed, used to generate private key. Always use
# a secure RNG with sufficient entropy to generate a seed (at least 32 bytes).
seed: bytes = bytes([0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192,
19, 18, 12, 89, 6, 220, 18, 102, 58, 209, 82,
12, 62, 89, 110, 182, 9, 44, 20, 254, 22])
sk: PrivateKey = AugSchemeMPL.key_gen(seed)
pk: G1Element = sk.get_g1()
message: bytes = bytes([1, 2, 3, 4, 5])
signature: G2Element = AugSchemeMPL.sign(sk, message)
# Verify the signature
ok: bool = AugSchemeMPL.verify(pk, message, signature)
assert ok
Serializing keys and signatures to bytes
sk_bytes: bytes = bytes(sk) # 32 bytes
pk_bytes: bytes = bytes(pk) # 48 bytes
signature_bytes: bytes = bytes(signature) # 96 bytes
print(sk_bytes.hex(), pk_bytes.hex(), signature_bytes.hex())
Loading keys and signatures from bytes
sk = PrivateKey.from_bytes(sk_bytes)
pk = G1Element.from_bytes(pk_bytes)
signature = G2Element.from_bytes(signature_bytes)
Create aggregate signatures
# Generate some more private keys
seed = bytes([1]) + seed[1:]
sk1: PrivateKey = AugSchemeMPL.key_gen(seed)
seed = bytes([2]) + seed[1:]
sk2: PrivateKey = AugSchemeMPL.key_gen(seed)
message2: bytes = bytes([1, 2, 3, 4, 5, 6, 7])
# Generate first sig
pk1: G1Element = sk1.get_g1()
sig1: G2Element = AugSchemeMPL.sign(sk1, message)
# Generate second sig
pk2: G1Element = sk2.get_g1()
sig2: G2Element = AugSchemeMPL.sign(sk2, message2)
# Signatures can be non-interactively combined by anyone
agg_sig: G2Element = AugSchemeMPL.aggregate([sig1, sig2])
ok = AugSchemeMPL.aggregate_verify([pk1, pk2], [message, message2], agg_sig)
Arbitrary trees of aggregates
seed = bytes([3]) + seed[1:]
sk3: PrivateKey = AugSchemeMPL.key_gen(seed)
pk3: G1Element = sk3.get_g1()
message3: bytes = bytes([100, 2, 254, 88, 90, 45, 23])
sig3: G2Element = AugSchemeMPL.sign(sk3, message3)
agg_sig_final: G2Element = AugSchemeMPL.aggregate([agg_sig, sig3])
ok = AugSchemeMPL.aggregate_verify([pk1, pk2, pk3], [message, message2, message3], agg_sig_final)
Very fast verification with Proof of Possession scheme
# If the same message is signed, you can use Proof of Posession (PopScheme) for efficiency
# A proof of possession MUST be passed around with the PK to ensure security.
pop_sig1: G2Element = PopSchemeMPL.sign(sk1, message)
pop_sig2: G2Element = PopSchemeMPL.sign(sk2, message)
pop_sig3: G2Element = PopSchemeMPL.sign(sk3, message)
pop1: G2Element = PopSchemeMPL.pop_prove(sk1)
pop2: G2Element = PopSchemeMPL.pop_prove(sk2)
pop3: G2Element = PopSchemeMPL.pop_prove(sk3)
ok = PopSchemeMPL.pop_verify(pk1, pop1)
ok = PopSchemeMPL.pop_verify(pk2, pop2)
ok = PopSchemeMPL.pop_verify(pk3, pop3)
pop_sig_agg: G2Element = PopSchemeMPL.aggregate([pop_sig1, pop_sig2, pop_sig3])
ok = PopSchemeMPL.fast_aggregate_verify([pk1, pk2, pk3], message, pop_sig_agg)
# Aggregate public key, indistinguishable from a single public key
pop_agg_pk: G1Element = pk1 + pk2 + pk3
ok = PopSchemeMPL.verify(pop_agg_pk, message, pop_sig_agg)
# Aggregate private keys
pop_agg_sk: PrivateKey = PrivateKey.aggregate([sk1, sk2, sk3])
ok = PopSchemeMPL.sign(pop_agg_sk, message) == pop_sig_agg
HD keys using EIP-2333
master_sk: PrivateKey = AugSchemeMPL.key_gen(seed)
child: PrivateKey = AugSchemeMPL.derive_child_sk(master_sk, 152)
grandchild: PrivateKey = AugSchemeMPL.derive_child_sk(child, 952)
master_pk: G1Element = master_sk.get_g1()
child_u: PrivateKey = AugSchemeMPL.derive_child_sk_unhardened(master_sk, 22)
grandchild_u: PrivateKey = AugSchemeMPL.derive_child_sk_unhardened(child_u, 0)
child_u_pk: G1Element = AugSchemeMPL.derive_child_pk_unhardened(master_pk, 22)
grandchild_u_pk: G1Element = AugSchemeMPL.derive_child_pk_unhardened(child_u_pk, 0)
ok = (grandchild_u_pk == grandchild_u.get_g1())