Skip to content

Commit

Permalink
fix: added missing doc comments and minor cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
meling committed Mar 10, 2024
1 parent 6cfadb2 commit 870abcc
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 41 deletions.
37 changes: 14 additions & 23 deletions crypto/ecdsa/ecdsa.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Package ecdsa supports spec-k256 curve signature
// Package ecdsa implements the spec-k256 curve signature.
package ecdsa

import (
Expand All @@ -21,23 +21,24 @@ func init() {
const (
// PrivateKeyFileType is the PEM type for a private key.
PrivateKeyFileType = "ECDSA PRIVATE KEY"

// PublicKeyFileType is the PEM type for a public key.
PublicKeyFileType = "ECDSA PUBLIC KEY"
)

var (
_ hotstuff.QuorumSignature = (*crypto.Multi[*Signature])(nil)
_ hotstuff.IDSet = (*crypto.Multi[*Signature])(nil)
_ crypto.Signature = (*Signature)(nil)
)

// Signature is an ECDSA signature
// Signature is an ECDSA signature.
type Signature struct {
r, s *big.Int
signer hotstuff.ID
}

// RestoreSignature restores an existing signature. It should not be used to create new signatures, use Sign instead.
// RestoreSignature restores an existing signature.
// It should not be used to create new signatures, use Sign instead.
func RestoreSignature(r, s *big.Int, signer hotstuff.ID) *Signature {
return &Signature{r, s, signer}
}
Expand All @@ -47,17 +48,17 @@ func (sig Signature) Signer() hotstuff.ID {
return sig.signer
}

// R returns the r value of the signature
// R returns the r value of the signature.
func (sig Signature) R() *big.Int {
return sig.r
}

// S returns the s value of the signature
// S returns the s value of the signature.
func (sig Signature) S() *big.Int {
return sig.s
}

// ToBytes returns a raw byte string representation of the signature
// ToBytes returns a raw byte string representation of the signature.
func (sig Signature) ToBytes() []byte {
var b []byte
b = append(b, sig.r.Bytes()...)
Expand All @@ -76,10 +77,6 @@ func New() modules.CryptoBase {
return &ecdsaBase{}
}

func (ec *ecdsaBase) getPrivateKey() *ecdsa.PrivateKey {
return ec.opts.PrivateKey().(*ecdsa.PrivateKey)
}

// InitModule gives the module a reference to the Core object.
// It also allows the module to set module options using the OptionsBuilder.
func (ec *ecdsaBase) InitModule(mods *modules.Core) {
Expand All @@ -90,10 +87,14 @@ func (ec *ecdsaBase) InitModule(mods *modules.Core) {
)
}

func (ec *ecdsaBase) privateKey() *ecdsa.PrivateKey {
return ec.opts.PrivateKey().(*ecdsa.PrivateKey)
}

// Sign creates a cryptographic signature of the given message.
func (ec *ecdsaBase) Sign(message []byte) (signature hotstuff.QuorumSignature, err error) {
hash := sha256.Sum256(message)
r, s, err := ecdsa.Sign(rand.Reader, ec.getPrivateKey(), hash[:])
r, s, err := ecdsa.Sign(rand.Reader, ec.privateKey(), hash[:])
if err != nil {
return nil, fmt.Errorf("ecdsa: sign failed: %w", err)
}
Expand All @@ -111,11 +112,10 @@ func (ec *ecdsaBase) Combine(signatures ...hotstuff.QuorumSignature) (hotstuff.Q
}

ts := make(crypto.Multi[*Signature])

for _, sig1 := range signatures {
if sig2, ok := sig1.(crypto.Multi[*Signature]); ok {
for id, s := range sig2 {
if _, ok := ts[id]; ok {
if _, duplicate := ts[id]; duplicate {
return nil, crypto.ErrCombineOverlap
}
ts[id] = s
Expand All @@ -124,7 +124,6 @@ func (ec *ecdsaBase) Combine(signatures ...hotstuff.QuorumSignature) (hotstuff.Q
ec.logger.Panicf("cannot combine signature of incompatible type %T (expected %T)", sig1, sig2)
}
}

return ts, nil
}

Expand All @@ -134,28 +133,24 @@ func (ec *ecdsaBase) Verify(signature hotstuff.QuorumSignature, message []byte)
if !ok {
ec.logger.Panicf("cannot verify signature of incompatible type %T (expected %T)", signature, s)
}

n := signature.Participants().Len()
if n == 0 {
return false
}

results := make(chan bool, n)
hash := sha256.Sum256(message)

for _, sig := range s {
go func(sig *Signature, hash hotstuff.Hash) {
results <- ec.verifySingle(sig, hash)
}(sig, hash)
}

valid := true
for range s {
if !<-results {
valid = false
}
}

return valid
}

Expand All @@ -165,7 +160,6 @@ func (ec *ecdsaBase) BatchVerify(signature hotstuff.QuorumSignature, batch map[h
if !ok {
ec.logger.Panicf("cannot verify signature of incompatible type %T (expected %T)", signature, s)
}

n := signature.Participants().Len()
if n == 0 {
return false
Expand All @@ -184,7 +178,6 @@ func (ec *ecdsaBase) BatchVerify(signature hotstuff.QuorumSignature, batch map[h
results <- ec.verifySingle(sig, hash)
}(sig, hash)
}

valid := true
for range s {
if !<-results {
Expand All @@ -205,5 +198,3 @@ func (ec *ecdsaBase) verifySingle(sig *Signature, hash hotstuff.Hash) bool {
pk := replica.PublicKey().(*ecdsa.PublicKey)
return ecdsa.Verify(pk, hash[:], sig.R(), sig.S())
}

var _ crypto.Signature = (*Signature)(nil)
34 changes: 16 additions & 18 deletions crypto/eddsa/eddsa.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Package eddsa implements 25519 curve signature
// Package eddsa implements the ed25519 curve signature.
package eddsa

import (
Expand All @@ -18,23 +18,24 @@ func init() {
const (
// PrivateKeyFileType is the PEM type for a private key.
PrivateKeyFileType = "EDDSA PRIVATE KEY"

// PublicKeyFileType is the PEM type for a public key.
PublicKeyFileType = "EDDSA PUBLIC KEY"
)

var (
_ hotstuff.QuorumSignature = (*crypto.Multi[*Signature])(nil)
_ hotstuff.IDSet = (*crypto.Multi[*Signature])(nil)
_ crypto.Signature = (*Signature)(nil)
)

// Signature is an ECDSA signature
// Signature is an EDDSA signature.
type Signature struct {
signer hotstuff.ID
sign []byte
}

// RestoreSignature restores an existing signature. It should not be used to create new signatures, use Sign instead.
// RestoreSignature restores an existing signature.
// It should not be used to create new signatures, use Sign instead.
func RestoreSignature(sign []byte, signer hotstuff.ID) *Signature {
return &Signature{signer, sign}
}
Expand All @@ -44,7 +45,7 @@ func (sig Signature) Signer() hotstuff.ID {
return sig.signer
}

// ToBytes returns a raw byte string representation of the signature
// ToBytes returns a raw byte string representation of the signature.
func (sig Signature) ToBytes() []byte {
var b []byte
b = append(b, sig.sign...)
Expand All @@ -57,7 +58,7 @@ type eddsaBase struct {
opts *modules.Options
}

// New returns a new instance of the ECDSA CryptoBase implementation.
// New returns a new instance of the EDDSA CryptoBase implementation.
func New() modules.CryptoBase {
return &eddsaBase{}
}
Expand All @@ -76,23 +77,24 @@ func (ed *eddsaBase) privateKey() ed25519.PrivateKey {
return ed.opts.PrivateKey().(ed25519.PrivateKey)
}

// Sign creates a cryptographic signature of the given message.
func (ed *eddsaBase) Sign(message []byte) (signature hotstuff.QuorumSignature, err error) {
sign := ed25519.Sign(ed.privateKey(), message)
eddsaSign := &Signature{signer: ed.opts.ID(), sign: sign}
return crypto.Multi[*Signature]{ed.opts.ID(): eddsaSign}, nil
}

// Combine combines multiple signatures into a single signature.
func (ed *eddsaBase) Combine(signatures ...hotstuff.QuorumSignature) (hotstuff.QuorumSignature, error) {
if len(signatures) < 2 {
return nil, crypto.ErrCombineMultiple
}

ts := make(crypto.Multi[*Signature])

for _, sig1 := range signatures {
if sig2, ok := sig1.(crypto.Multi[*Signature]); ok {
for id, s := range sig2 {
if _, ok := ts[id]; ok {
if _, duplicate := ts[id]; duplicate {
return nil, crypto.ErrCombineOverlap
}
ts[id] = s
Expand All @@ -104,6 +106,7 @@ func (ed *eddsaBase) Combine(signatures ...hotstuff.QuorumSignature) (hotstuff.Q
return ts, nil
}

// Verify verifies the given quorum signature against the message.
func (ed *eddsaBase) Verify(signature hotstuff.QuorumSignature, message []byte) bool {
s, ok := signature.(crypto.Multi[*Signature])
if !ok {
Expand All @@ -115,29 +118,26 @@ func (ed *eddsaBase) Verify(signature hotstuff.QuorumSignature, message []byte)
}

Check warning on line 118 in crypto/eddsa/eddsa.go

View check run for this annotation

Codecov / codecov/patch

crypto/eddsa/eddsa.go#L117-L118

Added lines #L117 - L118 were not covered by tests

results := make(chan bool, n)

for _, sig := range s {
go func(sig *Signature, msg []byte) {
results <- ed.verifySingle(sig, msg)
}(sig, message)
}

valid := true
for range s {
if !<-results {
valid = false
}

Check warning on line 130 in crypto/eddsa/eddsa.go

View check run for this annotation

Codecov / codecov/patch

crypto/eddsa/eddsa.go#L129-L130

Added lines #L129 - L130 were not covered by tests
}

return valid

}

// BatchVerify verifies the given quorum signature against the batch of messages.
func (ed *eddsaBase) BatchVerify(signature hotstuff.QuorumSignature, batch map[hotstuff.ID][]byte) bool {
s, ok := signature.(crypto.Multi[*Signature])
if !ok {
ed.logger.Panicf("cannot verify signature of incompatible type %T (expected %T)", signature, s)
}

Check warning on line 140 in crypto/eddsa/eddsa.go

View check run for this annotation

Codecov / codecov/patch

crypto/eddsa/eddsa.go#L139-L140

Added lines #L139 - L140 were not covered by tests

n := signature.Participants().Len()
if n == 0 {
return false
Expand All @@ -156,7 +156,6 @@ func (ed *eddsaBase) BatchVerify(signature hotstuff.QuorumSignature, batch map[h
results <- ed.verifySingle(sig, msg)
}(sig, message)
}

valid := true
for range s {
if !<-results {
Expand All @@ -167,18 +166,17 @@ func (ed *eddsaBase) BatchVerify(signature hotstuff.QuorumSignature, batch map[h
// valid if all partial signatures are valid and there are no duplicate messages
return valid && len(set) == len(batch)
}

func (ed *eddsaBase) verifySingle(sig *Signature, message []byte) bool {
replica, ok := ed.configuration.Replica(sig.Signer())
if !ok {
ed.logger.Warnf("ecdsaBase: got signature from replica whose ID (%d) was not in the config.", sig.Signer())
ed.logger.Warnf("eddsaBase: got signature from replica whose ID (%d) was not in the config.", sig.Signer())
return false
}

Check warning on line 175 in crypto/eddsa/eddsa.go

View check run for this annotation

Codecov / codecov/patch

crypto/eddsa/eddsa.go#L173-L175

Added lines #L173 - L175 were not covered by tests
pk, ok := replica.PublicKey().([]byte)
if !ok {
ed.logger.Infof("ecdsaBase: got public key from replica that was not of type []byte.")
ed.logger.Infof("eddsaBase: got public key from replica that was not of type []byte.")
pk = replica.PublicKey().(ed25519.PublicKey)
}
return ed25519.Verify(pk, message, sig.sign)
}

var _ crypto.Signature = (*Signature)(nil)

0 comments on commit 870abcc

Please sign in to comment.