decred.org/dcrdex@v1.0.5/tatanka/mj/auth.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package mj
     5  
     6  import (
     7  	"crypto/sha256"
     8  	"encoding/binary"
     9  	"fmt"
    10  
    11  	"decred.org/dcrdex/dex/msgjson"
    12  	"github.com/btcsuite/btcd/btcec/v2/ecdsa"
    13  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
    14  )
    15  
    16  func MessageDigest(msg *msgjson.Message) [32]byte {
    17  	b := make([]byte, 0, 1+len(msg.Route)+8+len(msg.Payload))
    18  	b = append(b, byte(msg.Type))
    19  	b = append(b, []byte(msg.Route)...)
    20  	var idB [8]byte
    21  	binary.BigEndian.PutUint64(idB[:], msg.ID)
    22  	b = append(b, idB[:]...)
    23  	b = append(b, msg.Payload...)
    24  	return sha256.Sum256(b)
    25  }
    26  
    27  func SignMessage(priv *secp256k1.PrivateKey, msg *msgjson.Message) {
    28  	h := MessageDigest(msg)
    29  	msg.Sig = ecdsa.Sign(priv, h[:]).Serialize()
    30  }
    31  
    32  // CheckSig checks that the message's signature was created with the private
    33  // key for the provided secp256k1 public key on the sha256 hash of the message.
    34  func CheckSig(msg *msgjson.Message, pubKey *secp256k1.PublicKey) error {
    35  	signature, err := ecdsa.ParseDERSignature(msg.Sig)
    36  	if err != nil {
    37  		return fmt.Errorf("error decoding secp256k1 Signature from bytes: %w", err)
    38  	}
    39  	h := MessageDigest(msg)
    40  	if !signature.Verify(h[:], pubKey) {
    41  		return fmt.Errorf("secp256k1 signature verification failed")
    42  	}
    43  	return nil
    44  }