diff --git a/Makefile b/Makefile index 14e117d..5d82f1f 100644 --- a/Makefile +++ b/Makefile @@ -7,13 +7,21 @@ GOLANGCI_VERSION := v1.59.0 all: build build: - @echo "Building..." - @go build $(PKG) + @if [ -z "$(TAGS)" ]; then \ + echo "Building..."; \ + else \ + echo "Building with tags: $(TAGS)"; \ + fi + @go build -tags "$(TAGS)" $(PKG) # Run tests test: - @echo "Running tests..." - @go test -v $(PKG) + @if [ -z "$(TAGS)" ]; then \ + echo "Running tests..."; \ + else \ + echo "Running tests with tags: $(TAGS)"; \ + fi + @go test -tags "$(TAGS)" -v $(PKG) # Install golangci-lint lint-install: diff --git a/curves/bls12381/alias.go b/curves/bls12381/alias.go index 6682f30..5096406 100644 --- a/curves/bls12381/alias.go +++ b/curves/bls12381/alias.go @@ -1,5 +1,3 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst import blst "github.com/supranational/blst/bindings/go" diff --git a/curves/bls12381/helper_test.go b/curves/bls12381/helper_test.go index 20cf48c..dd42f99 100644 --- a/curves/bls12381/helper_test.go +++ b/curves/bls12381/helper_test.go @@ -1,5 +1,3 @@ -//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. diff --git a/curves/bls12381/init.go b/curves/bls12381/init.go index 3112fa0..5d0da87 100644 --- a/curves/bls12381/init.go +++ b/curves/bls12381/init.go @@ -1,5 +1,3 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst import ( diff --git a/curves/bls12381/pubkey.go b/curves/bls12381/pubkey.go index 5f8590d..55d6abd 100644 --- a/curves/bls12381/pubkey.go +++ b/curves/bls12381/pubkey.go @@ -1,5 +1,3 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst import ( diff --git a/curves/bls12381/pubkey_test.go b/curves/bls12381/pubkey_test.go index fd656ea..de18ba5 100644 --- a/curves/bls12381/pubkey_test.go +++ b/curves/bls12381/pubkey_test.go @@ -1,5 +1,3 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst_test import ( diff --git a/curves/bls12381/secret_key.go b/curves/bls12381/secret_key.go index deaf0a4..917f627 100644 --- a/curves/bls12381/secret_key.go +++ b/curves/bls12381/secret_key.go @@ -1,5 +1,3 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst import ( @@ -8,6 +6,8 @@ import ( "fmt" blst "github.com/supranational/blst/bindings/go" + + "github.com/cosmos/crypto/internal/rand" ) // bls12SecretKey used in the BLS signature scheme. diff --git a/curves/bls12381/secret_key_test.go b/curves/bls12381/secret_key_test.go index bfea916..601c118 100644 --- a/curves/bls12381/secret_key_test.go +++ b/curves/bls12381/secret_key_test.go @@ -1,5 +1,3 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst_test import ( diff --git a/curves/bls12381/signature.go b/curves/bls12381/signature.go index a5a8655..5ec56b7 100644 --- a/curves/bls12381/signature.go +++ b/curves/bls12381/signature.go @@ -1,5 +1,3 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst import ( diff --git a/curves/bls12381/signature_test.go b/curves/bls12381/signature_test.go index 318adc9..1a2956c 100644 --- a/curves/bls12381/signature_test.go +++ b/curves/bls12381/signature_test.go @@ -1,10 +1,9 @@ -//go:build ((linux && amd64) || (linux && arm64) || (darwin && amd64) || (darwin && arm64) || (windows && amd64)) && bls12381 - package blst import ( "bytes" "errors" + "reflect" "testing" "github.com/stretchr/testify/assert" @@ -51,32 +50,32 @@ func TestSignatureFromBytes(t *testing.T) { }{ { name: "Nil", - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Empty", input: []byte{}, - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Short", input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Long", input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Bad", input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - err: errors.New("could not unmarshal bytes into signature"), + err: errors.New("could not create signature from byte slice: could not unmarshal bytes into signature"), }, { input: []byte{0xac, 0xb0, 0x12, 0x4c, 0x75, 0x74, 0xf2, 0x81, 0xa2, 0x93, 0xf4, 0x18, 0x5c, 0xad, 0x3c, 0xb2, 0x26, 0x81, 0xd5, 0x20, 0x91, 0x7c, 0xe4, 0x66, 0x65, 0x24, 0x3e, 0xac, 0xb0, 0x51, 0x00, 0x0d, 0x8b, 0xac, 0xf7, 0x5e, 0x14, 0x51, 0x87, 0x0c, 0xa6, 0xb3, 0xb9, 0xe6, 0xc9, 0xd4, 0x1a, 0x7b, 0x02, 0xea, 0xd2, 0x68, 0x5a, 0x84, 0x18, 0x8a, 0x4f, 0xaf, 0xd3, 0x82, 0x5d, 0xaf, 0x6a, 0x98, 0x96, 0x25, 0xd7, 0x19, 0xcc, 0xd2, 0xd8, 0x3a, 0x40, 0x10, 0x1f, 0x4a, 0x45, 0x3f, 0xca, 0x62, 0x87, 0x8c, 0x89, 0x0e, 0xca, 0x62, 0x23, 0x63, 0xf9, 0xdd, 0xb8, 0xf3, 0x67, 0xa9, 0x1e, 0x84}, name: "Not in group", - err: errors.New("signature not in group"), + err: errors.New("could not create signature from byte slice: signature not in group"), }, { name: "Good", @@ -106,27 +105,27 @@ func TestSignatureFromBytesNoValidation(t *testing.T) { }{ { name: "Nil", - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Empty", input: []byte{}, - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Short", input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Long", input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - err: errors.New("signature must be 96 bytes"), + err: errors.New("could not create signature from byte slice: signature must be 96 bytes"), }, { name: "Bad", input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - err: errors.New("could not unmarshal bytes into signature"), + err: errors.New("could not create signature from byte slice: could not unmarshal bytes into signature"), }, { name: "Not in group", @@ -161,10 +160,7 @@ func TestCopy(t *testing.T) { signatureA := &Signature{s: new(blstSignature).Sign(key.p, []byte("foo"), dst)} signatureB, ok := signatureA.Copy().(*Signature) require.Equal(t, true, ok) - - assert.NotEqual(t, signatureA, signatureB) - assert.NotEqual(t, signatureA.s, signatureB.s) - assert.Equal(t, signatureA, signatureB) + assert.True(t, reflect.DeepEqual(signatureA.s, signatureB.s), "Signatures are not deeply equal") signatureA.s.Sign(key.p, []byte("bar"), dst) assert.NotEqual(t, signatureA, signatureB) diff --git a/internal/rand/rand.go b/internal/rand/rand.go new file mode 100644 index 0000000..3fe4a94 --- /dev/null +++ b/internal/rand/rand.go @@ -0,0 +1,45 @@ +package rand + +import ( + "crypto/rand" + "encoding/binary" + mrand "math/rand" + "sync" +) + +type source struct{} + +var lock sync.RWMutex +var _ mrand.Source64 = (*source)(nil) // #nosec G404 -- This ensures we meet the interface + +// Seed does nothing when crypto/rand is used as source. +func (_ *source) Seed(_ int64) {} + +// Int63 returns uniformly-distributed random (as in CSPRNG) int64 value within [0, 1<<63) range. +// Panics if random generator reader cannot return data. +func (s *source) Int63() int64 { + return int64(s.Uint64() & ^uint64(1<<63)) +} + +// Uint64 returns uniformly-distributed random (as in CSPRNG) uint64 value within [0, 1<<64) range. +// Panics if random generator reader cannot return data. +func (_ *source) Uint64() (val uint64) { + lock.RLock() + defer lock.RUnlock() + if err := binary.Read(rand.Reader, binary.BigEndian, &val); err != nil { + panic(err) + } + return +} + +// Rand is alias for underlying random generator. +type Rand = mrand.Rand // #nosec G404 + +// NewGenerator returns a new generator that uses random values from crypto/rand as a source +// (cryptographically secure random number generator). +// Panics if crypto/rand input cannot be read. +// Use it for everything where crypto secure non-deterministic randomness is required. Performance +// takes a hit, so use sparingly. +func NewGenerator() *Rand { + return mrand.New(&source{}) // #nosec G404 -- excluded +}