forked from TrueCloudLab/frostfs-sdk-go
[#190] Refactor cryptographic functionality
Remove `signature` and `util/signature` packages. Re-implement their functionality in new `crypto` package. Generalize the approach of digital signature computation and verification by adding `Signer` and `PublicKey` primitives similar to standard `crypto` package. Support already exising in protocol signature schemes. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
2deaaeef05
commit
ea043f4ca3
33 changed files with 728 additions and 627 deletions
86
crypto/ecdsa/signer.go
Normal file
86
crypto/ecdsa/signer.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package neofsecdsa
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
||||
)
|
||||
|
||||
// Signer implements neofscrypto.Signer based on ECDSA.
|
||||
//
|
||||
// Supported schemes:
|
||||
// - neofscrypto.ECDSA_SHA512 (default)
|
||||
// - neofscrypto.ECDSA_DETERMINISTIC_SHA256
|
||||
//
|
||||
// Instances MUST be initialized with ecdsa.PrivateKey using SetKey.
|
||||
type Signer struct {
|
||||
deterministic bool
|
||||
|
||||
key ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// SetKey specifies ecdsa.PrivateKey to be used for ECDSA signature calculation.
|
||||
func (x *Signer) SetKey(key ecdsa.PrivateKey) {
|
||||
x.key = key
|
||||
}
|
||||
|
||||
// MakeDeterministic makes Signer to use Deterministic ECDSA scheme
|
||||
// (see neofscrypto.ECDSA_DETERMINISTIC_SHA256). By default,
|
||||
// neofscrypto.ECDSA_SHA512 is used.
|
||||
func (x *Signer) MakeDeterministic() {
|
||||
x.deterministic = true
|
||||
}
|
||||
|
||||
// Scheme returns signature scheme depending on Signer state:
|
||||
// - neofscrypto.ECDSA_DETERMINISTIC_SHA256 if MakeDeterministic called
|
||||
// - neofscrypto.ECDSA_SHA512 otherwise.
|
||||
func (x Signer) Scheme() neofscrypto.Scheme {
|
||||
if x.deterministic {
|
||||
return neofscrypto.ECDSA_DETERMINISTIC_SHA256
|
||||
}
|
||||
|
||||
return neofscrypto.ECDSA_SHA512
|
||||
}
|
||||
|
||||
// Sign signs data with algorithm depending on Signer state:
|
||||
// - Deterministic ECDSA with SHA-256 hashing if MakeDeterministic called
|
||||
// - ECDSA with SHA-512 hashing, otherwise
|
||||
func (x Signer) Sign(data []byte) ([]byte, error) {
|
||||
if x.deterministic {
|
||||
p := keys.PrivateKey{PrivateKey: x.key}
|
||||
return p.Sign(data), nil
|
||||
}
|
||||
|
||||
h := sha512.Sum512(data)
|
||||
r, s, err := ecdsa.Sign(rand.Reader, &x.key, h[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return elliptic.Marshal(elliptic.P256(), r, s), nil
|
||||
}
|
||||
|
||||
// MaxPublicKeyEncodedSize returns size of the compressed ECDSA public key
|
||||
// of the Signer.
|
||||
func (x Signer) MaxPublicKeyEncodedSize() int {
|
||||
return 33
|
||||
}
|
||||
|
||||
// EncodePublicKey encodes ECDSA public key of the Signer in compressed form
|
||||
// into buf. Uses exactly MaxPublicKeyEncodedSize bytes of the buf.
|
||||
//
|
||||
// EncodePublicKey panics if buf length is less than MaxPublicKeyEncodedSize.
|
||||
//
|
||||
// See also PublicKey.Decode.
|
||||
func (x Signer) EncodePublicKey(buf []byte) int {
|
||||
if len(buf) < 33 {
|
||||
panic(fmt.Sprintf("too short buffer %d", len(buf)))
|
||||
}
|
||||
|
||||
return copy(buf, (*keys.PublicKey)(&x.key.PublicKey).Bytes())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue