Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
"crypto/sha256"
"fmt"

"github.com/onflow/crypto/common"
"github.com/onflow/crypto/hash"
"github.com/onflow/crypto/sign"
)
Expand Down Expand Up @@ -271,7 +272,7 @@ func (a *blsBLS12381Algo) GeneratePrivateKey(ikm []byte) (sign.PrivateKey, error
// HKDF secret = IKM || I2OSP(0, 1)
secret := make([]byte, len(ikm)+1)
copy(secret, ikm)
defer overwrite(secret) // overwrite secret
Comment thread
tarakby marked this conversation as resolved.
defer common.Overwrite(secret)
// HKDF info = key_info || I2OSP(L, 2)
keyInfo := []byte{} // use empty key diversifier. TODO: update header to accept input identifier
info := string(append(keyInfo, byte(okmLength>>8), byte(okmLength)))
Expand All @@ -283,7 +284,7 @@ func (a *blsBLS12381Algo) GeneratePrivateKey(ikm []byte) (sign.PrivateKey, error
if err != nil {
return nil, fmt.Errorf("HKDF computation failed: %w", err)
}
defer overwrite(okm) // overwrite okm
defer common.Overwrite(okm)

// map the bytes to a private key using modular reduction
// SK = OS2IP(OKM) mod r
Expand Down
6 changes: 4 additions & 2 deletions bls12381_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/onflow/crypto/sign/testutils"
)

// Sanity check of G1 and G2 scalar multiplication
Expand Down Expand Up @@ -190,7 +192,7 @@ func BenchmarkMapToG1(b *testing.B) {

// test subgroup membership check in G1 and G2
func TestSubgroupCheck(t *testing.T) {
prg := getPRG(t)
prg := testutils.GetPRG(t)
seed := make([]byte, 192)
_, err := prg.Read(seed)
require.NoError(t, err)
Expand Down Expand Up @@ -242,7 +244,7 @@ func BenchmarkSubgroupCheck(b *testing.B) {
// specific test of G1 points Encode and decode (BLS signature since the library is set for min_sig).
// G2 points read and write are implicitly tested by public keys Encode/Decode.
func TestReadWriteG1(t *testing.T) {
prg := getPRG(t)
prg := testutils.GetPRG(t)
seed := make([]byte, frBytesLen)
bytes := make([]byte, g1BytesLen)
// generate a random G1 point, encode it, decode it,
Expand Down
37 changes: 19 additions & 18 deletions bls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@ import (

"github.com/onflow/crypto/hash"
"github.com/onflow/crypto/sign"
"github.com/onflow/crypto/sign/testutils"
)

// TestBLSMainMethods is a sanity check of main signature scheme methods (keyGen, sign, verify)
func TestBLSMainMethods(t *testing.T) {
// test the key generation seed lengths
testKeyGenSeed(t, sign.BLSBLS12381, KeyGenSeedMinLen, KeyGenSeedMaxLen)
testutils.TestKeyGenSeed(t, sign.BLSBLS12381, KeyGenSeedMinLen, KeyGenSeedMaxLen)
// test the consistency with different inputs
hasher := NewExpandMsgXOFKMAC128("test tag")
testGenSignVerify(t, sign.BLSBLS12381, hasher)
testutils.TestGenSignVerify(t, sign.BLSBLS12381, hasher)

// specific signature test for BLS:
// Test a signature with a point encoded with a coordinate x not reduced mod p.
Expand Down Expand Up @@ -105,13 +106,13 @@ func TestBLSMainMethods(t *testing.T) {
// Signing bench
func BenchmarkBLSSingleSign(b *testing.B) {
halg := NewExpandMsgXOFKMAC128("bench tag")
benchSign(b, sign.BLSBLS12381, halg)
testutils.BenchSign(b, sign.BLSBLS12381, halg)
}

// Verifying bench
func BenchmarkBLSSingleVerify(b *testing.B) {
halg := NewExpandMsgXOFKMAC128("bench tag")
benchVerify(b, sign.BLSBLS12381, halg)
testutils.BenchVerify(b, sign.BLSBLS12381, halg)
}

// utility function to generate a random BLS private key
Expand All @@ -138,7 +139,7 @@ func invalidSK(t *testing.T) sign.PrivateKey {

// BLS tests
func TestBLSBLS12381Hasher(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
// generate a key pair
sk := randomSK(t, rand)
sig := make([]byte, SignatureLenBLSBLS12381)
Expand Down Expand Up @@ -197,7 +198,7 @@ func TestBLSBLS12381Hasher(t *testing.T) {
// TestBLSEncodeDecode tests encoding and decoding of BLS keys
func TestBLSEncodeDecode(t *testing.T) {
// generic tests
testEncodeDecode(t, sign.BLSBLS12381)
testutils.TestEncodeDecode(t, sign.BLSBLS12381)

// specific tests for BLS

Expand Down Expand Up @@ -276,23 +277,23 @@ func TestBLSEncodeDecode(t *testing.T) {

// TestBLSEquals tests equal for BLS keys
func TestBLSEquals(t *testing.T) {
testEquals(t, sign.BLSBLS12381, sign.ECDSAP256)
testutils.TestEquals(t, sign.BLSBLS12381, sign.ECDSAP256)
}

// TestBLSUtils tests some utility functions
func TestBLSUtils(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
// generate a key pair
sk := randomSK(t, rand)
// test Algorithm()
testKeysAlgorithm(t, sk, sign.BLSBLS12381)
testutils.TestKeysAlgorithm(t, sk, sign.BLSBLS12381)
// test Size()
testKeySize(t, sk, PrKeyLenBLSBLS12381, PubKeyLenBLSBLS12381)
testutils.TestKeySize(t, sk, PrKeyLenBLSBLS12381, PubKeyLenBLSBLS12381)
}

// BLS Proof of Possession test
func TestBLSPOP(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
seed := make([]byte, KeyGenSeedMinLen)
input := make([]byte, 100)

Expand Down Expand Up @@ -347,7 +348,7 @@ func TestBLSPOP(t *testing.T) {
// Verify the aggregated signature using the multi-signature verification with
// one message.
func TestBLSAggregateSignatures(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
// random message
input := make([]byte, 100)
_, err := rand.Read(input)
Expand Down Expand Up @@ -472,7 +473,7 @@ func TestBLSAggregateSignatures(t *testing.T) {
// the public key of the aggregated private key is equal to the aggregated
// public key
func TestBLSAggregatePublicKeys(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
// number of keys to aggregate
pkNum := rand.Intn(100) + 1
pks := make([]sign.PublicKey, 0, pkNum)
Expand Down Expand Up @@ -595,7 +596,7 @@ func TestBLSAggregatePublicKeys(t *testing.T) {
// BLS multi-signature
// public keys removal sanity check
func TestBLSRemovePubKeys(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
// number of keys to aggregate
pkNum := rand.Intn(100) + 1
pks := make([]sign.PublicKey, 0, pkNum)
Expand Down Expand Up @@ -683,7 +684,7 @@ func TestBLSRemovePubKeys(t *testing.T) {
// batch verification technique and compares the result to verifying each signature
// separately.
func TestBLSBatchVerify(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
// random message
input := make([]byte, 100)
_, err := rand.Read(input)
Expand Down Expand Up @@ -920,7 +921,7 @@ func BenchmarkBatchVerify(b *testing.B) {
// and verify the aggregated signature using the multi-signature verification with
// many messages.
func TestBLSAggregateSignaturesManyMessages(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
// number of signatures to aggregate
sigsNum := rand.Intn(40) + 1
sigs := make([]sign.Signature, 0, sigsNum)
Expand Down Expand Up @@ -1035,7 +1036,7 @@ func TestBLSAggregateSignaturesManyMessages(t *testing.T) {

t.Run("variable number of distinct keys and messages", func(t *testing.T) {
// use a specific PRG for easier reproduction
prg := getPRG(t)
prg := testutils.GetPRG(t)
// number of signatures to aggregate
N := 100
sigs := make([]sign.Signature, 0, N)
Expand Down Expand Up @@ -1203,7 +1204,7 @@ func BenchmarkAggregate(b *testing.B) {
}

func TestBLSIdentity(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)

var identitySig []byte
msg := []byte("random_message")
Expand Down
9 changes: 5 additions & 4 deletions bls_thresholdsign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/onflow/crypto/sign"
"github.com/onflow/crypto/sign/testutils"
)

func TestBLSThresholdSignature(t *testing.T) {
Expand All @@ -50,7 +51,7 @@ var thresholdSignatureMessage = []byte("random message")

// centralized test of the stateful threshold signature using the threshold key generation.
func testCentralizedStatefulAPI(t *testing.T) {
rand := getPRG(t)
rand := testutils.GetPRG(t)
seed := make([]byte, KeyGenSeedMinLen)
_, err := rand.Read(seed)
n := 10
Expand Down Expand Up @@ -337,7 +338,7 @@ func testDistributedStatefulAPI_FeldmanVSS(t *testing.T) {
log.SetLevel(log.ErrorLevel)
log.Info("DKG starts")
gt = t
rand := getPRG(t)
rand := testutils.GetPRG(t)
// number of participants to test
n := 5
lead := rand.Intn(n) // random
Expand Down Expand Up @@ -397,7 +398,7 @@ func testDistributedStatefulAPI_JointFeldman(t *testing.T) {
log.SetLevel(log.ErrorLevel)
log.Info("DKG starts")
gt = t
rand := getPRG(t)
rand := testutils.GetPRG(t)
// number of participants to test
n := 5
for threshold := MinimumThreshold; threshold < n; threshold++ {
Expand Down Expand Up @@ -569,7 +570,7 @@ func testCentralizedStatelessAPI(t *testing.T) {
n := 10
for threshold := MinimumThreshold; threshold < n; threshold++ {
// generate threshold keys
rand := getPRG(t)
rand := testutils.GetPRG(t)
_, err := rand.Read(seed)
require.NoError(t, err)
skShares, pkShares, pkGroup, err := BLSThresholdKeyGen(n, threshold, seed)
Expand Down
13 changes: 0 additions & 13 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package crypto

import (
"crypto/rand"
"errors"
"fmt"
)
Expand All @@ -38,18 +37,6 @@ const (
KeyGenSeedMaxLen = 256
)

// TODO: update this code to make sure
// the function isn't removed by the compiler
// https://github.com/golang/go/issues/21865
func overwrite(data []byte) {
_, err := rand.Read(data) // checking err is enough
if err != nil {
// zero the buffer if randomizing failed
for i := 0; i < len(data); i++ {
data[i] = 0
}
}
}

// invalidInputsError is an error returned when a crypto API receives invalid inputs.
// It allows a function caller differentiate unexpected program errors from errors caused by
Expand Down
36 changes: 36 additions & 0 deletions common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Flow Crypto
*
* Copyright Flow Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package common

import (
"crypto/rand"
)

//
// TODO: update this code to make sure the function isn't removed by the compiler
// https://github.com/golang/go/issues/21865
func Overwrite(data []byte) {
_, err := rand.Read(data) // checking err is enough
if err != nil {
// zero the buffer if randomizing failed
for i := 0; i < len(data); i++ {
data[i] = 0
}
}
}
33 changes: 33 additions & 0 deletions init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Flow Crypto
*
* Copyright Flow Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package crypto

import (
"github.com/onflow/crypto/sign"
_ "github.com/onflow/crypto/sign/ecdsa"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can delete this line

)

func init() {
// init the BLS12-381 curve context
initBLS12381()
// register the BLS context on the BLS 12-381 curve instance in the `sign` package
if err := sign.RegisterSigner(sign.BLSBLS12381, &blsBLS12381Algo{algo: sign.BLSBLS12381}); err != nil {
panic(err)
}
}
3 changes: 0 additions & 3 deletions no_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ func BLSInvalidSignature() sign.Signature {
panic(withFeature("BLS signature"))
}

func isG2Compressed() bool {
panic(withFeature("BLS12-381 curve"))
}

func NewBLSThresholdSignatureParticipant(
groupPublicKey sign.PublicKey,
Expand Down
Loading