Skip to content

Commit

Permalink
refactor: use runtime.KeepAlive to prevent GC memory release (dashpay#36
Browse files Browse the repository at this point in the history
)

* refactor: use runtime.KeepAlive to prevent GC memory release

* refactor: change a way how CGO links deps, add gmp as required dep

* fix: update build-test.yaml and Makefile

* fix: update Makefile

* fix: update Makefile
  • Loading branch information
shotonoff authored Jun 30, 2022
1 parent f96e103 commit a90ffba
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 29 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/build-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ jobs:
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install valgrind -y
sudo apt-get install snap -y
sudo apt-get install -qq --yes valgrind snap libgmp-dev libsodium-dev
sudo apt-get remove --purge cmake -y
sudo snap install cmake --classic
hash -r
Expand Down
29 changes: 16 additions & 13 deletions go-bindings/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
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
Expand All @@ -12,15 +8,23 @@ COVERAGE_OUTPUT ?= coverage.out

default: prepare vet test clean

MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
CURR_DIR := $(dir $(MAKEFILE_PATH))

CGO_ENABLED := 1

CGO_LDFLAGS ?= "-L$(CURR_DIR)../build/_deps/sodium-build \
-L$(CURR_DIR)../build/_deps/relic-build/lib \
-L$(CURR_DIR)../build/src \
-lbls-dash -lrelic_s -lgmp"

CGO_CXXFLAGS ?= "-I$(CURR_DIR)../build/_deps/relic-src/include \
-I$(CURR_DIR)../build/_deps/relic-build/include \
-I$(CURR_DIR)../build/src"

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
@mkdir -p ../build/src/bls-dash
cp -rv ../src/* ../build/src/bls-dash

fmt: ## Run go fmt to format Go files
$(GO) fmt
Expand All @@ -43,4 +47,3 @@ help: ## Show This Help
clean: ## Clean up transient (generated) files
$(GO) clean
rm -f $(COVERAGE_OUTPUT)
rm -rf $(CACHE_DIR)
32 changes: 26 additions & 6 deletions go-bindings/elements.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

package blschia

// #cgo LDFLAGS: -lbls-dash -lrelic_s -lsodium
// #cgo LDFLAGS: -lbls-dash -lrelic_s -lsodium -lgmp
// #cgo CXXFLAGS: -std=c++14
// #include <stdbool.h>
// #include <stdlib.h>
Expand Down Expand Up @@ -56,19 +56,26 @@ func (g *G1Element) Mul(sk *PrivateKey) *G1Element {
val: C.CG1ElementMul(g.val, sk.val),
}
runtime.SetFinalizer(&el, func(el *G1Element) { el.free() })
runtime.KeepAlive(g)
runtime.KeepAlive(sk)
return &el
}

// EqualTo returns true if the elements are equal otherwise returns false
// this method is the binding of the equality operation
func (g *G1Element) EqualTo(el *G1Element) bool {
return bool(C.CG1ElementIsEqual(g.val, el.val))
val := bool(C.CG1ElementIsEqual(g.val, el.val))
runtime.KeepAlive(g)
runtime.KeepAlive(el)
return val
}

// IsValid returns true if a state of G1Element (public key) is valid
// this method is the binding of the bls::G1Element::IsValid
func (g *G1Element) IsValid() bool {
return bool(C.CG1ElementIsValid(g.val))
isValid := bool(C.CG1ElementIsValid(g.val))
runtime.KeepAlive(g)
return isValid
}

// Add performs addition operation on the passed G1Element (public key) and returns a new G1Element (public key)
Expand All @@ -78,21 +85,27 @@ func (g *G1Element) Add(el *G1Element) *G1Element {
val: C.CG1ElementAdd(g.val, el.val),
}
runtime.SetFinalizer(&res, func(res *G1Element) { res.free() })
runtime.KeepAlive(g)
runtime.KeepAlive(el)
return &res
}

// Fingerprint returns a fingerprint of G1Element (public key)
// this method is a binding of the bls::G1Element::GetFingerprint
func (g *G1Element) Fingerprint() int {
return int(C.CG1ElementGetFingerprint(g.val))
fp := int(C.CG1ElementGetFingerprint(g.val))
runtime.KeepAlive(g)
return fp
}

// Serialize serializes G1Element (public key) into a slice of bytes and returns it
// this method is a binding of the bls::G1Element::Serialize
func (g *G1Element) Serialize() []byte {
ptr := C.CG1ElementSerialize(g.val)
defer C.free(unsafe.Pointer(ptr))
return C.GoBytes(ptr, C.CG1ElementSize())
bytes := C.GoBytes(ptr, C.CG1ElementSize())
runtime.KeepAlive(g)
return bytes
}

// HexString returns a hex string representation of serialized data
Expand Down Expand Up @@ -131,6 +144,7 @@ func G2ElementFromBytes(data []byte) (*G2Element, error) {
// this method is the binding of the equality operation
func (g *G2Element) EqualTo(el *G2Element) bool {
isEqual := bool(C.CG2ElementIsEqual(g.val, el.val))
runtime.KeepAlive(g)
return isEqual
}

Expand All @@ -141,6 +155,8 @@ func (g *G2Element) Add(el *G2Element) *G2Element {
val: C.CG2ElementAdd(g.val, el.val),
}
runtime.SetFinalizer(&res, func(res *G2Element) { res.free() })
runtime.KeepAlive(g)
runtime.KeepAlive(el)
return &res
}

Expand All @@ -151,6 +167,8 @@ func (g *G2Element) Mul(sk *PrivateKey) *G2Element {
val: C.CG2ElementMul(g.val, sk.val),
}
runtime.SetFinalizer(&el, func(el *G2Element) { el.free() })
runtime.KeepAlive(g)
runtime.KeepAlive(sk)
return &el
}

Expand All @@ -159,7 +177,9 @@ func (g *G2Element) Mul(sk *PrivateKey) *G2Element {
func (g *G2Element) Serialize() []byte {
ptr := C.CG2ElementSerialize(g.val)
defer C.free(unsafe.Pointer(ptr))
return C.GoBytes(ptr, C.CG2ElementSize())
bytes := C.GoBytes(ptr, C.CG2ElementSize())
runtime.KeepAlive(g)
return bytes
}

// HexString returns a hex string representation of serialized data
Expand Down
16 changes: 13 additions & 3 deletions go-bindings/privatekey.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

package blschia

// #cgo LDFLAGS: -lbls-dash -lrelic_s -lsodium
// #cgo LDFLAGS: -lbls-dash -lrelic_s -lsodium -lgmp
// #cgo CXXFLAGS: -std=c++14
// #include <stdbool.h>
// #include <stdlib.h>
Expand Down Expand Up @@ -58,6 +58,7 @@ func (sk *PrivateKey) G1Element() (*G1Element, error) {
return nil, errFromC()
}
runtime.SetFinalizer(&el, func(el *G1Element) { el.free() })
runtime.KeepAlive(sk)
return &el, nil
}

Expand All @@ -72,6 +73,7 @@ func (sk *PrivateKey) G2Element() (*G2Element, error) {
if bool(cDidErr) {
return nil, errFromC()
}
runtime.KeepAlive(sk)
return &el, nil
}

Expand All @@ -82,6 +84,8 @@ func (sk *PrivateKey) G2Power(el *G2Element) *G2Element {
val: C.CPrivateKeyGetG2Power(sk.val, el.val),
}
runtime.SetFinalizer(&sig, func() { sig.free() })
runtime.KeepAlive(sk)
runtime.KeepAlive(el)
return &sig
}

Expand All @@ -90,7 +94,9 @@ func (sk *PrivateKey) G2Power(el *G2Element) *G2Element {
func (sk *PrivateKey) Serialize() []byte {
ptr := C.CPrivateKeySerialize(sk.val)
defer C.SecFree(ptr)
return C.GoBytes(ptr, C.int(C.CPrivateKeySizeBytes()))
bytes := C.GoBytes(ptr, C.int(C.CPrivateKeySizeBytes()))
runtime.KeepAlive(sk)
return bytes
}

// PrivateKeyAggregate securely aggregates multiple private keys into one
Expand All @@ -102,13 +108,17 @@ func PrivateKeyAggregate(sks ...*PrivateKey) *PrivateKey {
val: C.CPrivateKeyAggregate(cPrivKeyArrPtr, C.size_t(len(sks))),
}
runtime.SetFinalizer(&sk, func(p *PrivateKey) { p.free() })
runtime.KeepAlive(sks)
return &sk
}

// EqualTo tests if one PrivateKey is equal to another
// this method is the binding of the equality operation
func (sk *PrivateKey) EqualTo(other *PrivateKey) bool {
return bool(C.CPrivateKeyIsEqual(sk.val, other.val))
isEqual := bool(C.CPrivateKeyIsEqual(sk.val, other.val))
runtime.KeepAlive(sk)
runtime.KeepAlive(other)
return isEqual
}

// HexString returns a hex string representation of serialized data
Expand Down
Loading

0 comments on commit a90ffba

Please sign in to comment.