package identity import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "fmt" "github.com/ethereum/go-ethereum/crypto/secp256k1" "github.com/iotaledger/goshimmer/packages/crypto" ) type Identity struct { Type IdentityType Identifier []byte StringIdentifier string PublicKey []byte PrivateKey []byte } func NewIdentity(publicKey []byte, optionalPrivateKey ...[]byte) *Identity { this := &Identity{ Identifier: crypto.Hash20(publicKey), PublicKey: publicKey, } this.StringIdentifier = fmt.Sprintf("%x", this.Identifier) if len(optionalPrivateKey) == 1 { this.Type = PRIVATE_TYPE this.PrivateKey = optionalPrivateKey[0] } else { this.Type = PUBLIC_TYPE } return this } func (this *Identity) Sign(data []byte) ([]byte, error) { sha256Hasher := sha256.New() sha256Hasher.Write(data) sig, err := secp256k1.Sign(sha256Hasher.Sum(nil), this.PrivateKey) if err != nil { return nil, err } return sig, nil } func (this *Identity) VerifySignature(data []byte, signature []byte) bool { sha256Hasher := sha256.New() sha256Hasher.Write(data) return secp256k1.VerifySignature(this.PublicKey, sha256Hasher.Sum(nil), signature[:64]) } func GenerateRandomIdentity() *Identity { // generate key pair keyPair, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader) if err != nil { panic(err) } // build public key bytes publicKey := elliptic.Marshal(secp256k1.S256(), keyPair.X, keyPair.Y) // build private key bytes privkey := make([]byte, 32) blob := keyPair.D.Bytes() copy(privkey[32-len(blob):], blob) return NewIdentity(publicKey, privkey) } func FromSignedData(data []byte, signature []byte) (*Identity, error) { sha256Hasher := sha256.New() sha256Hasher.Write(data) pubKey, err := secp256k1.RecoverPubkey(sha256Hasher.Sum(nil), signature) if err != nil { return nil, err } return NewIdentity(pubKey), nil }