forked from dashpay/dash
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request dashpay#28 from shotonoff/TD-17-upgrade-go-binding…
…s-to-upstream-v1.0.7 TD-17 Upgrade go-bindings to upstream v1.0.7
- Loading branch information
Showing
28 changed files
with
3,190 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
!Makefile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
SRC_DIR=$(PWD)/../src | ||
BUILD_DIR=$(PWD)/../build | ||
CACHE_DIR=$(PWD)/cache | ||
|
||
CGO_LDFLAGS="-L$(CACHE_DIR)/lib -lbls-dash -lrelic_s -lgmp" | ||
CGO_CXXFLAGS="-I$(CACHE_DIR)" | ||
|
||
GO="go" | ||
COVERAGE_OUTPUT ?= coverage.out | ||
|
||
.PHONY: default vet test clean | ||
|
||
default: prepare vet test clean | ||
|
||
prepare: | ||
ifeq ("$(wildcard $(CACHE_DIR))", "") | ||
@mkdir -p $(CACHE_DIR)/bls-dash | ||
@mkdir -p $(CACHE_DIR)/lib | ||
@find $(BUILD_DIR) -name "*.a" -exec cp {} $(CACHE_DIR)/lib \; | ||
@cp -r $(BUILD_DIR)/_deps/relic-src/include/* $(CACHE_DIR) | ||
@cp -r $(BUILD_DIR)/_deps/relic-build/include/* $(CACHE_DIR) | ||
@cp -r $(SRC_DIR)/* $(CACHE_DIR)/bls-dash | ||
endif | ||
|
||
fmt: ## Run go fmt to format Go files | ||
$(GO) fmt | ||
|
||
test: ## Run a basic test suite | ||
CGO_CXXFLAGS=$(CGO_CXXFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) $(GO) test | ||
|
||
cover: ## Run tests and generate test coverage file, output coverage results and HTML coverage file. | ||
CGO_CXXFLAGS=$(CGO_CXXFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) $(GO) test -coverprofile $(COVERAGE_OUTPUT) | ||
CGO_CXXFLAGS=$(CGO_CXXFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) $(GO) tool cover -func=$(COVERAGE_OUTPUT) | ||
CGO_CXXFLAGS=$(CGO_CXXFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) $(GO) tool cover -html=$(COVERAGE_OUTPUT) | ||
rm -f $(COVERAGE_OUTPUT) | ||
|
||
vet: ## Go vet all project code | ||
CGO_CXXFLAGS=$(CGO_CXXFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) go vet ./... | ||
|
||
help: ## Show This Help | ||
@for line in $$(cat Makefile | grep "##" | grep -v "grep" | sed "s/:.*##/:/g" | sed "s/\ /!/g"); do verb=$$(echo $$line | cut -d ":" -f 1); desc=$$(echo $$line | cut -d ":" -f 2 | sed "s/!/\ /g"); printf "%-30s--%s\n" "$$verb" "$$desc"; done | ||
|
||
clean: ## Clean up transient (generated) files | ||
$(GO) clean | ||
rm -f $(COVERAGE_OUTPUT) | ||
rm -rf $(CACHE_DIR) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
## bls-signatures | ||
|
||
Go library that implements BLS signatures with aggregation as | ||
in [Boneh, Drijvers, Neven 2018](https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html), using the relic | ||
toolkit for cryptographic primitives (pairings, EC, hashing). | ||
|
||
This library is a Go port of the [Chia Network's BLS lib](https://github.com/Chia-Network/bls-signatures). | ||
|
||
### Usage | ||
|
||
```bash | ||
go get github.com/dashpay/bls-signatures/go-bindings | ||
``` | ||
|
||
### Creating keys and signatures | ||
|
||
```go | ||
// seed data must not be less 32 bytes length | ||
seed := []byte{ | ||
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, | ||
} | ||
|
||
// create a scheme, available three schemes: BasicSchemeMPL, AugSchemeMPL and PopSchemeMPL | ||
scheme := NewAugSchemeMPL() | ||
|
||
// generate a private key using a seed data | ||
sk, err := scheme.KeyGen(seed) | ||
if err != nil { | ||
panic(err.Error()) | ||
} | ||
// get a public key | ||
pk, err := sk.G1Element() | ||
if err != nil { | ||
panic(err.Error()) | ||
} | ||
|
||
msg := []byte{1, 2, 3, 4, 5} | ||
|
||
// make a signature for a message | ||
sig := scheme.Sign(sk, msg) | ||
|
||
// verify the message signature | ||
if !scheme.Verify(pk, msg, sig) { | ||
panic("failed the signature verification") | ||
} | ||
``` | ||
|
||
### Serializing keys and signatures to bytes | ||
|
||
```go | ||
skBytes := sk.Serialize() | ||
pkBytes := pk.Serialize() | ||
sigBytes := sig.Serialize() | ||
``` | ||
|
||
### Loading keys and signatures from bytes | ||
|
||
```go | ||
sk1, _ := PrivateKeyFromBytes(skBytes, false) | ||
pk1, _ := G1ElementFromBytes(pkBytes) | ||
sig1, _ := G2ElementFromBytes(sigBytes) | ||
``` | ||
|
||
### Create aggregate signatures | ||
|
||
```go | ||
// Generate some more private keys | ||
seed[0] = 1 | ||
sk1, _ := scheme.KeyGen(seed) | ||
seed[0] = 2 | ||
sk2, _ := scheme.KeyGen(seed) | ||
msg2 := []byte{1, 2, 3, 4, 5,6, 7} | ||
|
||
// Generate first sig | ||
pk1, _ := sk1.G1Element() | ||
sig1 := scheme.Sign(sk1, msg) | ||
|
||
// Generate second sig | ||
pk2, _ := sk2.G1Element() | ||
sig2 := scheme.Sign(sk2, msg2) | ||
|
||
// Signatures can be non-interactively combined by anyone | ||
var aggSig = scheme.AggregateSigs(sig1, sig2) | ||
|
||
ok := scheme.AggregateVerify([]*G1Element{pk1, pk2}, [][]byte{msg, msg2}, aggSig) | ||
if !ok { | ||
panic("failed a verification of the aggregated signature ") | ||
} | ||
``` | ||
|
||
### Arbitrary trees of aggregates | ||
|
||
```go | ||
seed[0] = 3 | ||
sk3, _ := scheme.KeyGen(seed) | ||
pk3, _ := sk3.G1Element() | ||
msg3 := []byte{100, 2, 254, 88, 90, 45, 23} | ||
sig3 := scheme.Sign(sk3, msg3) | ||
|
||
aggSigFinal := scheme.AggregateSigs(aggSig, sig3) | ||
ok = scheme.AggregateVerify([]*G1Element{pk1, pk2, pk3}, [][]byte{msg, msg2, msg3}, aggSigFinal) | ||
if !ok { | ||
panic("failed a verification of the aggregated signature ") | ||
} | ||
``` | ||
|
||
### Very fast verification with Proof of Possession scheme | ||
|
||
```go | ||
// create a proof possession scheme | ||
popScheme := NewPopSchemeMPL() | ||
|
||
// If the same msg is signed, you can use Proof of Possession (PopScheme) for efficiency | ||
// A proof of possession MUST be passed around with the PK to ensure security. | ||
popSig1 := popScheme.Sign(sk1, msg) | ||
popSig2 := popScheme.Sign(sk2, msg) | ||
popSig3 := popScheme.Sign(sk3, msg) | ||
pop1 := popScheme.PopProve(sk1) | ||
pop2 := popScheme.PopProve(sk2) | ||
pop3 := popScheme.PopProve(sk3) | ||
|
||
ok = popScheme.PopVerify(pk1, pop1) | ||
if !ok { | ||
panic("failed a verification") | ||
} | ||
ok = popScheme.PopVerify(pk2, pop2) | ||
if !ok { | ||
panic("failed a verification") | ||
} | ||
ok = popScheme.PopVerify(pk3, pop3) | ||
if !ok { | ||
panic("failed a verification") | ||
} | ||
|
||
popSigAgg := popScheme.AggregateSigs(popSig1, popSig2, popSig3) | ||
ok = popScheme.FastAggregateVerify([]*G1Element{pk1, pk2, pk3}, msg, popSigAgg) | ||
if !ok { | ||
panic("failed a verification") | ||
} | ||
|
||
// Aggregate public key, indistinguishable from a single public key | ||
var popAggPk = pk1.Add(pk2).Add(pk3) | ||
ok = popScheme.Verify(popAggPk, msg, popSigAgg) | ||
if !ok { | ||
panic("failed a verification") | ||
} | ||
|
||
// Aggregate private keys | ||
var aggSk = PrivateKeyAggregate(sk1, sk2, sk3) | ||
ok = popScheme.Sign(aggSk, msg).EqualTo(popSigAgg) | ||
if !ok { | ||
panic("failed a verification") | ||
} | ||
``` | ||
|
||
### HD keys using [EIP-2333](https://github.com/ethereum/EIPs/pull/2333) | ||
|
||
```go | ||
// You can derive 'child' keys from any key, to create arbitrary trees. 4 byte indeces are used. | ||
// Hardened (more secure, but no parent pk -> child pk) | ||
masterSk, _ := augScheme.KeyGen(seed) | ||
|
||
// Unhardened (less secure, but can go from parent pk -> child pk), BIP32 style | ||
masterPk, _ := masterSk.G1Element() | ||
childU := augScheme.DeriveChildSkUnhardened(masterSk, 22) | ||
grandchildU := augScheme.DeriveChildSkUnhardened(childU, 0) | ||
|
||
childUPk := augScheme.DeriveChildPkUnhardened(masterPk, 22) | ||
grandchildUPk := augScheme.DeriveChildPkUnhardened(childUPk, 0) | ||
|
||
pkChildU, _ := grandchildU.G1Element() | ||
ok = grandchildUPk.EqualTo(pkChildU) | ||
if !ok { | ||
panic("keys are not equal") | ||
} | ||
``` | ||
|
||
Do not forget to handle the errors properly, this part of the code was omitted deliberately | ||
|
||
Use cases can be found in the [original lib's readme](../README.md). | ||
|
||
__Important note:__ Since this library is a port of the c++ library, so every piece of memory allocated by the library | ||
MUST be released on our own in GO. To release the memory is used `runtime.SetFinalizer` function, that will invoke | ||
automatically before GC release a memory allocated by GO. | ||
|
||
### Run tests | ||
|
||
To run tests, build the library, then go to the `go-bindings` folder in the build directory and run | ||
|
||
```bash | ||
make test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright (c) 2021 The Dash Core developers | ||
|
||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
|
||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include <string> | ||
#include <stdlib.h> | ||
#include "bls-dash/bls.hpp" | ||
#include "error.h" | ||
#include "blschia.h" | ||
|
||
std::string gErrMsg; | ||
|
||
void SecFree(void *p) { | ||
bls::Util::SecFree(p); | ||
} | ||
|
||
void** AllocPtrArray(size_t len) { | ||
// caller to free | ||
return (void**)bls::Util::SecAlloc<uint8_t>(sizeof(void*) * len); | ||
} | ||
|
||
void SetPtrArray(void** arrPtr, void* elemPtr, int index) { | ||
arrPtr[index] = elemPtr; | ||
} | ||
|
||
void FreePtrArray(void** inPtr) { | ||
bls::Util::SecFree(inPtr); | ||
} | ||
|
||
void* GetPtrAtIndex(void** arrPtr, int index) { | ||
return arrPtr[index]; | ||
} | ||
|
||
uint8_t* SecAllocBytes(size_t len) { | ||
return (uint8_t*)bls::Util::SecAlloc<uint8_t>(sizeof(uint8_t) * len); | ||
} | ||
|
||
void* GetAddressAtIndex(uint8_t* ptr, int index) { | ||
return (void*)&ptr[index]; | ||
} | ||
|
||
const char* GetLastErrorMsg() { | ||
return gErrMsg.c_str(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright (c) 2021 The Dash Core developers | ||
|
||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
|
||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#ifndef GO_BINDINGS_BLSCHIA_H_ | ||
#define GO_BINDINGS_BLSCHIA_H_ | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
#include "privatekey.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// Export the BLS SecFree method | ||
void SecFree(void *p); | ||
|
||
typedef void** carr; | ||
|
||
// Additional C++ helper funcs for allocations | ||
void** AllocPtrArray(size_t len); | ||
void SetPtrArray(void **arrPtr, void *elemPtr, int index); | ||
void FreePtrArray(void **inPtr); | ||
void* GetPtrAtIndex(void **arrPtr, int index); | ||
|
||
// Allocates an array of bytes with size of passed in len argument | ||
uint8_t* SecAllocBytes(size_t len); | ||
|
||
void* GetAddressAtIndex(uint8_t *ptr, int index); | ||
|
||
const char* GetLastErrorMsg(); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif // GO_BINDINGS_BLSCHIA_H_ |
Oops, something went wrong.