PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/crypto/ecies/ecies_test.go

https://gitlab.com/akomba/ether-bot-wallet
Go | 543 lines | 415 code | 72 blank | 56 comment | 152 complexity | a13659aea0686d8f7a126d1f1e9a6a70 MD5 | raw file
  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. "flag"
  36. "fmt"
  37. "io/ioutil"
  38. "testing"
  39. )
  40. var dumpEnc bool
  41. func init() {
  42. flDump := flag.Bool("dump", false, "write encrypted test message to file")
  43. flag.Parse()
  44. dumpEnc = *flDump
  45. }
  46. // Ensure the KDF generates appropriately sized keys.
  47. func TestKDF(t *testing.T) {
  48. msg := []byte("Hello, world")
  49. h := sha256.New()
  50. k, err := concatKDF(h, msg, nil, 64)
  51. if err != nil {
  52. fmt.Println(err.Error())
  53. t.FailNow()
  54. }
  55. if len(k) != 64 {
  56. fmt.Printf("KDF: generated key is the wrong size (%d instead of 64\n",
  57. len(k))
  58. t.FailNow()
  59. }
  60. }
  61. var skLen int
  62. var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match")
  63. // cmpParams compares a set of ECIES parameters. We assume, as per the
  64. // docs, that AES is the only supported symmetric encryption algorithm.
  65. func cmpParams(p1, p2 *ECIESParams) bool {
  66. if p1.hashAlgo != p2.hashAlgo {
  67. return false
  68. } else if p1.KeyLen != p2.KeyLen {
  69. return false
  70. } else if p1.BlockSize != p2.BlockSize {
  71. return false
  72. }
  73. return true
  74. }
  75. // cmpPublic returns true if the two public keys represent the same pojnt.
  76. func cmpPublic(pub1, pub2 PublicKey) bool {
  77. if pub1.X == nil || pub1.Y == nil {
  78. fmt.Println(ErrInvalidPublicKey.Error())
  79. return false
  80. }
  81. if pub2.X == nil || pub2.Y == nil {
  82. fmt.Println(ErrInvalidPublicKey.Error())
  83. return false
  84. }
  85. pub1Out := elliptic.Marshal(pub1.Curve, pub1.X, pub1.Y)
  86. pub2Out := elliptic.Marshal(pub2.Curve, pub2.X, pub2.Y)
  87. return bytes.Equal(pub1Out, pub2Out)
  88. }
  89. // cmpPrivate returns true if the two private keys are the same.
  90. func cmpPrivate(prv1, prv2 *PrivateKey) bool {
  91. if prv1 == nil || prv1.D == nil {
  92. return false
  93. } else if prv2 == nil || prv2.D == nil {
  94. return false
  95. } else if prv1.D.Cmp(prv2.D) != 0 {
  96. return false
  97. } else {
  98. return cmpPublic(prv1.PublicKey, prv2.PublicKey)
  99. }
  100. }
  101. // Validate the ECDH component.
  102. func TestSharedKey(t *testing.T) {
  103. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  104. if err != nil {
  105. fmt.Println(err.Error())
  106. t.FailNow()
  107. }
  108. skLen = MaxSharedKeyLength(&prv1.PublicKey) / 2
  109. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  110. if err != nil {
  111. fmt.Println(err.Error())
  112. t.FailNow()
  113. }
  114. sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen)
  115. if err != nil {
  116. fmt.Println(err.Error())
  117. t.FailNow()
  118. }
  119. sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen)
  120. if err != nil {
  121. fmt.Println(err.Error())
  122. t.FailNow()
  123. }
  124. if !bytes.Equal(sk1, sk2) {
  125. fmt.Println(ErrBadSharedKeys.Error())
  126. t.FailNow()
  127. }
  128. }
  129. // Verify that the key generation code fails when too much key data is
  130. // requested.
  131. func TestTooBigSharedKey(t *testing.T) {
  132. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  133. if err != nil {
  134. fmt.Println(err.Error())
  135. t.FailNow()
  136. }
  137. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  138. if err != nil {
  139. fmt.Println(err.Error())
  140. t.FailNow()
  141. }
  142. _, err = prv1.GenerateShared(&prv2.PublicKey, skLen*2, skLen*2)
  143. if err != ErrSharedKeyTooBig {
  144. fmt.Println("ecdh: shared key should be too large for curve")
  145. t.FailNow()
  146. }
  147. _, err = prv2.GenerateShared(&prv1.PublicKey, skLen*2, skLen*2)
  148. if err != ErrSharedKeyTooBig {
  149. fmt.Println("ecdh: shared key should be too large for curve")
  150. t.FailNow()
  151. }
  152. }
  153. // Ensure a public key can be successfully marshalled and unmarshalled, and
  154. // that the decoded key is the same as the original.
  155. func TestMarshalPublic(t *testing.T) {
  156. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  157. if err != nil {
  158. fmt.Println(err.Error())
  159. t.FailNow()
  160. }
  161. out, err := MarshalPublic(&prv.PublicKey)
  162. if err != nil {
  163. fmt.Println(err.Error())
  164. t.FailNow()
  165. }
  166. pub, err := UnmarshalPublic(out)
  167. if err != nil {
  168. fmt.Println(err.Error())
  169. t.FailNow()
  170. }
  171. if !cmpPublic(prv.PublicKey, *pub) {
  172. fmt.Println("ecies: failed to unmarshal public key")
  173. t.FailNow()
  174. }
  175. }
  176. // Ensure that a private key can be encoded into DER format, and that
  177. // the resulting key is properly parsed back into a public key.
  178. func TestMarshalPrivate(t *testing.T) {
  179. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  180. if err != nil {
  181. fmt.Println(err.Error())
  182. t.FailNow()
  183. }
  184. out, err := MarshalPrivate(prv)
  185. if err != nil {
  186. fmt.Println(err.Error())
  187. t.FailNow()
  188. }
  189. if dumpEnc {
  190. ioutil.WriteFile("test.out", out, 0644)
  191. }
  192. prv2, err := UnmarshalPrivate(out)
  193. if err != nil {
  194. fmt.Println(err.Error())
  195. t.FailNow()
  196. }
  197. if !cmpPrivate(prv, prv2) {
  198. fmt.Println("ecdh: private key import failed")
  199. t.FailNow()
  200. }
  201. }
  202. // Ensure that a private key can be successfully encoded to PEM format, and
  203. // the resulting key is properly parsed back in.
  204. func TestPrivatePEM(t *testing.T) {
  205. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  206. if err != nil {
  207. fmt.Println(err.Error())
  208. t.FailNow()
  209. }
  210. out, err := ExportPrivatePEM(prv)
  211. if err != nil {
  212. fmt.Println(err.Error())
  213. t.FailNow()
  214. }
  215. if dumpEnc {
  216. ioutil.WriteFile("test.key", out, 0644)
  217. }
  218. prv2, err := ImportPrivatePEM(out)
  219. if err != nil {
  220. fmt.Println(err.Error())
  221. t.FailNow()
  222. } else if !cmpPrivate(prv, prv2) {
  223. fmt.Println("ecdh: import from PEM failed")
  224. t.FailNow()
  225. }
  226. }
  227. // Ensure that a public key can be successfully encoded to PEM format, and
  228. // the resulting key is properly parsed back in.
  229. func TestPublicPEM(t *testing.T) {
  230. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  231. if err != nil {
  232. fmt.Println(err.Error())
  233. t.FailNow()
  234. }
  235. out, err := ExportPublicPEM(&prv.PublicKey)
  236. if err != nil {
  237. fmt.Println(err.Error())
  238. t.FailNow()
  239. }
  240. if dumpEnc {
  241. ioutil.WriteFile("test.pem", out, 0644)
  242. }
  243. pub2, err := ImportPublicPEM(out)
  244. if err != nil {
  245. fmt.Println(err.Error())
  246. t.FailNow()
  247. } else if !cmpPublic(prv.PublicKey, *pub2) {
  248. fmt.Println("ecdh: import from PEM failed")
  249. t.FailNow()
  250. }
  251. }
  252. // Benchmark the generation of P256 keys.
  253. func BenchmarkGenerateKeyP256(b *testing.B) {
  254. for i := 0; i < b.N; i++ {
  255. if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil {
  256. fmt.Println(err.Error())
  257. b.FailNow()
  258. }
  259. }
  260. }
  261. // Benchmark the generation of P256 shared keys.
  262. func BenchmarkGenSharedKeyP256(b *testing.B) {
  263. prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil)
  264. if err != nil {
  265. fmt.Println(err.Error())
  266. b.FailNow()
  267. }
  268. for i := 0; i < b.N; i++ {
  269. _, err := prv.GenerateShared(&prv.PublicKey, skLen, skLen)
  270. if err != nil {
  271. fmt.Println(err.Error())
  272. b.FailNow()
  273. }
  274. }
  275. }
  276. // Verify that an encrypted message can be successfully decrypted.
  277. func TestEncryptDecrypt(t *testing.T) {
  278. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  279. if err != nil {
  280. fmt.Println(err.Error())
  281. t.FailNow()
  282. }
  283. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  284. if err != nil {
  285. fmt.Println(err.Error())
  286. t.FailNow()
  287. }
  288. message := []byte("Hello, world.")
  289. ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil)
  290. if err != nil {
  291. fmt.Println(err.Error())
  292. t.FailNow()
  293. }
  294. pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil)
  295. if err != nil {
  296. fmt.Println(err.Error())
  297. t.FailNow()
  298. }
  299. if !bytes.Equal(pt, message) {
  300. fmt.Println("ecies: plaintext doesn't match message")
  301. t.FailNow()
  302. }
  303. _, err = prv1.Decrypt(rand.Reader, ct, nil, nil)
  304. if err == nil {
  305. fmt.Println("ecies: encryption should not have succeeded")
  306. t.FailNow()
  307. }
  308. }
  309. func TestDecryptShared2(t *testing.T) {
  310. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  311. if err != nil {
  312. t.Fatal(err)
  313. }
  314. message := []byte("Hello, world.")
  315. shared2 := []byte("shared data 2")
  316. ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, shared2)
  317. if err != nil {
  318. t.Fatal(err)
  319. }
  320. // Check that decrypting with correct shared data works.
  321. pt, err := prv.Decrypt(rand.Reader, ct, nil, shared2)
  322. if err != nil {
  323. t.Fatal(err)
  324. }
  325. if !bytes.Equal(pt, message) {
  326. t.Fatal("ecies: plaintext doesn't match message")
  327. }
  328. // Decrypting without shared data or incorrect shared data fails.
  329. if _, err = prv.Decrypt(rand.Reader, ct, nil, nil); err == nil {
  330. t.Fatal("ecies: decrypting without shared data didn't fail")
  331. }
  332. if _, err = prv.Decrypt(rand.Reader, ct, nil, []byte("garbage")); err == nil {
  333. t.Fatal("ecies: decrypting with incorrect shared data didn't fail")
  334. }
  335. }
  336. // TestMarshalEncryption validates the encode/decode produces a valid
  337. // ECIES encryption key.
  338. func TestMarshalEncryption(t *testing.T) {
  339. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  340. if err != nil {
  341. fmt.Println(err.Error())
  342. t.FailNow()
  343. }
  344. out, err := MarshalPrivate(prv1)
  345. if err != nil {
  346. fmt.Println(err.Error())
  347. t.FailNow()
  348. }
  349. prv2, err := UnmarshalPrivate(out)
  350. if err != nil {
  351. fmt.Println(err.Error())
  352. t.FailNow()
  353. }
  354. message := []byte("Hello, world.")
  355. ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil)
  356. if err != nil {
  357. fmt.Println(err.Error())
  358. t.FailNow()
  359. }
  360. pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil)
  361. if err != nil {
  362. fmt.Println(err.Error())
  363. t.FailNow()
  364. }
  365. if !bytes.Equal(pt, message) {
  366. fmt.Println("ecies: plaintext doesn't match message")
  367. t.FailNow()
  368. }
  369. _, err = prv1.Decrypt(rand.Reader, ct, nil, nil)
  370. if err != nil {
  371. fmt.Println(err.Error())
  372. t.FailNow()
  373. }
  374. }
  375. type testCase struct {
  376. Curve elliptic.Curve
  377. Name string
  378. Expected bool
  379. }
  380. var testCases = []testCase{
  381. testCase{
  382. Curve: elliptic.P256(),
  383. Name: "P256",
  384. Expected: true,
  385. },
  386. testCase{
  387. Curve: elliptic.P384(),
  388. Name: "P384",
  389. Expected: true,
  390. },
  391. testCase{
  392. Curve: elliptic.P521(),
  393. Name: "P521",
  394. Expected: true,
  395. },
  396. }
  397. // Test parameter selection for each curve, and that P224 fails automatic
  398. // parameter selection (see README for a discussion of P224). Ensures that
  399. // selecting a set of parameters automatically for the given curve works.
  400. func TestParamSelection(t *testing.T) {
  401. for _, c := range testCases {
  402. testParamSelection(t, c)
  403. }
  404. }
  405. func testParamSelection(t *testing.T, c testCase) {
  406. params := ParamsFromCurve(c.Curve)
  407. if params == nil && c.Expected {
  408. fmt.Printf("%s (%s)\n", ErrInvalidParams.Error(), c.Name)
  409. t.FailNow()
  410. } else if params != nil && !c.Expected {
  411. fmt.Printf("ecies: parameters should be invalid (%s)\n",
  412. c.Name)
  413. t.FailNow()
  414. }
  415. prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  416. if err != nil {
  417. fmt.Printf("%s (%s)\n", err.Error(), c.Name)
  418. t.FailNow()
  419. }
  420. prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  421. if err != nil {
  422. fmt.Printf("%s (%s)\n", err.Error(), c.Name)
  423. t.FailNow()
  424. }
  425. message := []byte("Hello, world.")
  426. ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil)
  427. if err != nil {
  428. fmt.Printf("%s (%s)\n", err.Error(), c.Name)
  429. t.FailNow()
  430. }
  431. pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil)
  432. if err != nil {
  433. fmt.Printf("%s (%s)\n", err.Error(), c.Name)
  434. t.FailNow()
  435. }
  436. if !bytes.Equal(pt, message) {
  437. fmt.Printf("ecies: plaintext doesn't match message (%s)\n",
  438. c.Name)
  439. t.FailNow()
  440. }
  441. _, err = prv1.Decrypt(rand.Reader, ct, nil, nil)
  442. if err == nil {
  443. fmt.Printf("ecies: encryption should not have succeeded (%s)\n",
  444. c.Name)
  445. t.FailNow()
  446. }
  447. }
  448. // Ensure that the basic public key validation in the decryption operation
  449. // works.
  450. func TestBasicKeyValidation(t *testing.T) {
  451. badBytes := []byte{0, 1, 5, 6, 7, 8, 9}
  452. prv, err := GenerateKey(rand.Reader, DefaultCurve, nil)
  453. if err != nil {
  454. fmt.Println(err.Error())
  455. t.FailNow()
  456. }
  457. message := []byte("Hello, world.")
  458. ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil)
  459. if err != nil {
  460. fmt.Println(err.Error())
  461. t.FailNow()
  462. }
  463. for _, b := range badBytes {
  464. ct[0] = b
  465. _, err := prv.Decrypt(rand.Reader, ct, nil, nil)
  466. if err != ErrInvalidPublicKey {
  467. fmt.Println("ecies: validated an invalid key")
  468. t.FailNow()
  469. }
  470. }
  471. }