github.com/annchain/OG@v0.0.9/deprecated/ogcrypto/signer_secp256k1_noncgo.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  // +build noncgo
    15  
    16  package ogcrypto
    17  
    18  import (
    19  	"crypto/ecdsa"
    20  	"crypto/rand"
    21  	"fmt"
    22  	"github.com/annchain/OG/arefactor/ogcrypto"
    23  	"github.com/annchain/OG/deprecated"
    24  	"github.com/annchain/OG/deprecated/ogcrypto/ecies"
    25  	"github.com/annchain/OG/deprecated/ogcrypto_interface"
    26  	"github.com/btcsuite/btcd/btcec"
    27  	"math/big"
    28  )
    29  
    30  type SignerSecp256k1 struct {
    31  }
    32  
    33  func (s *SignerSecp256k1) GetCryptoType() ogcrypto_interface.CryptoType {
    34  	return ogcrypto_interface.CryptoTypeSecp256k1
    35  }
    36  
    37  // Sign calculates an ECDSA signature.
    38  //
    39  // This function is susceptible to chosen plaintext attacks that can leak
    40  // information about the private key that is used for signing. Callers must
    41  // be aware that the given hash cannot be chosen by an adversery. Common
    42  // solution is to hash any input before calculating the signature.
    43  //
    44  // The produced signature is in the [R || S || V] format where V is 0 or 1.
    45  func (s *SignerSecp256k1) Sign(privKey ogcrypto_interface.PrivateKey, msg []byte) ogcrypto_interface.Signature {
    46  	prv, _ := ToECDSA(privKey.KeyBytes)
    47  	hash := deprecated.Sha256(msg)
    48  	if len(hash) != 32 {
    49  		panic(fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)))
    50  	}
    51  	if prv.Curve != btcec.S256() {
    52  		panic(fmt.Errorf("private key curve is not secp256k1"))
    53  	}
    54  	sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false)
    55  	//sig, err := btcec.Sign(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false)
    56  	if err != nil {
    57  		panic(err)
    58  	}
    59  	// Convert to Ethereum signature format with 'recovery id' v at the end.
    60  	v := sig[0] - 27
    61  	copy(sig, sig[1:])
    62  	sig[64] = v
    63  	return deprecated.SignatureFromBytes(s.GetCryptoType(), sig)
    64  }
    65  
    66  // VerifySignature checks that the given public key created signature over hash.
    67  // The public key should be in compressed (33 bytes) or uncompressed (65 bytes) format.
    68  // The signature should have the 64 byte [R || S] format.
    69  func (s *SignerSecp256k1) Verify(pubKey ogcrypto_interface.PublicKey, signature ogcrypto_interface.Signature, msg []byte) bool {
    70  	hash := deprecated.Sha256(msg)
    71  	signature = s.DealRecoverID(signature)
    72  	sigs := signature.SignatureBytes
    73  	sig := &btcec.Signature{R: new(big.Int).SetBytes(sigs[:32]), S: new(big.Int).SetBytes(sigs[32:])}
    74  	key, err := btcec.ParsePubKey(pubKey.KeyBytes, btcec.S256())
    75  	if err != nil {
    76  		fmt.Println(err)
    77  		return false
    78  	}
    79  	// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
    80  	if sig.S.Cmp(secp256k1halfN) > 0 {
    81  		fmt.Println("sec")
    82  		return false
    83  	}
    84  	return sig.Verify(hash, key)
    85  }
    86  
    87  func (s *SignerSecp256k1) PubKey(privKey ogcrypto_interface.PrivateKey) ogcrypto_interface.PublicKey {
    88  	_, ecdsapub := btcec.PrivKeyFromBytes(btcec.S256(), privKey.KeyBytes)
    89  	pub := FromECDSAPub((*ecdsa.PublicKey)(ecdsapub))
    90  	return deprecated.PublicKeyFromBytes(ogcrypto_interface.CryptoTypeSecp256k1, pub[:])
    91  }
    92  
    93  func (s *SignerSecp256k1) PublicKeyFromBytes(b []byte) ogcrypto_interface.PublicKey {
    94  	return deprecated.PublicKeyFromBytes(s.GetCryptoType(), b)
    95  }
    96  
    97  func (s *SignerSecp256k1) Encrypt(p ogcrypto_interface.PublicKey, m []byte) (ct []byte, err error) {
    98  	pub, err := UnmarshalPubkey(p.KeyBytes)
    99  	if err != nil {
   100  		panic(err)
   101  	}
   102  	eciesPub := ecies.ImportECDSAPublic(pub)
   103  	return ecies.Encrypt(rand.Reader, eciesPub, m, nil, nil)
   104  }
   105  
   106  func (s *SignerSecp256k1) Decrypt(p ogcrypto_interface.PrivateKey, ct []byte) (m []byte, err error) {
   107  	prive, err := ToECDSA(p.KeyBytes)
   108  	ecisesPriv := ecies.ImportECDSA(prive)
   109  	return ecisesPriv.Decrypt(ct, nil, nil)
   110  	//return nil, nil
   111  }
   112  
   113  const sigLength int = 64
   114  
   115  func (s *SignerSecp256k1) DealRecoverID(sig ogcrypto_interface.Signature) ogcrypto_interface.Signature {
   116  	l := len(sig.SignatureBytes)
   117  	if l == sigLength+1 {
   118  		sig.SignatureBytes = sig.SignatureBytes[:l-1]
   119  	}
   120  	return sig
   121  }
   122  
   123  func (s *SignerSecp256k1) RandomKeyPair() (publicKey ogcrypto_interface.PublicKey, privateKey ogcrypto_interface.PrivateKey) {
   124  	privKeyBytes := [32]byte{}
   125  	copy(privKeyBytes[:], ogcrypto.CRandBytes(32))
   126  
   127  	privateKey = deprecated.PrivateKeyFromBytes(ogcrypto_interface.CryptoTypeSecp256k1, privKeyBytes[:])
   128  	publicKey = s.PubKey(privateKey)
   129  	return
   130  }
   131  
   132  // Ecrecover returns the uncompressed public key that created the given signature.
   133  func Ecrecover(hash, sig []byte) ([]byte, error) {
   134  	pub, err := SigToPub(hash, sig)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  	bytes := (*btcec.PublicKey)(pub).SerializeUncompressed()
   139  	return bytes, err
   140  }
   141  
   142  // SigToPub returns the public key that created the given signature.
   143  func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
   144  	// Convert to btcec input format with 'recovery id' v at the beginning.
   145  	btcsig := make([]byte, 65)
   146  	btcsig[0] = sig[64] + 27
   147  	copy(btcsig[1:], sig)
   148  
   149  	pub, _, err := btcec.RecoverCompact(btcec.S256(), btcsig, hash)
   150  	return (*ecdsa.PublicKey)(pub), err
   151  }
   152  
   153  func (s *SignerSecp256k1) CanRecoverPubFromSig() bool {
   154  	return false
   155  }