82 lines
1.8 KiB
Go
82 lines
1.8 KiB
Go
package crypto
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
)
|
|
|
|
// Sign signs the hash of an arbitrary string
|
|
func Sign(content string, identity *ecdsa.PrivateKey) (string, error) {
|
|
signature, err := crypto.Sign(crypto.Keccak256([]byte(content)), identity)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return hex.EncodeToString(signature), nil
|
|
}
|
|
|
|
// VerifySignatures verifys tuples of signatures content/hash/public key
|
|
func VerifySignatures(signaturePairs [][3]string) error {
|
|
for _, signaturePair := range signaturePairs {
|
|
content := crypto.Keccak256([]byte(signaturePair[0]))
|
|
|
|
signature, err := hex.DecodeString(signaturePair[1])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
publicKeyBytes, err := hex.DecodeString(signaturePair[2])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
publicKey, err := crypto.UnmarshalPubkey(publicKeyBytes)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
recoveredKey, err := crypto.SigToPub(
|
|
content,
|
|
signature,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if crypto.PubkeyToAddress(*recoveredKey) != crypto.PubkeyToAddress(*publicKey) {
|
|
return errors.New("identity key and signature mismatch")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ExtractSignatures extract from tuples of signatures content a public key
|
|
func ExtractSignatures(signaturePairs [][2]string) ([]string, error) {
|
|
response := make([]string, len(signaturePairs))
|
|
for i, signaturePair := range signaturePairs {
|
|
content := crypto.Keccak256([]byte(signaturePair[0]))
|
|
|
|
signature, err := hex.DecodeString(signaturePair[1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
recoveredKey, err := crypto.SigToPub(
|
|
content,
|
|
signature,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
response[i] = fmt.Sprintf("%x", crypto.FromECDSAPub(recoveredKey))
|
|
}
|
|
|
|
return response, nil
|
|
}
|