github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/crypto/ecies/params.go (about)

     1  // Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is>
     2  // Copyright (c) 2012 The Go Authors. All rights reserved.
     3  //
     4  // Redistribution and use in source and binary forms, with or without
     5  // modification, are permitted provided that the following conditions are
     6  // met:
     7  //
     8  //    * Redistributions of source code must retain the above copyright
     9  // notice, this list of conditions and the following disclaimer.
    10  //    * Redistributions in binary form must reproduce the above
    11  // copyright notice, this list of conditions and the following disclaimer
    12  // in the documentation and/or other materials provided with the
    13  // distribution.
    14  //    * Neither the name of Google Inc. nor the names of its
    15  // contributors may be used to endorse or promote products derived from
    16  // this software without specific prior written permission.
    17  //
    18  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29  
    30  package ecies
    31  
    32  // This file contains parameters for ECIES encryption, specifying the
    33  // symmetric encryption and HMAC parameters.
    34  
    35  import (
    36  	"crypto"
    37  	"crypto/aes"
    38  	"crypto/cipher"
    39  	"crypto/elliptic"
    40  	"crypto/sha256"
    41  	"crypto/sha512"
    42  	"fmt"
    43  	"hash"
    44  
    45  	"github.com/atheioschain/go-atheios/crypto/secp256k1"
    46  )
    47  
    48  var (
    49  	DefaultCurve                  = secp256k1.S256()
    50  	ErrUnsupportedECDHAlgorithm   = fmt.Errorf("ecies: unsupported ECDH algorithm")
    51  	ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters")
    52  )
    53  
    54  type ECIESParams struct {
    55  	Hash      func() hash.Hash // hash function
    56  	hashAlgo  crypto.Hash
    57  	Cipher    func([]byte) (cipher.Block, error) // symmetric cipher
    58  	BlockSize int                                // block size of symmetric cipher
    59  	KeyLen    int                                // length of symmetric key
    60  }
    61  
    62  // Standard ECIES parameters:
    63  // * ECIES using AES128 and HMAC-SHA-256-16
    64  // * ECIES using AES256 and HMAC-SHA-256-32
    65  // * ECIES using AES256 and HMAC-SHA-384-48
    66  // * ECIES using AES256 and HMAC-SHA-512-64
    67  
    68  var (
    69  	ECIES_AES128_SHA256 = &ECIESParams{
    70  		Hash:      sha256.New,
    71  		hashAlgo:  crypto.SHA256,
    72  		Cipher:    aes.NewCipher,
    73  		BlockSize: aes.BlockSize,
    74  		KeyLen:    16,
    75  	}
    76  
    77  	ECIES_AES256_SHA256 = &ECIESParams{
    78  		Hash:      sha256.New,
    79  		hashAlgo:  crypto.SHA256,
    80  		Cipher:    aes.NewCipher,
    81  		BlockSize: aes.BlockSize,
    82  		KeyLen:    32,
    83  	}
    84  
    85  	ECIES_AES256_SHA384 = &ECIESParams{
    86  		Hash:      sha512.New384,
    87  		hashAlgo:  crypto.SHA384,
    88  		Cipher:    aes.NewCipher,
    89  		BlockSize: aes.BlockSize,
    90  		KeyLen:    32,
    91  	}
    92  
    93  	ECIES_AES256_SHA512 = &ECIESParams{
    94  		Hash:      sha512.New,
    95  		hashAlgo:  crypto.SHA512,
    96  		Cipher:    aes.NewCipher,
    97  		BlockSize: aes.BlockSize,
    98  		KeyLen:    32,
    99  	}
   100  )
   101  
   102  var paramsFromCurve = map[elliptic.Curve]*ECIESParams{
   103  	secp256k1.S256(): ECIES_AES128_SHA256,
   104  	elliptic.P256():  ECIES_AES128_SHA256,
   105  	elliptic.P384():  ECIES_AES256_SHA384,
   106  	elliptic.P521():  ECIES_AES256_SHA512,
   107  }
   108  
   109  func AddParamsForCurve(curve elliptic.Curve, params *ECIESParams) {
   110  	paramsFromCurve[curve] = params
   111  }
   112  
   113  // ParamsFromCurve selects parameters optimal for the selected elliptic curve.
   114  // Only the curves P256, P384, and P512 are supported.
   115  func ParamsFromCurve(curve elliptic.Curve) (params *ECIESParams) {
   116  	return paramsFromCurve[curve]
   117  
   118  	/*
   119  		switch curve {
   120  		case elliptic.P256():
   121  			return ECIES_AES128_SHA256
   122  		case elliptic.P384():
   123  			return ECIES_AES256_SHA384
   124  		case elliptic.P521():
   125  			return ECIES_AES256_SHA512
   126  		default:
   127  			return nil
   128  		}
   129  	*/
   130  }
   131  
   132  // ASN.1 encode the ECIES parameters relevant to the encryption operations.
   133  func paramsToASNECIES(params *ECIESParams) (asnParams asnECIESParameters) {
   134  	if nil == params {
   135  		return
   136  	}
   137  	asnParams.KDF = asnNISTConcatenationKDF
   138  	asnParams.MAC = hmacFull
   139  	switch params.KeyLen {
   140  	case 16:
   141  		asnParams.Sym = aes128CTRinECIES
   142  	case 24:
   143  		asnParams.Sym = aes192CTRinECIES
   144  	case 32:
   145  		asnParams.Sym = aes256CTRinECIES
   146  	}
   147  	return
   148  }
   149  
   150  // ASN.1 encode the ECIES parameters relevant to ECDH.
   151  func paramsToASNECDH(params *ECIESParams) (algo asnECDHAlgorithm) {
   152  	switch params.hashAlgo {
   153  	case crypto.SHA224:
   154  		algo = dhSinglePass_stdDH_sha224kdf
   155  	case crypto.SHA256:
   156  		algo = dhSinglePass_stdDH_sha256kdf
   157  	case crypto.SHA384:
   158  		algo = dhSinglePass_stdDH_sha384kdf
   159  	case crypto.SHA512:
   160  		algo = dhSinglePass_stdDH_sha512kdf
   161  	}
   162  	return
   163  }
   164  
   165  // ASN.1 decode the ECIES parameters relevant to the encryption stage.
   166  func asnECIEStoParams(asnParams asnECIESParameters, params *ECIESParams) {
   167  	if !asnParams.KDF.Cmp(asnNISTConcatenationKDF) {
   168  		params = nil
   169  		return
   170  	} else if !asnParams.MAC.Cmp(hmacFull) {
   171  		params = nil
   172  		return
   173  	}
   174  
   175  	switch {
   176  	case asnParams.Sym.Cmp(aes128CTRinECIES):
   177  		params.KeyLen = 16
   178  		params.BlockSize = 16
   179  		params.Cipher = aes.NewCipher
   180  	case asnParams.Sym.Cmp(aes192CTRinECIES):
   181  		params.KeyLen = 24
   182  		params.BlockSize = 16
   183  		params.Cipher = aes.NewCipher
   184  	case asnParams.Sym.Cmp(aes256CTRinECIES):
   185  		params.KeyLen = 32
   186  		params.BlockSize = 16
   187  		params.Cipher = aes.NewCipher
   188  	default:
   189  		params = nil
   190  	}
   191  }
   192  
   193  // ASN.1 decode the ECIES parameters relevant to ECDH.
   194  func asnECDHtoParams(asnParams asnECDHAlgorithm, params *ECIESParams) {
   195  	if asnParams.Cmp(dhSinglePass_stdDH_sha224kdf) {
   196  		params.hashAlgo = crypto.SHA224
   197  		params.Hash = sha256.New224
   198  	} else if asnParams.Cmp(dhSinglePass_stdDH_sha256kdf) {
   199  		params.hashAlgo = crypto.SHA256
   200  		params.Hash = sha256.New
   201  	} else if asnParams.Cmp(dhSinglePass_stdDH_sha384kdf) {
   202  		params.hashAlgo = crypto.SHA384
   203  		params.Hash = sha512.New384
   204  	} else if asnParams.Cmp(dhSinglePass_stdDH_sha512kdf) {
   205  		params.hashAlgo = crypto.SHA512
   206  		params.Hash = sha512.New
   207  	} else {
   208  		params = nil
   209  	}
   210  }