-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add basic common code used in sdk and cometbft repos (#2)
* Add files from cometBFT repo * Rename hash package * wip * Clean up curves (for now) * Add bls curve and cache util * Add github action * Fix action * Fix tests * Fix ci * Simpler ci * Fix lint * Add lint jobs * Add lint ci
- Loading branch information
Showing
49 changed files
with
3,412 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
name: Build and Test | ||
on: | ||
pull_request: | ||
merge_group: | ||
push: | ||
branches: | ||
- main | ||
- release/** | ||
permissions: | ||
contents: read | ||
|
||
concurrency: | ||
group: ci-${{ github.ref }}-build | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: "1.22.2" | ||
- name: Build | ||
run: make build | ||
|
||
test: | ||
runs-on: ubuntu-latest | ||
needs: build | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: "1.22.2" | ||
- name: Test | ||
run: 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,21 @@ | ||
name: Lint | ||
on: | ||
pull_request: | ||
push: | ||
branches: | ||
- main | ||
- release/** | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
lint: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: "1.22.2" | ||
- name: Run Linter | ||
run: make lint |
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 @@ | ||
.idea |
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,35 @@ | ||
# Variables | ||
PKG := ./... | ||
GOFILES := $(shell find . -name '*.go' | grep -v _test.go) | ||
TESTFILES := $(shell find . -name '*_test.go') | ||
GOLANGCI_VERSION := v1.59.0 | ||
|
||
all: build | ||
|
||
build: | ||
@echo "Building..." | ||
@go build $(PKG) | ||
|
||
# Run tests | ||
test: | ||
@echo "Running tests..." | ||
@go test -v $(PKG) | ||
|
||
# Install golangci-lint | ||
lint-install: | ||
@echo "--> Installing golangci-lint $(GOLANGCI_VERSION)" | ||
@go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_VERSION) | ||
|
||
# Run golangci-lint | ||
lint: | ||
@echo "--> Running linter" | ||
$(MAKE) lint-install | ||
@golangci-lint run --timeout=15m | ||
|
||
# Run golangci-lint and fix | ||
lint-fix: | ||
@echo "--> Running linter with fix" | ||
$(MAKE) lint-install | ||
@golangci-lint run --fix | ||
|
||
.PHONY: build test lint-install lint lint-fix |
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,9 @@ | ||
# crypto | ||
|
||
cosmos-crypto is the cryptographic package adapted for the interchain stack | ||
|
||
## Importing it | ||
|
||
To get the interfaces, | ||
`import "github.com/cosmos/crypto/types"` | ||
|
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,52 @@ | ||
package armor | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
|
||
"golang.org/x/crypto/openpgp/armor" //nolint: staticcheck | ||
) | ||
|
||
// ErrEncode represents an error from calling [EncodeArmor]. | ||
type ErrEncode struct { | ||
Err error | ||
} | ||
|
||
func (e ErrEncode) Error() string { | ||
return fmt.Sprintf("armor: could not encode ASCII armor: %v", e.Err) | ||
} | ||
|
||
func (e ErrEncode) Unwrap() error { | ||
return e.Err | ||
} | ||
|
||
func EncodeArmor(blockType string, headers map[string]string, data []byte) (string, error) { | ||
buf := new(bytes.Buffer) | ||
w, err := armor.Encode(buf, blockType, headers) | ||
if err != nil { | ||
return "", ErrEncode{Err: err} | ||
} | ||
_, err = w.Write(data) | ||
if err != nil { | ||
return "", ErrEncode{Err: err} | ||
} | ||
err = w.Close() | ||
if err != nil { | ||
return "", ErrEncode{Err: err} | ||
} | ||
return buf.String(), nil | ||
} | ||
|
||
func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error) { | ||
buf := bytes.NewBufferString(armorStr) | ||
block, err := armor.Decode(buf) | ||
if err != nil { | ||
return "", nil, nil, err | ||
} | ||
data, err = io.ReadAll(block.Body) | ||
if err != nil { | ||
return "", nil, nil, err | ||
} | ||
return block.Type, block.Header, data, nil | ||
} |
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,21 @@ | ||
package armor | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestArmor(t *testing.T) { | ||
blockType := "MINT TEST" | ||
data := []byte("somedata") | ||
armorStr, err := EncodeArmor(blockType, nil, data) | ||
require.NoError(t, err, "%+v", err) | ||
|
||
// Decode armorStr and test for equivalence. | ||
blockType2, _, data2, err := DecodeArmor(armorStr) | ||
require.NoError(t, err, "%+v", err) | ||
assert.Equal(t, blockType, blockType2) | ||
assert.Equal(t, data, data2) | ||
} |
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,9 @@ | ||
//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 | ||
|
||
package blst | ||
|
||
import blst "github.com/supranational/blst/bindings/go" | ||
|
||
// Internal types for blst. | ||
type blstPublicKey = blst.P1Affine | ||
type blstSignature = blst.P2Affine |
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,6 @@ | ||
// Package blst implements a go-wrapper around a library implementing the | ||
// BLS12-381 curve and signature scheme. This package exposes a public API for | ||
// verifying and aggregating BLS signatures used by Ethereum. | ||
// | ||
// This implementation uses the library written by Supranational, blst. | ||
package blst |
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,15 @@ | ||
//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 | ||
|
||
package blst | ||
|
||
// Note: These functions are for tests to access private globals, such as pubkeyCache. | ||
|
||
// DisableCaches sets the cache sizes to 0. | ||
func DisableCaches() { | ||
pubkeyCache.Resize(0) | ||
} | ||
|
||
// EnableCaches sets the cache sizes to the default values. | ||
func EnableCaches() { | ||
pubkeyCache.Resize(maxKeys) | ||
} |
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,27 @@ | ||
//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 | ||
|
||
package blst | ||
|
||
import ( | ||
"fmt" | ||
"runtime" | ||
|
||
blst "github.com/supranational/blst/bindings/go" | ||
|
||
"github.com/cosmos/crypto/internal/cache" | ||
) | ||
|
||
func init() { | ||
// Reserve 1 core for general application work | ||
maxProcs := runtime.GOMAXPROCS(0) - 1 | ||
if maxProcs <= 0 { | ||
maxProcs = 1 | ||
} | ||
blst.SetMaxProcs(maxProcs) | ||
onEvict := func(_ [48]byte, _ PubKey) {} | ||
keysCache, err := cache.NewLRU(maxKeys, onEvict) | ||
if err != nil { | ||
panic(fmt.Sprintf("Could not initiate public keys cache: %v", err)) | ||
} | ||
pubkeyCache = keysCache | ||
} |
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,21 @@ | ||
package blst | ||
|
||
type PubKey interface { | ||
Marshal() []byte | ||
Copy() PubKey | ||
Equals(p2 PubKey) bool | ||
} | ||
|
||
// SignatureI represents a BLS signature. | ||
type SignatureI interface { | ||
Verify(pubKey PubKey, msg []byte) bool | ||
Marshal() []byte | ||
Copy() SignatureI | ||
} | ||
|
||
// SecretKey represents a BLS secret or private key. | ||
type SecretKey interface { | ||
PublicKey() PubKey | ||
Sign(msg []byte) SignatureI | ||
Marshal() []byte | ||
} |
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,76 @@ | ||
//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 | ||
|
||
package blst | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/cosmos/crypto/internal/cache" | ||
) | ||
|
||
const ( | ||
SignatureLength = 96 | ||
PubkeyLength = 48 // PubkeyLength defines the byte length of a BLSSignature. | ||
) | ||
|
||
var maxKeys = 2_000_000 | ||
var pubkeyCache *cache.LRU[[48]byte, PubKey] | ||
|
||
// PublicKey used in the BLS signature scheme. | ||
type PublicKey struct { | ||
p *blstPublicKey | ||
} | ||
|
||
// Marshal a public key into a LittleEndian byte slice. | ||
func (p *PublicKey) Marshal() []byte { | ||
return p.p.Compress() | ||
} | ||
|
||
// Copy the public key to a new pointer reference. | ||
func (p *PublicKey) Copy() PubKey { | ||
np := *p.p | ||
return &PublicKey{p: &np} | ||
} | ||
|
||
// Equals checks if the provided public key is equal to | ||
// the current one. | ||
func (p *PublicKey) Equals(p2 PubKey) bool { | ||
return p.p.Equals(p2.(*PublicKey).p) | ||
} | ||
|
||
// PublicKeyFromBytes creates a BLS public key from a BigEndian byte slice. | ||
func PublicKeyFromBytes(pubKey []byte) (PubKey, error) { | ||
return publicKeyFromBytes(pubKey, true) | ||
} | ||
|
||
func publicKeyFromBytes(pubKey []byte, cacheCopy bool) (PubKey, error) { | ||
if len(pubKey) != PubkeyLength { //TODO: make this a parameter | ||
return nil, fmt.Errorf("public key must be %d bytes", PubkeyLength) | ||
} | ||
|
||
newKey := (*[PubkeyLength]byte)(pubKey) | ||
if cv, ok := pubkeyCache.Get(*newKey); ok { | ||
if cacheCopy { | ||
return cv.Copy(), nil | ||
} | ||
return cv, nil | ||
} | ||
|
||
// Subgroup check NOT done when decompressing pubkey. | ||
p := new(blstPublicKey).Uncompress(pubKey) | ||
if p == nil { | ||
return nil, errors.New("could not unmarshal bytes into public key") | ||
} | ||
// Subgroup and infinity check | ||
if !p.KeyValidate() { | ||
// NOTE: the error is not quite accurate since it includes group check | ||
return nil, errors.New("publickey is infinite") | ||
} | ||
|
||
pubKeyObj := &PublicKey{p: p} | ||
copiedKey := pubKeyObj.Copy() | ||
cacheKey := *newKey | ||
pubkeyCache.Add(cacheKey, copiedKey) | ||
return pubKeyObj, nil | ||
} |
Oops, something went wrong.