params.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. package ecies
  30. // This file contains parameters for ECIES encryption, specifying the
  31. // symmetric encryption and HMAC parameters.
  32. import (
  33. "crypto"
  34. "crypto/aes"
  35. "crypto/cipher"
  36. "crypto/elliptic"
  37. "crypto/sha256"
  38. "crypto/sha512"
  39. "fmt"
  40. "hash"
  41. ethcrypto "github.com/ethereum/go-ethereum/crypto"
  42. )
  43. var (
  44. DefaultCurve = ethcrypto.S256()
  45. ErrUnsupportedECDHAlgorithm = fmt.Errorf("ecies: unsupported ECDH algorithm")
  46. ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters")
  47. )
  48. type ECIESParams struct {
  49. Hash func() hash.Hash // hash function
  50. hashAlgo crypto.Hash
  51. Cipher func([]byte) (cipher.Block, error) // symmetric cipher
  52. BlockSize int // block size of symmetric cipher
  53. KeyLen int // length of symmetric key
  54. }
  55. // Standard ECIES parameters:
  56. // * ECIES using AES128 and HMAC-SHA-256-16
  57. // * ECIES using AES256 and HMAC-SHA-256-32
  58. // * ECIES using AES256 and HMAC-SHA-384-48
  59. // * ECIES using AES256 and HMAC-SHA-512-64
  60. var (
  61. ECIES_AES128_SHA256 = &ECIESParams{
  62. Hash: sha256.New,
  63. hashAlgo: crypto.SHA256,
  64. Cipher: aes.NewCipher,
  65. BlockSize: aes.BlockSize,
  66. KeyLen: 16,
  67. }
  68. ECIES_AES256_SHA256 = &ECIESParams{
  69. Hash: sha256.New,
  70. hashAlgo: crypto.SHA256,
  71. Cipher: aes.NewCipher,
  72. BlockSize: aes.BlockSize,
  73. KeyLen: 32,
  74. }
  75. ECIES_AES256_SHA384 = &ECIESParams{
  76. Hash: sha512.New384,
  77. hashAlgo: crypto.SHA384,
  78. Cipher: aes.NewCipher,
  79. BlockSize: aes.BlockSize,
  80. KeyLen: 32,
  81. }
  82. ECIES_AES256_SHA512 = &ECIESParams{
  83. Hash: sha512.New,
  84. hashAlgo: crypto.SHA512,
  85. Cipher: aes.NewCipher,
  86. BlockSize: aes.BlockSize,
  87. KeyLen: 32,
  88. }
  89. )
  90. var paramsFromCurve = map[elliptic.Curve]*ECIESParams{
  91. ethcrypto.S256(): ECIES_AES128_SHA256,
  92. elliptic.P256(): ECIES_AES128_SHA256,
  93. elliptic.P384(): ECIES_AES256_SHA384,
  94. elliptic.P521(): ECIES_AES256_SHA512,
  95. }
  96. func AddParamsForCurve(curve elliptic.Curve, params *ECIESParams) {
  97. paramsFromCurve[curve] = params
  98. }
  99. // ParamsFromCurve selects parameters optimal for the selected elliptic curve.
  100. // Only the curves P256, P384, and P512 are supported.
  101. func ParamsFromCurve(curve elliptic.Curve) (params *ECIESParams) {
  102. return paramsFromCurve[curve]
  103. /*
  104. switch curve {
  105. case elliptic.P256():
  106. return ECIES_AES128_SHA256
  107. case elliptic.P384():
  108. return ECIES_AES256_SHA384
  109. case elliptic.P521():
  110. return ECIES_AES256_SHA512
  111. default:
  112. return nil
  113. }
  114. */
  115. }
  116. // ASN.1 encode the ECIES parameters relevant to the encryption operations.
  117. func paramsToASNECIES(params *ECIESParams) (asnParams asnECIESParameters) {
  118. if nil == params {
  119. return
  120. }
  121. asnParams.KDF = asnNISTConcatenationKDF
  122. asnParams.MAC = hmacFull
  123. switch params.KeyLen {
  124. case 16:
  125. asnParams.Sym = aes128CTRinECIES
  126. case 24:
  127. asnParams.Sym = aes192CTRinECIES
  128. case 32:
  129. asnParams.Sym = aes256CTRinECIES
  130. }
  131. return
  132. }
  133. // ASN.1 encode the ECIES parameters relevant to ECDH.
  134. func paramsToASNECDH(params *ECIESParams) (algo asnECDHAlgorithm) {
  135. switch params.hashAlgo {
  136. case crypto.SHA224:
  137. algo = dhSinglePass_stdDH_sha224kdf
  138. case crypto.SHA256:
  139. algo = dhSinglePass_stdDH_sha256kdf
  140. case crypto.SHA384:
  141. algo = dhSinglePass_stdDH_sha384kdf
  142. case crypto.SHA512:
  143. algo = dhSinglePass_stdDH_sha512kdf
  144. }
  145. return
  146. }
  147. // ASN.1 decode the ECIES parameters relevant to the encryption stage.
  148. func asnECIEStoParams(asnParams asnECIESParameters, params *ECIESParams) {
  149. if !asnParams.KDF.Cmp(asnNISTConcatenationKDF) {
  150. params = nil
  151. return
  152. } else if !asnParams.MAC.Cmp(hmacFull) {
  153. params = nil
  154. return
  155. }
  156. switch {
  157. case asnParams.Sym.Cmp(aes128CTRinECIES):
  158. params.KeyLen = 16
  159. params.BlockSize = 16
  160. params.Cipher = aes.NewCipher
  161. case asnParams.Sym.Cmp(aes192CTRinECIES):
  162. params.KeyLen = 24
  163. params.BlockSize = 16
  164. params.Cipher = aes.NewCipher
  165. case asnParams.Sym.Cmp(aes256CTRinECIES):
  166. params.KeyLen = 32
  167. params.BlockSize = 16
  168. params.Cipher = aes.NewCipher
  169. default:
  170. params = nil
  171. }
  172. }
  173. // ASN.1 decode the ECIES parameters relevant to ECDH.
  174. func asnECDHtoParams(asnParams asnECDHAlgorithm, params *ECIESParams) {
  175. if asnParams.Cmp(dhSinglePass_stdDH_sha224kdf) {
  176. params.hashAlgo = crypto.SHA224
  177. params.Hash = sha256.New224
  178. } else if asnParams.Cmp(dhSinglePass_stdDH_sha256kdf) {
  179. params.hashAlgo = crypto.SHA256
  180. params.Hash = sha256.New
  181. } else if asnParams.Cmp(dhSinglePass_stdDH_sha384kdf) {
  182. params.hashAlgo = crypto.SHA384
  183. params.Hash = sha512.New384
  184. } else if asnParams.Cmp(dhSinglePass_stdDH_sha512kdf) {
  185. params.hashAlgo = crypto.SHA512
  186. params.Hash = sha512.New
  187. } else {
  188. params = nil
  189. }
  190. }