You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

601 lines
14 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. # cryptofun [![Go Report Card](https://goreportcard.com/badge/github.com/arnaucube/cryptofun)](https://goreportcard.com/report/github.com/arnaucube/cryptofun)
  2. Crypto algorithms from scratch. Academic purposes only.
  3. - [RSA cryptosystem & Blind signature & Homomorphic Multiplication](#rsa-cryptosystem--blind-signature--homomorphic-multiplication)
  4. - [Paillier cryptosystem & Homomorphic Addition](#paillier-cryptosystem--homomorphic-addition)
  5. - [Shamir Secret Sharing](#shamir-secret-sharing)
  6. - [Diffie-Hellman](#diffie-hellman)
  7. - [ECC](#ecc)
  8. - [ECC ElGamal](#ecc-elgamal)
  9. - [ECC ECDSA](#ecc-ecdsa)
  10. - [Schnorr signature](#schnorr-signature)
  11. - [Bn128](#bn128)
  12. ---
  13. ## RSA cryptosystem & Blind signature & Homomorphic Multiplication
  14. - https://en.wikipedia.org/wiki/RSA_(cryptosystem)#
  15. - https://en.wikipedia.org/wiki/Blind_signature
  16. - https://en.wikipedia.org/wiki/Homomorphic_encryption
  17. - [x] GenerateKeyPair
  18. - [x] Encrypt
  19. - [x] Decrypt
  20. - [x] Blind
  21. - [x] Blind Signature
  22. - [x] Unblind Signature
  23. - [x] Verify Signature
  24. - [x] Homomorphic Multiplication
  25. #### Usage
  26. - Key generation, Encryption, Decryption
  27. ```go
  28. // generate key pair
  29. key, err := GenerateKeyPair()
  30. if err!=nil {
  31. fmt.Println(err)
  32. }
  33. mBytes := []byte("Hi")
  34. m := new(big.Int).SetBytes(mBytes)
  35. // encrypt message
  36. c := Encrypt(m, key.PubK)
  37. // decrypt ciphertext
  38. d := Decrypt(c, key.PrivK)
  39. if m == d {
  40. fmt.Println("correctly decrypted")
  41. }
  42. ```
  43. - Blind signatures
  44. ```go
  45. // key generation [Alice]
  46. key, err := GenerateKeyPair()
  47. if err!=nil {
  48. fmt.Println(err)
  49. }
  50. // create new message [Alice]
  51. mBytes := []byte("Hi")
  52. m := new(big.Int).SetBytes(mBytes)
  53. // define r value [Alice]
  54. rVal := big.NewInt(int64(101))
  55. // blind message [Alice]
  56. mBlinded := Blind(m, rVal, key.PubK)
  57. // Blind Sign the blinded message [Bob]
  58. sigma := BlindSign(mBlinded, key.PrivK)
  59. // unblind the blinded signed message, and get the signature of the message [Alice]
  60. mSigned := Unblind(sigma, rVal, key.PubK)
  61. // verify the signature [Alice/Bob/Trudy]
  62. verified := Verify(m, mSigned, key.PubK)
  63. if !verified {
  64. fmt.Println("signature could not be verified")
  65. }
  66. ```
  67. - Homomorphic Multiplication
  68. ```go
  69. // key generation [Alice]
  70. key, err := GenerateKeyPair()
  71. if err!=nil {
  72. fmt.Println(err)
  73. }
  74. // define values [Alice]
  75. n1 := big.NewInt(int64(11))
  76. n2 := big.NewInt(int64(15))
  77. // encrypt the values [Alice]
  78. c1 := Encrypt(n1, key.PubK)
  79. c2 := Encrypt(n2, key.PubK)
  80. // compute homomorphic multiplication with the encrypted values [Bob]
  81. c3c4 := HomomorphicMul(c1, c2, key.PubK)
  82. // decrypt the result [Alice]
  83. d := Decrypt(c3c4, key.PrivK)
  84. // check that the result is the expected
  85. if !bytes.Equal(new(big.Int).Mul(n1, n2).Bytes(), d.Bytes()) {
  86. fmt.Println("decrypted result not equal to expected result")
  87. }
  88. ```
  89. ## Paillier cryptosystem & Homomorphic Addition
  90. - https://en.wikipedia.org/wiki/Paillier_cryptosystem
  91. - https://en.wikipedia.org/wiki/Homomorphic_encryption
  92. - [x] GenerateKeyPair
  93. - [x] Encrypt
  94. - [x] Decrypt
  95. - [x] Homomorphic Addition
  96. #### Usage
  97. - Encrypt, Decrypt
  98. ```go
  99. // key generation
  100. key, err := GenerateKeyPair()
  101. if err!=nil {
  102. fmt.Println(err)
  103. }
  104. mBytes := []byte("Hi")
  105. m := new(big.Int).SetBytes(mBytes)
  106. // encryption
  107. c := Encrypt(m, key.PubK)
  108. // decryption
  109. d := Decrypt(c, key.PubK, key.PrivK)
  110. if m == d {
  111. fmt.Println("ciphertext decrypted correctly")
  112. }
  113. ```
  114. - Homomorphic Addition
  115. ```go
  116. // key generation [Alice]
  117. key, err := GenerateKeyPair()
  118. if err!=nil {
  119. fmt.Println(err)
  120. }
  121. // define values [Alice]
  122. n1 := big.NewInt(int64(110))
  123. n2 := big.NewInt(int64(150))
  124. // encrypt values [Alice]
  125. c1 := Encrypt(n1, key.PubK)
  126. c2 := Encrypt(n2, key.PubK)
  127. // compute homomorphic addition [Bob]
  128. c3c4 := HomomorphicAddition(c1, c2, key.PubK)
  129. // decrypt the result [Alice]
  130. d := Decrypt(c3c4, key.PubK, key.PrivK)
  131. if !bytes.Equal(new(big.Int).Add(n1, n2).Bytes(), d.Bytes()) {
  132. fmt.Println("decrypted result not equal to expected result")
  133. }
  134. ```
  135. ## Shamir Secret Sharing
  136. - https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing
  137. - [x] create secret sharing from number of secrets needed, number of shares, random point p, secret to share
  138. - [x] Lagrange Interpolation to restore the secret from the shares
  139. #### Usage
  140. ```go
  141. // define secret to share
  142. k := 123456789
  143. // define random prime
  144. p, err := rand.Prime(rand.Reader, bits/2)
  145. if err!=nil {
  146. fmt.Println(err)
  147. }
  148. // define how many shares want to generate
  149. nShares := big.NewInt(int64(6))
  150. // define how many shares are needed to recover the secret
  151. nNeededShares := big.NewInt(int64(3))
  152. // create the shares
  153. shares, err := Create(
  154. nNeededShares,
  155. nShares,
  156. p,
  157. big.NewInt(int64(k)))
  158. assert.Nil(t, err)
  159. if err!=nil {
  160. fmt.Println(err)
  161. }
  162. // select shares to use
  163. var sharesToUse [][]*big.Int
  164. sharesToUse = append(sharesToUse, shares[2])
  165. sharesToUse = append(sharesToUse, shares[1])
  166. sharesToUse = append(sharesToUse, shares[0])
  167. // recover the secret using Lagrange Interpolation
  168. secr := LagrangeInterpolation(sharesToUse, p)
  169. // check that the restored secret matches the original secret
  170. if !bytes.Equal(k.Bytes(), secr.Bytes()) {
  171. fmt.Println("reconstructed secret not correspond to original secret")
  172. }
  173. ```
  174. ## Diffie-Hellman
  175. - https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
  176. - [x] key exchange
  177. ## ECC
  178. - https://en.wikipedia.org/wiki/Elliptic-curve_cryptography
  179. - [x] define elliptic curve
  180. - [x] get point at X
  181. - [x] get order of a Point on the elliptic curve
  182. - [x] Add two points on the elliptic curve
  183. - [x] Multiply a point n times on the elliptic curve
  184. #### Usage
  185. - ECC basic operations
  186. ```go
  187. // define new ec
  188. ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
  189. // define two points over the curve
  190. p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(7))}
  191. p2 := Point{big.NewInt(int64(2)), big.NewInt(int64(2))}
  192. // add the two points
  193. q, err := ec.Add(p1, p2)
  194. if err!=nil {
  195. fmt.Println(err)
  196. }
  197. // multiply the two points
  198. q, err := ec.Mul(p, big.NewInt(int64(1)))
  199. if err!=nil {
  200. fmt.Println(err)
  201. }
  202. // get order of a generator point over the elliptic curve
  203. g := Point{big.NewInt(int64(7)), big.NewInt(int64(8))}
  204. order, err := ec.Order(g)
  205. if err!=nil {
  206. fmt.Println(err)
  207. }
  208. ```
  209. ## ECC ElGamal
  210. - https://en.wikipedia.org/wiki/ElGamal_encryption
  211. - [x] ECC ElGamal key generation
  212. - [x] ECC ElGamal Encrypton
  213. - [x] ECC ElGamal Decryption
  214. #### Usage
  215. - NewEG, Encryption, Decryption
  216. ```go
  217. // define new elliptic curve
  218. ec := ecc.NewEC(big.NewInt(int64(1)), big.NewInt(int64(18)), big.NewInt(int64(19)))
  219. // define new point
  220. g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
  221. // define new ElGamal crypto system with the elliptic curve and the point
  222. eg, err := NewEG(ec, g)
  223. if err!=nil {
  224. fmt.Println(err)
  225. }
  226. // define privK&pubK over the elliptic curve
  227. privK := big.NewInt(int64(5))
  228. pubK, err := eg.PubK(privK)
  229. if err!=nil {
  230. fmt.Println(err)
  231. }
  232. // define point to encrypt
  233. m := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(12))}
  234. // encrypt
  235. c, err := eg.Encrypt(m, pubK, big.NewInt(int64(15)))
  236. if err!=nil {
  237. fmt.Println(err)
  238. }
  239. // decrypt
  240. d, err := eg.Decrypt(c, privK)
  241. if err!=nil {
  242. fmt.Println(err)
  243. }
  244. // check that decryption is correct
  245. if !m.Equal(d) {
  246. fmt.Println("decrypted not equal to original")
  247. }
  248. ```
  249. ## ECC ECDSA
  250. - https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
  251. - [x] define ECDSA data structure
  252. - [x] ECDSA Sign
  253. - [x] ECDSA Verify signature
  254. #### Usage
  255. ```go
  256. // define new elliptic curve
  257. ec := ecc.NewEC(big.NewInt(int64(1)), big.NewInt(int64(18)), big.NewInt(int64(19)))
  258. // define new point
  259. g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
  260. // define new ECDSA system
  261. dsa, err := NewDSA(ec, g)
  262. if err!=nil {
  263. fmt.Println(err)
  264. }
  265. // define privK&pubK over the elliptic curve
  266. privK := big.NewInt(int64(5))
  267. pubK, err := dsa.PubK(privK)
  268. if err!=nil {
  269. fmt.Println(err)
  270. }
  271. // hash value to sign
  272. hashval := big.NewInt(int64(40))
  273. // define r
  274. r := big.NewInt(int64(11))
  275. // sign hashed value
  276. sig, err := dsa.Sign(hashval, privK, r)
  277. if err!=nil {
  278. fmt.Println(err)
  279. }
  280. // verify signature
  281. verified, err := dsa.Verify(hashval, sig, pubK)
  282. if err!=nil {
  283. fmt.Println(err)
  284. }
  285. if verified {
  286. fmt.Println("signature correctly verified")
  287. }
  288. ```
  289. ## Schnorr signature
  290. - https://en.wikipedia.org/wiki/Schnorr_signature
  291. - [x] Hash[M || R] (where M is the msg bytes and R is a Point on the ECC, using sha256 hash function)
  292. - [x] Generate Schnorr scheme
  293. - [x] Sign
  294. - [x] Verify signature
  295. #### Usage
  296. ```go
  297. // define new elliptic curve
  298. ec := ecc.NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
  299. // define new point
  300. g := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(27))} // Generator
  301. // define new random r
  302. r := big.NewInt(int64(23)) // random r
  303. // define new Schnorr crypto system using the values
  304. schnorr, sk, err := Gen(ec, g, r)
  305. if err!=nil {
  306. fmt.println(err)
  307. }
  308. // define message to sign
  309. m := []byte("hola")
  310. // also we can hash the message, but it's not mandatory, as it will be done inside the schnorr.Sign, but we can perform it now, just to check the function
  311. h := Hash([]byte("hola"), c)
  312. if h.String() != "34719153732582497359642109898768696927847420320548121616059449972754491425079") {
  313. fmt.Println("not correctly hashed")
  314. }
  315. s, rPoint, err := schnorr.Sign(sk, m)
  316. if err!=nil {
  317. fmt.println(err)
  318. }
  319. // verify Schnorr signature
  320. verified, err := Verify(schnorr.EC, sk.PubK, m, s, rPoint)
  321. if err!=nil {
  322. fmt.println(err)
  323. }
  324. if verified {
  325. fmt.Println("Schnorr signature correctly verified")
  326. }
  327. ```
  328. ## Bn128
  329. This is implemented followng the info and the implementations from:
  330. - `Multiplication and Squaring on Pairing-Friendly
  331. Fields`, Augusto Jun Devegili, Colm Ó hÉigeartaigh, Michael Scott, and Ricardo Dahab https://pdfs.semanticscholar.org/3e01/de88d7428076b2547b60072088507d881bf1.pdf
  332. - `Optimal Pairings`, Frederik Vercauteren https://www.cosic.esat.kuleuven.be/bcrypt/optimal.pdf , https://eprint.iacr.org/2008/096.pdf
  333. - `Double-and-Add with Relative Jacobian
  334. Coordinates`, Björn Fay https://eprint.iacr.org/2014/1014.pdf
  335. - `Fast and Regular Algorithms for Scalar Multiplication
  336. over Elliptic Curves`, Matthieu Rivain https://eprint.iacr.org/2011/338.pdf
  337. - `High-Speed Software Implementation of the Optimal Ate Pairing over Barreto–Naehrig Curves`, Jean-Luc Beuchat, Jorge E. González-Díaz, Shigeo Mitsunari, Eiji Okamoto, Francisco Rodríguez-Henríquez, and Tadanori Teruya https://eprint.iacr.org/2010/354.pdf
  338. - `New software speed records for cryptographic pairings`, Michael Naehrig, Ruben Niederhagen, Peter Schwabe https://cryptojedi.org/papers/dclxvi-20100714.pdf
  339. - https://github.com/zcash/zcash/tree/master/src/snark
  340. - https://github.com/iden3/snarkjs
  341. - https://github.com/ethereum/py_ecc/tree/master/py_ecc/bn128
  342. - [x] Fq, Fq2, Fq6, Fq12 operations
  343. - [x] G1, G2 operations
  344. - [x] preparePairing
  345. - [x] PreComupteG1, PreComupteG2
  346. - [x] DoubleStep, AddStep
  347. - [x] MillerLoop
  348. - [x] Pairing
  349. #### Usage
  350. First let's assume that we have these three basic functions to convert integer compositions to big integer compositions:
  351. ```go
  352. func iToBig(a int) *big.Int {
  353. return big.NewInt(int64(a))
  354. }
  355. func iiToBig(a, b int) [2]*big.Int {
  356. return [2]*big.Int{iToBig(a), iToBig(b)}
  357. }
  358. func iiiToBig(a, b int) [2]*big.Int {
  359. return [2]*big.Int{iToBig(a), iToBig(b)}
  360. }
  361. ```
  362. - Pairing
  363. ```go
  364. bn128, err := NewBn128()
  365. assert.Nil(t, err)
  366. big25 := big.NewInt(int64(25))
  367. big30 := big.NewInt(int64(30))
  368. g1a := bn128.G1.MulScalar(bn128.G1.G, big25)
  369. g2a := bn128.G2.MulScalar(bn128.G2.G, big30)
  370. g1b := bn128.G1.MulScalar(bn128.G1.G, big30)
  371. g2b := bn128.G2.MulScalar(bn128.G2.G, big25)
  372. pA, err := bn128.Pairing(g1a, g2a)
  373. assert.Nil(t, err)
  374. pB, err := bn128.Pairing(g1b, g2b)
  375. assert.Nil(t, err)
  376. assert.True(t, bn128.Fq12.Equal(pA, pB))
  377. ```
  378. - Finite Fields (1, 2, 6, 12) operations
  379. ```go
  380. // new finite field of order 1
  381. fq1 := NewFq(iToBig(7))
  382. // basic operations of finite field 1
  383. res := fq1.Add(iToBig(4), iToBig(4))
  384. res = fq1.Double(iToBig(5))
  385. res = fq1.Sub(iToBig(5), iToBig(7))
  386. res = fq1.Neg(iToBig(5))
  387. res = fq1.Mul(iToBig(5), iToBig(11))
  388. res = fq1.Inverse(iToBig(4))
  389. res = fq1.Square(iToBig(5))
  390. // new finite field of order 2
  391. nonResidueFq2str := "-1" // i/j
  392. nonResidueFq2, ok := new(big.Int).SetString(nonResidueFq2str, 10)
  393. fq2 := Fq2{fq1, nonResidueFq2}
  394. nonResidueFq6 := iiToBig(9, 1)
  395. // basic operations of finite field of order 2
  396. res := fq2.Add(iiToBig(4, 4), iiToBig(3, 4))
  397. res = fq2.Double(iiToBig(5, 3))
  398. res = fq2.Sub(iiToBig(5, 3), iiToBig(7, 2))
  399. res = fq2.Neg(iiToBig(4, 4))
  400. res = fq2.Mul(iiToBig(4, 4), iiToBig(3, 4))
  401. res = fq2.Inverse(iiToBig(4, 4))
  402. res = fq2.Div(iiToBig(4, 4), iiToBig(3, 4))
  403. res = fq2.Square(iiToBig(4, 4))
  404. // new finite field of order 6
  405. nonResidueFq6 := iiToBig(9, 1) // TODO
  406. fq6 := Fq6{fq2, nonResidueFq6}
  407. // define two new values of Finite Field 6, in order to be able to perform the operations
  408. a := [3][2]*big.Int{
  409. iiToBig(1, 2),
  410. iiToBig(3, 4),
  411. iiToBig(5, 6)}
  412. b := [3][2]*big.Int{
  413. iiToBig(12, 11),
  414. iiToBig(10, 9),
  415. iiToBig(8, 7)}
  416. // basic operations of finite field order 6
  417. res := fq6.Add(a, b)
  418. res = fq6.Sub(a, b)
  419. res = fq6.Mul(a, b)
  420. divRes := fq6.Div(mulRes, b)
  421. // new finite field of order 12
  422. q, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10) // i
  423. if !ok {
  424. fmt.Println("error parsing string to big integer")
  425. }
  426. fq1 := NewFq(q)
  427. nonResidueFq2, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208582", 10) // i
  428. assert.True(t, ok)
  429. nonResidueFq6 := iiToBig(9, 1)
  430. fq2 := Fq2{fq1, nonResidueFq2}
  431. fq6 := Fq6{fq2, nonResidueFq6}
  432. fq12 := Fq12{fq6, fq2, nonResidueFq6}
  433. ```
  434. - G1 operations
  435. ```go
  436. bn128, err := NewBn128()
  437. assert.Nil(t, err)
  438. r1 := big.NewInt(int64(33))
  439. r2 := big.NewInt(int64(44))
  440. gr1 := bn128.G1.MulScalar(bn128.G1.G, bn128.Fq1.Copy(r1))
  441. gr2 := bn128.G1.MulScalar(bn128.G1.G, bn128.Fq1.Copy(r2))
  442. grsum1 := bn128.G1.Add(gr1, gr2)
  443. r1r2 := bn128.Fq1.Add(r1, r2)
  444. grsum2 := bn128.G1.MulScalar(bn128.G1.G, r1r2)
  445. a := bn128.G1.Affine(grsum1)
  446. b := bn128.G1.Affine(grsum2)
  447. assert.Equal(t, a, b)
  448. assert.Equal(t, "0x2f978c0ab89ebaa576866706b14787f360c4d6c3869efe5a72f7c3651a72ff00", utils.BytesToHex(a[0].Bytes()))
  449. assert.Equal(t, "0x12e4ba7f0edca8b4fa668fe153aebd908d322dc26ad964d4cd314795844b62b2", utils.BytesToHex(a[1].Bytes()))
  450. ```
  451. - G2 operations
  452. ```go
  453. bn128, err := NewBn128()
  454. assert.Nil(t, err)
  455. r1 := big.NewInt(int64(33))
  456. r2 := big.NewInt(int64(44))
  457. gr1 := bn128.G2.MulScalar(bn128.G2.G, bn128.Fq1.Copy(r1))
  458. gr2 := bn128.G2.MulScalar(bn128.G2.G, bn128.Fq1.Copy(r2))
  459. grsum1 := bn128.G2.Add(gr1, gr2)
  460. r1r2 := bn128.Fq1.Add(r1, r2)
  461. grsum2 := bn128.G2.MulScalar(bn128.G2.G, r1r2)
  462. a := bn128.G2.Affine(grsum1)
  463. b := bn128.G2.Affine(grsum2)
  464. assert.Equal(t, a, b)
  465. ```
  466. ---
  467. To run all tests:
  468. ```
  469. go test ./... -v
  470. ```