Skip to content

Commit

Permalink
Update libsodium impl and add benchmark test (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
tnasu authored Aug 18, 2021
1 parent 79b76eb commit f53ee28
Show file tree
Hide file tree
Showing 21 changed files with 548 additions and 311 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ test/fuzz/**/corpus
test/fuzz/**/crashers
test/fuzz/**/suppressions
test/fuzz/**/*.zip
crypto/vrf/internal/vrf/lib
crypto/vrf/internal/vrf/include
node/data
crypto/vrf/internal/vrf/sodium
40 changes: 20 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,20 @@ SRCPATH=$(shell pwd)
OUTPUT?=build/ostracon

INCLUDE = -I=${GOPATH}/src/github.com/line/ostracon -I=${GOPATH}/src -I=${GOPATH}/src/github.com/gogo/protobuf/protobuf
BUILD_TAGS?='ostracon'
BUILD_TAGS?=ostracon
VERSION := $(shell git describe --always)
CGO_OPTPTION=0
LIBSODIUM_TARGET=
PREPARE_LIBSODIUM_TARGET=
ifeq ($(LIBSODIUM), 1)
BUILD_TAGS='libsodium ostracon'
LIBSODIUM_TARGET=libsodium
ifneq ($(OS), Windows_NT)
ifeq ($(shell uname -s), Linux)
PREPARE_LIBSODIUM_TARGET=prepare-libsodium-linux
BUILD_TAGS += libsodium
endif
endif
endif
LIBSODIM_BUILD_TAGS='libsodium ostracon'
LD_FLAGS = -X github.com/line/ostracon/version.Version=$(VERSION)
BUILD_FLAGS = -mod=readonly -ldflags "$(LD_FLAGS)"
HTTPS_GIT := https://github.com/line/ostracon.git
DOCKER_BUF := docker run -v $(shell pwd):/workspace --workdir /workspace bufbuild/buf
CGO_ENABLED ?= 0
TARGET_OS ?= $(shell go env GOOS)
TARGET_ARCH ?= $(shell go env GOARCH)

# handle nostrip
ifeq (,$(findstring nostrip,$(OSTRACON_BUILD_OPTIONS)))
Expand Down Expand Up @@ -72,7 +66,7 @@ build: $(LIBSODIUM_TARGET)
CGO_ENABLED=1 go build $(BUILD_FLAGS) -tags "$(BUILD_TAGS)" -o $(OUTPUT) ./cmd/ostracon/
.PHONY: build

install:
install: $(LIBSODIUM_TARGET)
CGO_ENABLED=1 go install $(BUILD_FLAGS) -tags "$(BUILD_TAGS)" ./cmd/ostracon
.PHONY: install

Expand Down Expand Up @@ -151,15 +145,21 @@ install_abci:
########################################
### libsodium

prepare-libsodium-linux:
apt-get update && apt-get -y install libtool libboost-all-dev autoconf build-essential
VRF_ROOT = $(SRCPATH)/crypto/vrf/internal/vrf
LIBSODIUM_ROOT = $(VRF_ROOT)/libsodium
LIBSODIUM_OS = $(VRF_ROOT)/sodium/$(TARGET_OS)_$(TARGET_ARCH)

libsodium:
cd $(SRCPATH)/crypto/vrf/internal/vrf/libsodium && \
./autogen.sh && \
./configure --disable-shared --prefix="$(SRCPATH)/crypto/vrf/internal/vrf/" && \
$(MAKE) && \
$(MAKE) install
rm -rf $(LIBSODIUM_ROOT)
mkdir $(LIBSODIUM_ROOT)
git submodule update --init --recursive
@if [ ! -f $(LIBSODIUM_OS)/lib/libsodium.a ]; then \
cd $(LIBSODIUM_ROOT) && \
./autogen.sh && \
./configure --disable-shared --prefix="$(LIBSODIUM_OS)" && \
$(MAKE) && \
$(MAKE) install; \
fi

########################################
### Distribution
Expand Down Expand Up @@ -287,9 +287,9 @@ DOCKER_CMD = docker run --rm \
-v `pwd`:$(DOCKER_HOME) \
-w $(DOCKER_HOME)
DOCKER_IMG = golang:1.15-alpine
BUILD_CMD = apk add --update --no-cache git make gcc libc-dev build-base curl jq file gmp-dev clang \
BUILD_CMD = apk add --update --no-cache git make gcc libc-dev build-base curl jq bash file gmp-dev clang libtool autoconf automake \
&& cd $(DOCKER_HOME) \
&& make build-linux
&& LIBSODIUM=$(LIBSODIUM) make build-linux

# Login docker-container for confirmation building linux binary
build-shell:
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@ Ostracon is forked from Tendermint Core at 2021-03-15.

# Quick Start

## git clone
```shell
git clone https://github.com/line/ostracon.git
# or
git clone git@github.com:line/ostracon.git
```

### git clone with recursive if you want to use libsodium
```shell
git clone --recursive https://github.com/line/ostracon.git
# or
git clone --recursive git@github.com:line/ostracon.git
```

### git submodule if you forget to clone with submodule
```shell
git submodule update --init --recursive
```

## Local Standalone
**Build**
```sh
Expand Down
6 changes: 3 additions & 3 deletions crypto/composite/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ func (sk PrivKey) Sign(msg []byte) ([]byte, error) {
return sk.SignKey.Sign(msg)
}

// VRFProve generates a VRF Proof for given seed to generate a verifiable random.
func (sk PrivKey) VRFProve(seed []byte) (crypto.Proof, error) {
return sk.VrfKey.VRFProve(seed)
// VRFProve generates a VRF Proof for given message to generate a verifiable random.
func (sk PrivKey) VRFProve(message []byte) (crypto.Proof, error) {
return sk.VrfKey.VRFProve(message)
}

func (sk PrivKey) PubKey() crypto.PubKey {
Expand Down
18 changes: 10 additions & 8 deletions crypto/ed25519/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ed25519
import (
"bytes"
"crypto/subtle"
"encoding/hex"
"fmt"
"io"

Expand Down Expand Up @@ -60,9 +61,9 @@ func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
return signatureBytes, nil
}

// VRFProve generates a VRF Proof for given seed to generate a verifiable random.
func (privKey PrivKey) VRFProve(seed []byte) (crypto.Proof, error) {
proof, err := vrf.Prove(privKey[:], seed)
// VRFProve generates a VRF Proof for given message to generate a verifiable random.
func (privKey PrivKey) VRFProve(message []byte) (crypto.Proof, error) {
proof, err := vrf.Prove(privKey[:], message)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -172,14 +173,15 @@ func (pubKey PubKey) Type() string {
return KeyType
}

// VRFVerify verifies that the given VRF Proof was generated from the seed by the owner of this public key.
func (pubKey PubKey) VRFVerify(proof crypto.Proof, seed []byte) (crypto.Output, error) {
valid, err := vrf.Verify(pubKey[:], vrf.Proof(proof), seed)
// VRFVerify verifies that the given VRF Proof was generated from the message by the owner of this public key.
func (pubKey PubKey) VRFVerify(proof crypto.Proof, message []byte) (crypto.Output, error) {
valid, err := vrf.Verify(pubKey[:], vrf.Proof(proof), message)
if err != nil {
return nil, fmt.Errorf("the specified proof is not a valid ed25519 proof: %v", proof)
return nil, fmt.Errorf("the specified proof is not a valid ed25519 proof: err: %s", err.Error())
}
if !valid {
return nil, fmt.Errorf("the specified Proof is not generated with this pair-key: %v", proof)
return nil, fmt.Errorf("the specified Proof is not generated with this pair-key: %s",
hex.EncodeToString(proof))
}
output, err := vrf.ProofToHash(vrf.Proof(proof))
if err != nil {
Expand Down
40 changes: 40 additions & 0 deletions crypto/ed25519/ed25519_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ed25519_test

import (
"encoding/hex"
coniks "github.com/coniks-sys/coniks-go/crypto/vrf"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -28,3 +30,41 @@ func TestSignAndValidateEd25519(t *testing.T) {

assert.False(t, pubKey.VerifySignature(msg, sig))
}

func TestVRFProveAndVRFVerify(t *testing.T) {

privKey := ed25519.GenPrivKey()
pubKey := privKey.PubKey()

message, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000000")
proof, err := privKey.VRFProve(message)
assert.Nil(t, err)
assert.NotNil(t, proof)

output, err := pubKey.VRFVerify(proof, message)
assert.Nil(t, err)
assert.NotNil(t, output)

// error
{
message, _ = hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000001")
output, err = pubKey.VRFVerify(proof, message)
assert.NotNil(t, err)
assert.Nil(t, output)
}

// invalid
{
privateKey, _ := coniks.GenerateKey(nil)
copy(privKey[:], privateKey)
pubKey = privKey.PubKey()

proof, err = privKey.VRFProve(message)
assert.Nil(t, err)
assert.NotNil(t, proof)

output, err = pubKey.VRFVerify(proof, message)
assert.NotNil(t, err)
assert.Nil(t, output)
}
}
91 changes: 91 additions & 0 deletions crypto/vrf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# VRF

VRF implementation is set by `func init()` with `build` option

## Interface
* package/file
* line/ostracon/crypto/vrf
* `var defaultVrf vrfEd25519`
* vrf.go
* vrf_test.go
```go
type vrfEd25519 interface {
Prove(privateKey []byte, message []byte) (Proof, error)
Verify(publicKey []byte, proof Proof, message []byte) (bool, error)
ProofToHash(proof Proof) (Output, error)
```
## Implementations
Use `func init()` with `build` option
* package/file
* line/ostracon/crypto/vrf
* (r2ishiguro = default)
* `// +build !libsodium,!coniks`
* `func init() { defaultVrf = newVrfEd25519r2ishiguro() }`
* vrf_r2ishiguro.go
* (coniks)
* `// +build coniks`
* `func init() { defaultVrf = newVrfEd25519coniks() }`
* vrf_coniks.go
* vrf_coniks_test.go
* (libsodium)
* `// +build libsodium`
* `func init() { defaultVrf = newVrfEd25519libsodium() }`
* vrf_libsodium.go
* vrf_libsodium_test.go

### Status

| impl | available | memo |
|:---|:---|:---|
|r2ishiguro|o|(default)|
|coniks|x|no compatibility between *crypto ED25519* and *coniks ED25519* (See `TestProveAndVerify_ConiksByCryptoED25519`)|
|libsodium|o| need to build libsodium (See `libsodium` task of `Makefile`)|

### Attention

* There is no compatibility between *r2ishiguro.Prove/libsodium.Verify* and *libsodium.Prove/r2ishiguro.Verify* (See `TestProveAndVerifyCompatibilityLibsodium`)
* Ostracon Network should use `r2ishiguro` or `libsodium` (Can't use both at the same time in Ostracon Network)
### libsodium (bind C implementations)
* package/file
* line/ostracon/crypto/vrf/internal/vrf
* `// +build libsodium`
* vrf.go
* vrf_test.go
* libsodium: submodule (See `.gitmodule`)
* sodium: libs (See `libsodium` task of `Makefile`)
## How to test
```shell
# r2ishiguro
go test github.com/line/ostracon/crypto/vrf -tags r2ishiguro
# libsodium
go test github.com/line/ostracon/crypto/vrf -tags libsodium
# internal libsodium only
go test github.com/line/ostracon/crypto/vrf/internal/vrf -v -tags libsodium
# coniks is not available, but if you want to do, you can see no-compatibility
go test github.com/line/ostracon/crypto/vrf -tags coniks
```
## How to benchmark
```shell
# r2ishiguro
go test -bench Benchmark github.com/line/ostracon/crypto/vrf -run ^$ -benchtime=1000x -count 10 -benchmem -v
# libsodium
go test -bench Benchmark github.com/line/ostracon/crypto/vrf -run ^$ -benchtime=1000x -count 10 -benchmem -v -tags libsodium
```
## How to build
```shell
# r2ishiguro
make build
# libsodium
LIBSODIUM=1 make build
```
15 changes: 0 additions & 15 deletions crypto/vrf/internal/vrf/nolibsodium.go

This file was deleted.

Loading

0 comments on commit f53ee28

Please sign in to comment.