Skip to content

Commit f1e018e

Browse files
authored
[crypto]: add bls (#675)
* [crypto]: add bls * [wip: crypto] integrate bls into morpheusvm * [wip: crypto] add integration test * [crypto]: support bls + integration test * [crypto] create wrapper for bls * [crypto] remove comment * [crypto] fix BLS unit tests * [crypto] fix lint * [crypto] fix lint * [crypto] fix lint * [crypto] cleanup * [crypto] remove blst usage * [crypto] documentation explaining mul 2 * [crypto] use avalanchego import for Warp in integration test * [crypto] use switch for checkKeyType * [crypto] refactor unmarshalBLS * [crypto] use pointers in BLS struct field * [crypto] remove deserialize/serialize use from/to * [crypto] fix return err * [crypto] address minor changes
1 parent 797d38a commit f1e018e

File tree

13 files changed

+512
-4
lines changed

13 files changed

+512
-4
lines changed

crypto/bls/private.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package bls
5+
6+
import (
7+
"errors"
8+
9+
"github.com/ava-labs/avalanchego/utils/crypto/bls"
10+
)
11+
12+
const PrivateKeyLen = bls.SecretKeyLen
13+
14+
var errFailedPrivateKeyDeserialize = errors.New("couldn't deserialize secret key")
15+
16+
type PrivateKey = bls.SecretKey
17+
18+
func GeneratePrivateKey() (*PrivateKey, error) {
19+
return bls.NewSecretKey()
20+
}
21+
22+
func PrivateKeyToBytes(pk *PrivateKey) []byte {
23+
return bls.SecretKeyToBytes(pk)
24+
}
25+
26+
func PrivateKeyFromBytes(pkBytes []byte) (*PrivateKey, error) {
27+
pk, err := bls.SecretKeyFromBytes(pkBytes)
28+
if err != nil {
29+
return nil, errFailedPrivateKeyDeserialize
30+
}
31+
return pk, nil
32+
}
33+
34+
func PublicFromPrivateKey(pk *PrivateKey) *PublicKey {
35+
return bls.PublicFromSecretKey(pk)
36+
}
37+
38+
func Sign(msg []byte, pk *PrivateKey) *Signature {
39+
return bls.Sign(pk, msg)
40+
}

crypto/bls/private_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package bls
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/ava-labs/avalanchego/utils"
12+
)
13+
14+
func TestPrivateKeyFromBytesZero(t *testing.T) {
15+
require := require.New(t)
16+
17+
var skArr [PrivateKeyLen]byte
18+
skBytes := skArr[:]
19+
_, err := PrivateKeyFromBytes(skBytes)
20+
require.ErrorIs(err, errFailedPrivateKeyDeserialize)
21+
}
22+
23+
func TestPrivateKeyFromBytesWrongSize(t *testing.T) {
24+
require := require.New(t)
25+
26+
skBytes := utils.RandomBytes(PrivateKeyLen + 1)
27+
_, err := PrivateKeyFromBytes(skBytes)
28+
require.ErrorIs(err, errFailedPrivateKeyDeserialize)
29+
}
30+
31+
func TestPrivateKeyBytes(t *testing.T) {
32+
require := require.New(t)
33+
34+
msg := utils.RandomBytes(1234)
35+
36+
sk, err := GeneratePrivateKey()
37+
require.NoError(err)
38+
sig := Sign(msg, sk)
39+
skBytes := PrivateKeyToBytes(sk)
40+
41+
sk2, err := PrivateKeyFromBytes(skBytes)
42+
require.NoError(err)
43+
sig2 := Sign(msg, sk2)
44+
sk2Bytes := PrivateKeyToBytes(sk2)
45+
46+
require.Equal(sk, sk2)
47+
require.Equal(skBytes, sk2Bytes)
48+
require.Equal(sig, sig2)
49+
}

crypto/bls/public.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package bls
5+
6+
import (
7+
"errors"
8+
9+
"github.com/ava-labs/avalanchego/utils/crypto/bls"
10+
)
11+
12+
const PublicKeyLen = bls.PublicKeyLen
13+
14+
var (
15+
ErrNoPublicKeys = errors.New("no public keys")
16+
ErrFailedPublicKeyDecompress = errors.New("couldn't decompress public key")
17+
)
18+
19+
type (
20+
PublicKey = bls.PublicKey
21+
AggregatePublicKey = bls.AggregatePublicKey
22+
)
23+
24+
func PublicKeyToBytes(pk *PublicKey) []byte {
25+
return bls.PublicKeyToBytes(pk)
26+
}
27+
28+
func PublicKeyFromBytes(pkBytes []byte) (*PublicKey, error) {
29+
return bls.PublicKeyFromBytes(pkBytes)
30+
}
31+
32+
func Verify(msg []byte, pk *PublicKey, sig *Signature) bool {
33+
return bls.Verify(pk, sig, msg)
34+
}

crypto/bls/public_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package bls
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/ava-labs/avalanchego/utils"
12+
"github.com/ava-labs/avalanchego/utils/crypto/bls"
13+
)
14+
15+
func TestPublicKeyFromBytesWrongSize(t *testing.T) {
16+
require := require.New(t)
17+
18+
pkBytes := utils.RandomBytes(PublicKeyLen + 1)
19+
_, err := PublicKeyFromBytes(pkBytes)
20+
require.ErrorIs(err, bls.ErrFailedPublicKeyDecompress)
21+
}
22+
23+
func TestPublicKeyBytes(t *testing.T) {
24+
require := require.New(t)
25+
26+
sk, err := GeneratePrivateKey()
27+
require.NoError(err)
28+
29+
pk := PublicFromPrivateKey(sk)
30+
pkBytes := PublicKeyToBytes(pk)
31+
32+
pk2, err := PublicKeyFromBytes(pkBytes)
33+
require.NoError(err)
34+
pk2Bytes := PublicKeyToBytes(pk2)
35+
36+
require.Equal(pk, pk2)
37+
require.Equal(pkBytes, pk2Bytes)
38+
}

crypto/bls/signature.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package bls
5+
6+
import (
7+
"github.com/ava-labs/avalanchego/utils/crypto/bls"
8+
)
9+
10+
const SignatureLen = bls.SignatureLen
11+
12+
type (
13+
Signature = bls.Signature
14+
AggregateSignature = bls.AggregateSignature
15+
)
16+
17+
func SignatureToBytes(sig *Signature) []byte {
18+
return bls.SignatureToBytes(sig)
19+
}
20+
21+
func SignatureFromBytes(sigBytes []byte) (*Signature, error) {
22+
return bls.SignatureFromBytes(sigBytes)
23+
}
24+
25+
func AggregateSignatures(sigs []*Signature) (*Signature, error) {
26+
return bls.AggregateSignatures(sigs)
27+
}

crypto/bls/signature_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package bls
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/ava-labs/avalanchego/utils"
12+
)
13+
14+
func TestSignatureBytes(t *testing.T) {
15+
require := require.New(t)
16+
17+
msg := utils.RandomBytes(1234)
18+
19+
sk, err := GeneratePrivateKey()
20+
require.NoError(err)
21+
sig := Sign(msg, sk)
22+
sigBytes := SignatureToBytes(sig)
23+
24+
sig2, err := SignatureFromBytes(sigBytes)
25+
require.NoError(err)
26+
sig2Bytes := SignatureToBytes(sig2)
27+
28+
require.Equal(sig, sig2)
29+
require.Equal(sigBytes, sig2Bytes)
30+
}
31+
32+
func TestAggregateSignaturesNoop(t *testing.T) {
33+
require := require.New(t)
34+
35+
msg := utils.RandomBytes(1234)
36+
37+
sk, err := GeneratePrivateKey()
38+
require.NoError(err)
39+
40+
sig := Sign(msg, sk)
41+
sigBytes := SignatureToBytes(sig)
42+
43+
aggSig, err := AggregateSignatures([]*Signature{sig})
44+
require.NoError(err)
45+
46+
aggSigBytes := SignatureToBytes(aggSig)
47+
require.NoError(err)
48+
49+
require.Equal(sig, aggSig)
50+
require.Equal(sigBytes, aggSigBytes)
51+
}

0 commit comments

Comments
 (0)