Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit the longest validity period allowed for key registration to pre… #3181

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions crypto/compactcert/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import (
"context"
"database/sql"
"fmt"
"github.com/algorand/go-algorand/config"
"strconv"
"testing"

"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/crypto/merklearray"
"github.com/algorand/go-algorand/crypto/merklekeystore"
Expand All @@ -36,7 +36,7 @@ import (

type TestMessage string

// TODO: change to CurrentVersion
// TODO: change to CurrentVersion when updated
var CompactCertRounds = config.Consensus[protocol.ConsensusFuture].CompactCertRounds

func (m TestMessage) ToBeHashed() (protocol.HashID, []byte) {
Expand Down Expand Up @@ -88,7 +88,7 @@ func generateTestSigner(name string, firstValid uint64, lastValid uint64, a *req
})
a.NoError(err)

signer, err := merklekeystore.New(firstValid, lastValid, crypto.FalconType, store)
signer, err := merklekeystore.New(firstValid, lastValid, CompactCertRounds, crypto.FalconType, store)
a.NoError(err)

err = signer.Persist()
Expand Down
2 changes: 1 addition & 1 deletion crypto/merklekeystore/KeystoreBuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,6 @@ func bencKeyGen(b *testing.B, algoType crypto.AlgorithmType) {

b.ResetTimer()
for i := 0; i < b.N; i++ {
New(0, 3000000, algoType, store)
New(0, 3000000, 128, algoType, store)
}
}
17 changes: 2 additions & 15 deletions crypto/merklekeystore/keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ package merklekeystore

import (
"errors"
"fmt"

"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/crypto/merklearray"
"github.com/algorand/go-algorand/protocol"
Expand Down Expand Up @@ -82,8 +79,6 @@ type (
}
)

// TODO: change to ConsensusCurrentVersion when updated
var errValidityPeriodTooLong = fmt.Errorf("the validity period for merkleKeyStore is too large: the limit is %d", config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod)
var errStartBiggerThanEndRound = errors.New("cannot create merkleKeyStore because end round is smaller then start round")
var errDivisorIsZero = errors.New("received zero Interval")

Expand Down Expand Up @@ -111,22 +106,14 @@ func (k *keysArray) Marshal(pos uint64) ([]byte, error) {
// New Generates a merklekeystore.Signer
// The function allow creation of empty signers, i.e signers without any key to sign with.
// keys can be created between [A,Z], if A == 0, keys created will be in the range (0,Z]
func New(firstValid, lastValid uint64, sigAlgoType crypto.AlgorithmType, store db.Accessor) (*Signer, error) {

func New(firstValid, lastValid, interval uint64, sigAlgoType crypto.AlgorithmType, store db.Accessor) (*Signer, error) {
if firstValid > lastValid {
return nil, errStartBiggerThanEndRound
}

// TODO: change to ConsensusCurrentVersion when updated
interval := config.Consensus[protocol.ConsensusFuture].CompactCertRounds
maxValidPeriod := config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod

if maxValidPeriod != 0 && (lastValid-firstValid) > maxValidPeriod {
return nil, errValidityPeriodTooLong
}
if interval == 0 {
return nil, errDivisorIsZero
}

if firstValid == 0 {
firstValid = 1
}
Expand Down
40 changes: 5 additions & 35 deletions crypto/merklekeystore/keystore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
uuid "github.com/satori/go.uuid"
"github.com/stretchr/testify/require"

"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/test/partitiontest"
Expand Down Expand Up @@ -482,35 +481,6 @@ func TestKeyDeletion(t *testing.T) {
}
}

func TestValidityPeriod(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)

// TODO: change to config.Consensus[protocol.ConsensusCurrentVersion].MaxKeyregValidPeriod when we reach that version
maxValidPeriod := config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod

store := initTestDB(a)
defer store.Close()
firstValid := uint64(0)
lastValid := maxValidPeriod
_, err := New(firstValid, lastValid, crypto.Ed25519Type, *store)
a.NoError(err)

store = initTestDB(a)
defer store.Close()
firstValid = uint64(0)
lastValid = maxValidPeriod + 1
_, err = New(firstValid, lastValid, crypto.Ed25519Type, *store)
a.Error(err)

store = initTestDB(a)
defer store.Close()
firstValid = uint64(0)
lastValid = maxValidPeriod - 1
_, err = New(firstValid, lastValid, crypto.Ed25519Type, *store)
a.NoError(err)
}

func TestNumberOfGeneratedKeys(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)
Expand All @@ -521,7 +491,7 @@ func TestNumberOfGeneratedKeys(t *testing.T) {
defer store.Close()
firstValid := uint64(1000)
lastValid := validPeriod + 1000
s, err := New(firstValid, lastValid, crypto.Ed25519Type, *store)
s, err := New(firstValid, lastValid, interval, crypto.Ed25519Type, *store)
a.NoError(err)
err = s.Persist()
a.NoError(err)
Expand All @@ -531,7 +501,7 @@ func TestNumberOfGeneratedKeys(t *testing.T) {
defer store.Close()
firstValid = uint64(0)
lastValid = validPeriod
s, err = New(firstValid, lastValid, crypto.Ed25519Type, *store)
s, err = New(firstValid, lastValid, interval, crypto.Ed25519Type, *store)
a.NoError(err)
err = s.Persist()
a.NoError(err)
Expand All @@ -541,7 +511,7 @@ func TestNumberOfGeneratedKeys(t *testing.T) {
defer store.Close()
firstValid = uint64(1000)
lastValid = validPeriod + 1000 - (interval * 50)
s, err = New(firstValid, lastValid, crypto.Ed25519Type, *store)
s, err = New(firstValid, lastValid, interval, crypto.Ed25519Type, *store)
a.NoError(err)
err = s.Persist()
a.NoError(err)
Expand All @@ -564,9 +534,9 @@ func generateTestSignerAux(a *require.Assertions) (uint64, uint64, *Signer) {
return start, end, signer
}

func generateTestSigner(t crypto.AlgorithmType, firstValid uint64, lastValid uint64, interval uint64, a *require.Assertions) *Signer {
func generateTestSigner(t crypto.AlgorithmType, firstValid, lastValid, interval uint64, a *require.Assertions) *Signer {
store := initTestDB(a)
signer, err := New(firstValid, lastValid, t, *store)
signer, err := New(firstValid, lastValid, interval, t, *store)
a.NoError(err)

err = signer.Persist()
Expand Down
23 changes: 20 additions & 3 deletions data/account/participation.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,23 @@ func (part PersistedParticipation) PersistNewParent() error {
})
}

func generateKeystore(firstValid, lastValid uint64, store db.Accessor, protoParams config.ConsensusParams) (*merklekeystore.Signer, error) {
interval := protoParams.CompactCertRounds
maxValidPeriod := protoParams.MaxKeyregValidPeriod

if maxValidPeriod != 0 && uint64(lastValid-firstValid) > maxValidPeriod {
return nil, fmt.Errorf("the validity period for merkleKeyStore is too large: the limit is %d", maxValidPeriod)
}

// Generate a new key which signs the compact certificates
stateProofSecrets, err := merklekeystore.New(uint64(firstValid), uint64(lastValid), interval, crypto.FalconType, store)
if err != nil {
return nil, err
}

return stateProofSecrets, nil
}

// FillDBWithParticipationKeys initializes the passed database with participation keys
func FillDBWithParticipationKeys(store db.Accessor, address basics.Address, firstValid, lastValid basics.Round, keyDilution uint64) (part PersistedParticipation, err error) {
if lastValid < firstValid {
Expand All @@ -235,10 +252,10 @@ func FillDBWithParticipationKeys(store db.Accessor, address basics.Address, firs
// Generate a new VRF key, which lives in the participation keys db
vrf := crypto.GenerateVRFSecrets()

// Generate a new key which signs the compact certificates
stateProofSecrets, err := merklekeystore.New(uint64(firstValid), uint64(lastValid), crypto.FalconType, store)
// TODO: change to ConsensusCurrentVersion when updated
stateProofSecrets, err := generateKeystore(uint64(firstValid), uint64(lastValid), store, config.Consensus[protocol.ConsensusFuture])
if err != nil {
return
return PersistedParticipation{}, err
}

// Construct the Participation containing these keys to be persisted
Expand Down
50 changes: 50 additions & 0 deletions data/account/participation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"
"testing"

uuid "github.com/satori/go.uuid"
"github.com/stretchr/testify/require"

"github.com/algorand/go-algorand/config"
Expand Down Expand Up @@ -448,3 +449,52 @@ func BenchmarkParticipationKeyRestoration(b *testing.B) {
}
part.Close()
}

func createKeystoreTestDB(a *require.Assertions) *db.Accessor {
tmpname := uuid.NewV4().String() // could this just be a constant string instead? does it even matter?
store, err := db.MakeAccessor(tmpname, false, true)
a.NoError(err)
a.NotNil(store)

err = store.Atomic(func(ctx context.Context, tx *sql.Tx) error {
_, err = tx.Exec(`CREATE TABLE schema (
tablename TEXT PRIMARY KEY,
version INTEGER
);`)
return err
})
a.NoError(err)

return &store
}

func TestKeyregValidityPeriod(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)

// TODO: change to ConsensusCurrentVersion when updated
testConsensusParams := config.Consensus[protocol.ConsensusFuture]
maxValidPeriod := uint64(10000)
testConsensusParams.MaxKeyregValidPeriod = maxValidPeriod

store := createKeystoreTestDB(a)
defer store.Close()
firstValid := uint64(0)
lastValid := maxValidPeriod
_, err := generateKeystore(firstValid, lastValid, *store, testConsensusParams)
a.NoError(err)

store = createKeystoreTestDB(a)
defer store.Close()
firstValid = uint64(0)
lastValid = maxValidPeriod + 1
_, err = generateKeystore(firstValid, lastValid, *store, testConsensusParams)
a.Error(err)

store = createKeystoreTestDB(a)
defer store.Close()
firstValid = uint64(0)
lastValid = maxValidPeriod - 1
_, err = generateKeystore(firstValid, lastValid, *store, testConsensusParams)
a.NoError(err)
}