ecies_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  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. import (
  31. "bytes"
  32. "crypto/elliptic"
  33. "crypto/rand"
  34. "crypto/sha256"
  35. "encoding/hex"
  36. "fmt"
  37. "math/big"
  38. "testing"
  39. "github.com/ethereum/go-ethereum/crypto"
  40. )
  41. func TestKDF(t *testing.T) {
  42. tests := []struct {
  43. length int
  44. output []byte
  45. }{
  46. {6, decode("858b192fa2ed")},
  47. {32, decode("858b192fa2ed4395e2bf88dd8d5770d67dc284ee539f12da8bceaa45d06ebae0")},
  48. {48, decode("858b192fa2ed4395e2bf88dd8d5770d67dc284ee539f12da8bceaa45d06ebae0700f1ab918a5f0413b8140f9940d6955")},
  49. {64, decode("858b192fa2ed4395e2bf88dd8d5770d67dc284ee539f12da8bceaa45d06ebae0700f1ab918a5f0413b8140f9940d6955f3467fd6672cce1024c5b1effccc0f61")},
  50. }
  51. for _, test := range tests {
  52. h := sha256.New()
  53. k := concatKDF(h, []byte("input"), nil, test.length)
  54. if !bytes.Equal(k, test.output) {
  55. t.Fatalf("KDF: generated key %x does not match expected output %x", k, test.output)
  56. }
  57. }
  58. }
  59. var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match")
  60. // cmpParams compares a set of ECIES parameters. We assume, as per the
  61. // docs, that AES is the only supported symmetric encryption algorithm.
  62. func cmpParams(p1, p2 *ECIESParams) bool {
  63. return p1.hashAlgo == p2.hashAlgo &&
  64. p1.KeyLen == p2.KeyLen &&
  65. p1.BlockSize == p2.BlockSize
  66. }
  67. // Validate the ECDH component.
  68. func TestSharedKey(t *testing.T) {
  69. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  70. if err != nil {
  71. t.Fatal(err)
  72. }
  73. skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2
  74. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen)
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen)
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. if !bytes.Equal(sk1, sk2) {
  87. t.Fatal(ErrBadSharedKeys)
  88. }
  89. }
  90. func TestSharedKeyPadding(t *testing.T) {
  91. // sanity checks
  92. prv0 := hexKey("1adf5c18167d96a1f9a0b1ef63be8aa27eaf6032c233b2b38f7850cf5b859fd9")
  93. prv1 := hexKey("0097a076fc7fcd9208240668e31c9abee952cbb6e375d1b8febc7499d6e16f1a")
  94. x0, _ := new(big.Int).SetString("1a8ed022ff7aec59dc1b440446bdda5ff6bcb3509a8b109077282b361efffbd8", 16)
  95. x1, _ := new(big.Int).SetString("6ab3ac374251f638d0abb3ef596d1dc67955b507c104e5f2009724812dc027b8", 16)
  96. y0, _ := new(big.Int).SetString("e040bd480b1deccc3bc40bd5b1fdcb7bfd352500b477cb9471366dbd4493f923", 16)
  97. y1, _ := new(big.Int).SetString("8ad915f2b503a8be6facab6588731fefeb584fd2dfa9a77a5e0bba1ec439e4fa", 16)
  98. if prv0.PublicKey.X.Cmp(x0) != 0 {
  99. t.Errorf("mismatched prv0.X:\nhave: %x\nwant: %x\n", prv0.PublicKey.X.Bytes(), x0.Bytes())
  100. }
  101. if prv0.PublicKey.Y.Cmp(y0) != 0 {
  102. t.Errorf("mismatched prv0.Y:\nhave: %x\nwant: %x\n", prv0.PublicKey.Y.Bytes(), y0.Bytes())
  103. }
  104. if prv1.PublicKey.X.Cmp(x1) != 0 {
  105. t.Errorf("mismatched prv1.X:\nhave: %x\nwant: %x\n", prv1.PublicKey.X.Bytes(), x1.Bytes())
  106. }
  107. if prv1.PublicKey.Y.Cmp(y1) != 0 {
  108. t.Errorf("mismatched prv1.Y:\nhave: %x\nwant: %x\n", prv1.PublicKey.Y.Bytes(), y1.Bytes())
  109. }
  110. // test shared secret generation
  111. sk1, err := prv0.GenerateShared(&prv1.PublicKey, 16, 16)
  112. if err != nil {
  113. t.Log(err.Error())
  114. }
  115. sk2, err := prv1.GenerateShared(&prv0.PublicKey, 16, 16)
  116. if err != nil {
  117. t.Fatal(err.Error())
  118. }
  119. if !bytes.Equal(sk1, sk2) {
  120. t.Fatal(ErrBadSharedKeys.Error())
  121. }
  122. }
  123. // Verify that the key generation code fails when too much key data is
  124. // requested.
  125. func TestTooBigSharedKey(t *testing.T) {
  126. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  127. if err != nil {
  128. t.Fatal(err)
  129. }
  130. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  131. if err != nil {
  132. t.Fatal(err)
  133. }
  134. _, err = prv1.GenerateShared(&prv2.PublicKey, 32, 32)
  135. if err != ErrSharedKeyTooBig {
  136. t.Fatal("ecdh: shared key should be too large for curve")
  137. }
  138. _, err = prv2.GenerateShared(&prv1.PublicKey, 32, 32)
  139. if err != ErrSharedKeyTooBig {
  140. t.Fatal("ecdh: shared key should be too large for curve")
  141. }
  142. }
  143. // Benchmark the generation of P256 keys.
  144. func BenchmarkGenerateKeyP256(b *testing.B) {
  145. for i := 0; i < b.N; i++ {
  146. if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil {
  147. b.Fatal(err)
  148. }
  149. }
  150. }
  151. // Benchmark the generation of P256 shared keys.
  152. func BenchmarkGenSharedKeyP256(b *testing.B) {
  153. prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil)
  154. if err != nil {
  155. b.Fatal(err)
  156. }
  157. b.ResetTimer()
  158. for i := 0; i < b.N; i++ {
  159. _, err := prv.GenerateShared(&prv.PublicKey, 16, 16)
  160. if err != nil {
  161. b.Fatal(err)
  162. }
  163. }
  164. }
  165. // Benchmark the generation of S256 shared keys.
  166. func BenchmarkGenSharedKeyS256(b *testing.B) {
  167. prv, err := GenerateKey(rand.Reader, crypto.S256(), nil)
  168. if err != nil {
  169. b.Fatal(err)
  170. }
  171. b.ResetTimer()
  172. for i := 0; i < b.N; i++ {
  173. _, err := prv.GenerateShared(&prv.PublicKey, 16, 16)
  174. if err != nil {
  175. b.Fatal(err)
  176. }
  177. }
  178. }
  179. // Verify that an encrypted message can be successfully decrypted.
  180. func TestEncryptDecrypt(t *testing.T) {
  181. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  186. if err != nil {
  187. t.Fatal(err)
  188. }
  189. message := []byte("Hello, world.")
  190. ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil)
  191. if err != nil {
  192. t.Fatal(err)
  193. }
  194. pt, err := prv2.Decrypt(ct, nil, nil)
  195. if err != nil {
  196. t.Fatal(err)
  197. }
  198. if !bytes.Equal(pt, message) {
  199. t.Fatal("ecies: plaintext doesn't match message")
  200. }
  201. _, err = prv1.Decrypt(ct, nil, nil)
  202. if err == nil {
  203. t.Fatal("ecies: encryption should not have succeeded")
  204. }
  205. }
  206. func TestDecryptShared2(t *testing.T) {
  207. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  208. if err != nil {
  209. t.Fatal(err)
  210. }
  211. message := []byte("Hello, world.")
  212. shared2 := []byte("shared data 2")
  213. ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, shared2)
  214. if err != nil {
  215. t.Fatal(err)
  216. }
  217. // Check that decrypting with correct shared data works.
  218. pt, err := prv.Decrypt(ct, nil, shared2)
  219. if err != nil {
  220. t.Fatal(err)
  221. }
  222. if !bytes.Equal(pt, message) {
  223. t.Fatal("ecies: plaintext doesn't match message")
  224. }
  225. // Decrypting without shared data or incorrect shared data fails.
  226. if _, err = prv.Decrypt(ct, nil, nil); err == nil {
  227. t.Fatal("ecies: decrypting without shared data didn't fail")
  228. }
  229. if _, err = prv.Decrypt(ct, nil, []byte("garbage")); err == nil {
  230. t.Fatal("ecies: decrypting with incorrect shared data didn't fail")
  231. }
  232. }
  233. type testCase struct {
  234. Curve elliptic.Curve
  235. Name string
  236. Expected *ECIESParams
  237. }
  238. var testCases = []testCase{
  239. {
  240. Curve: elliptic.P256(),
  241. Name: "P256",
  242. Expected: ECIES_AES128_SHA256,
  243. },
  244. {
  245. Curve: elliptic.P384(),
  246. Name: "P384",
  247. Expected: ECIES_AES256_SHA384,
  248. },
  249. {
  250. Curve: elliptic.P521(),
  251. Name: "P521",
  252. Expected: ECIES_AES256_SHA512,
  253. },
  254. }
  255. // Test parameter selection for each curve, and that P224 fails automatic
  256. // parameter selection (see README for a discussion of P224). Ensures that
  257. // selecting a set of parameters automatically for the given curve works.
  258. func TestParamSelection(t *testing.T) {
  259. for _, c := range testCases {
  260. testParamSelection(t, c)
  261. }
  262. }
  263. func testParamSelection(t *testing.T, c testCase) {
  264. params := ParamsFromCurve(c.Curve)
  265. if params == nil {
  266. t.Fatal("ParamsFromCurve returned nil")
  267. } else if params != nil && !cmpParams(params, c.Expected) {
  268. t.Fatalf("ecies: parameters should be invalid (%s)\n", c.Name)
  269. }
  270. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  271. if err != nil {
  272. t.Fatalf("%s (%s)\n", err.Error(), c.Name)
  273. }
  274. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  275. if err != nil {
  276. t.Fatalf("%s (%s)\n", err.Error(), c.Name)
  277. }
  278. message := []byte("Hello, world.")
  279. ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil)
  280. if err != nil {
  281. t.Fatalf("%s (%s)\n", err.Error(), c.Name)
  282. }
  283. pt, err := prv2.Decrypt(ct, nil, nil)
  284. if err != nil {
  285. t.Fatalf("%s (%s)\n", err.Error(), c.Name)
  286. }
  287. if !bytes.Equal(pt, message) {
  288. t.Fatalf("ecies: plaintext doesn't match message (%s)\n", c.Name)
  289. }
  290. _, err = prv1.Decrypt(ct, nil, nil)
  291. if err == nil {
  292. t.Fatalf("ecies: encryption should not have succeeded (%s)\n", c.Name)
  293. }
  294. }
  295. // Ensure that the basic public key validation in the decryption operation
  296. // works.
  297. func TestBasicKeyValidation(t *testing.T) {
  298. badBytes := []byte{0, 1, 5, 6, 7, 8, 9}
  299. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  300. if err != nil {
  301. t.Fatal(err)
  302. }
  303. message := []byte("Hello, world.")
  304. ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil)
  305. if err != nil {
  306. t.Fatal(err)
  307. }
  308. for _, b := range badBytes {
  309. ct[0] = b
  310. _, err := prv.Decrypt(ct, nil, nil)
  311. if err != ErrInvalidPublicKey {
  312. t.Fatal("ecies: validated an invalid key")
  313. }
  314. }
  315. }
  316. func TestBox(t *testing.T) {
  317. prv1 := hexKey("4b50fa71f5c3eeb8fdc452224b2395af2fcc3d125e06c32c82e048c0559db03f")
  318. prv2 := hexKey("d0b043b4c5d657670778242d82d68a29d25d7d711127d17b8e299f156dad361a")
  319. pub2 := &prv2.PublicKey
  320. message := []byte("Hello, world.")
  321. ct, err := Encrypt(rand.Reader, pub2, message, nil, nil)
  322. if err != nil {
  323. t.Fatal(err)
  324. }
  325. pt, err := prv2.Decrypt(ct, nil, nil)
  326. if err != nil {
  327. t.Fatal(err)
  328. }
  329. if !bytes.Equal(pt, message) {
  330. t.Fatal("ecies: plaintext doesn't match message")
  331. }
  332. if _, err = prv1.Decrypt(ct, nil, nil); err == nil {
  333. t.Fatal("ecies: encryption should not have succeeded")
  334. }
  335. }
  336. // Verify GenerateShared against static values - useful when
  337. // debugging changes in underlying libs
  338. func TestSharedKeyStatic(t *testing.T) {
  339. prv1 := hexKey("7ebbc6a8358bc76dd73ebc557056702c8cfc34e5cfcd90eb83af0347575fd2ad")
  340. prv2 := hexKey("6a3d6396903245bba5837752b9e0348874e72db0c4e11e9c485a81b4ea4353b9")
  341. skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2
  342. sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen)
  343. if err != nil {
  344. t.Fatal(err)
  345. }
  346. sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen)
  347. if err != nil {
  348. t.Fatal(err)
  349. }
  350. if !bytes.Equal(sk1, sk2) {
  351. t.Fatal(ErrBadSharedKeys)
  352. }
  353. sk := decode("167ccc13ac5e8a26b131c3446030c60fbfac6aa8e31149d0869f93626a4cdf62")
  354. if !bytes.Equal(sk1, sk) {
  355. t.Fatalf("shared secret mismatch: want: %x have: %x", sk, sk1)
  356. }
  357. }
  358. func hexKey(prv string) *PrivateKey {
  359. key, err := crypto.HexToECDSA(prv)
  360. if err != nil {
  361. panic(err)
  362. }
  363. return ImportECDSA(key)
  364. }
  365. func decode(s string) []byte {
  366. bytes, err := hex.DecodeString(s)
  367. if err != nil {
  368. panic(err)
  369. }
  370. return bytes
  371. }