github.com/core-coin/go-core/v2@v2.1.9/crypto/signature_cgo.go (about)

     1  // Copyright 2017 by the Authors
     2  // This file is part of the go-core library.
     3  //
     4  // The go-core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-core library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  //go:build !nacl && !js && cgo && !android && !ios && !mobile
    18  
    19  package crypto
    20  
    21  import (
    22  	"bytes"
    23  
    24  	"github.com/core-coin/go-goldilocks"
    25  )
    26  
    27  // SigToPub returns the public key that created the given signature.
    28  func SigToPub(hash, sig []byte) (*PublicKey, error) {
    29  	if len(sig) != ExtendedSignatureLength {
    30  		return nil, errInvalidSignature
    31  	}
    32  	pub := sig[SignatureLength:]
    33  	ok := VerifySignature(pub, hash, sig)
    34  	if !ok {
    35  		return nil, errInvalidSignature
    36  	}
    37  	return UnmarshalPubKey(pub)
    38  }
    39  
    40  // Sign calculates an EDDSA signature.
    41  //
    42  // This function is susceptible to chosen plaintext attacks that can leak
    43  // information about the private key that is used for signing. Callers must
    44  // be aware that the given digest cannot be chosen by an adversery. Common
    45  // solution is to hash any input before calculating the signature.
    46  func Sign(hash []byte, prv *PrivateKey) ([]byte, error) {
    47  	if prv == nil || len(prv.PrivateKey()) == 0 || bytes.Equal(prv.PrivateKey(), []byte{}) || bytes.Equal(prv.PrivateKey(), make([]byte, 57)) {
    48  		return []byte{}, errInvalidPrivkey
    49  	}
    50  	sig := goldilocks.Ed448Sign(goldilocks.BytesToPrivateKey(prv.PrivateKey()), goldilocks.BytesToPublicKey(prv.PublicKey()[:]), hash, []byte{}, false)
    51  	if len(sig) == ExtendedSignatureLength {
    52  		return sig[:], nil
    53  	}
    54  	return append(sig[:], prv.PublicKey()[:]...), nil
    55  }
    56  
    57  // VerifySignature checks that the given public key created signature over hash.
    58  func VerifySignature(pub, hash, signature []byte) bool {
    59  	if len(signature) != ExtendedSignatureLength {
    60  		return false
    61  	}
    62  	return goldilocks.Ed448Verify(goldilocks.BytesToPublicKey(pub), signature[:SignatureLength], hash, []byte{}, false)
    63  }