gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/ecbase/ecbase.go (about)

     1  // Copyright (c) 2023 zhaochun
     2  // core-gm is licensed under Mulan PSL v2.
     3  // You can use this software according to the terms and conditions of the Mulan PSL v2.
     4  // You may obtain a copy of Mulan PSL v2 at:
     5  //          http://license.coscl.org.cn/MulanPSL2
     6  // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
     7  // See the Mulan PSL v2 for more details.
     8  
     9  package ecbase
    10  
    11  import (
    12  	"crypto"
    13  	"encoding/asn1"
    14  	"errors"
    15  	"fmt"
    16  	"math/big"
    17  )
    18  
    19  //==============================================
    20  // EcVerifier 椭圆曲线验签接口
    21  //==============================================
    22  
    23  type EcVerifier interface {
    24  	EcVerify(digest []byte, sig []byte, opts EcSignerOpts) (bool, error)
    25  }
    26  
    27  //==============================================
    28  // EcSignerOpts 椭圆曲线签名参数接口
    29  //==============================================
    30  
    31  type EcSignerOpts interface {
    32  	crypto.SignerOpts
    33  	NeedLowS() bool
    34  	ResetHasher(hasher crypto.Hash)
    35  }
    36  
    37  type ecSignerOpts struct {
    38  	hasher   crypto.Hash
    39  	needLowS bool
    40  }
    41  
    42  func (eso ecSignerOpts) HashFunc() crypto.Hash {
    43  	return eso.hasher
    44  }
    45  
    46  func (eso ecSignerOpts) NeedLowS() bool {
    47  	return eso.needLowS
    48  }
    49  
    50  func (eso ecSignerOpts) ResetHasher(hasher crypto.Hash) {
    51  	eso.hasher = hasher
    52  }
    53  
    54  func CreateEcSignerOpts(hasher crypto.Hash, needLowS bool) EcSignerOpts {
    55  	return &ecSignerOpts{
    56  		hasher:   hasher,
    57  		needLowS: needLowS,
    58  	}
    59  }
    60  
    61  func CreateDefaultEcSignerOpts() EcSignerOpts {
    62  	return &ecSignerOpts{
    63  		hasher:   0,
    64  		needLowS: true,
    65  	}
    66  }
    67  
    68  //==============================================
    69  // ECSignature 椭圆曲线签名
    70  //==============================================
    71  
    72  // ECSignature 椭圆曲线签名
    73  type ECSignature struct {
    74  	R, S *big.Int
    75  }
    76  
    77  // MarshalECSignature 序列化椭圆曲线签名
    78  func MarshalECSignature(r, s *big.Int) ([]byte, error) {
    79  	return asn1.Marshal(ECSignature{r, s})
    80  }
    81  
    82  // UnmarshalECSignature 反序列化椭圆曲线签名
    83  func UnmarshalECSignature(raw []byte) (*big.Int, *big.Int, error) {
    84  	// Unmarshal
    85  	sig := new(ECSignature)
    86  	_, err := asn1.Unmarshal(raw, sig)
    87  	if err != nil {
    88  		return nil, nil, fmt.Errorf("failed unmashalling signature [%s]", err)
    89  	}
    90  
    91  	// Validate sig
    92  	if sig.R == nil {
    93  		return nil, nil, errors.New("invalid signature, R must be different from nil")
    94  	}
    95  	if sig.S == nil {
    96  		return nil, nil, errors.New("invalid signature, S must be different from nil")
    97  	}
    98  
    99  	if sig.R.Sign() != 1 {
   100  		return nil, nil, errors.New("invalid signature, R must be larger than zero")
   101  	}
   102  	if sig.S.Sign() != 1 {
   103  		return nil, nil, errors.New("invalid signature, S must be larger than zero")
   104  	}
   105  
   106  	return sig.R, sig.S, nil
   107  }