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.

572 lines
13 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 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. **[not finished]**
  330. This is implemented followng the implementations and info from:
  331. - https://github.com/iden3/zksnark
  332. - https://github.com/zcash/zcash/tree/master/src/snark
  333. - https://github.com/ethereum/py_ecc/tree/master/py_ecc/bn128
  334. - `Multiplication and Squaring on Pairing-Friendly
  335. Fields`, Augusto Jun Devegili, Colm Ó hÉigeartaigh, Michael Scott, and Ricardo Dahab https://pdfs.semanticscholar.org/3e01/de88d7428076b2547b60072088507d881bf1.pdf
  336. - `Optimal Pairings`, Frederik Vercauteren https://www.cosic.esat.kuleuven.be/bcrypt/optimal.pdf
  337. - `Double-and-Add with Relative Jacobian
  338. Coordinates`, Björn Fay https://eprint.iacr.org/2014/1014.pdf
  339. - `Fast and Regular Algorithms for Scalar Multiplication
  340. over Elliptic Curves`, Matthieu Rivain https://eprint.iacr.org/2011/338.pdf
  341. - [x] Fq, Fq2, Fq6, Fq12 operations
  342. - [x] G1, G2 operations
  343. #### Usage
  344. First let's define three basic functions to convert integer compositions to big integer compositions:
  345. ```go
  346. func iToBig(a int) *big.Int {
  347. return big.NewInt(int64(a))
  348. }
  349. func iiToBig(a, b int) [2]*big.Int {
  350. return [2]*big.Int{iToBig(a), iToBig(b)}
  351. }
  352. func iiiToBig(a, b int) [2]*big.Int {
  353. return [2]*big.Int{iToBig(a), iToBig(b)}
  354. }
  355. ```
  356. - Finite Fields (1, 2, 6, 12) operations
  357. ```go
  358. // new finite field of order 1
  359. fq1 := NewFq(iToBig(7))
  360. // basic operations of finite field 1
  361. res := fq1.Add(iToBig(4), iToBig(4))
  362. res = fq1.Double(iToBig(5))
  363. res = fq1.Sub(iToBig(5), iToBig(7))
  364. res = fq1.Neg(iToBig(5))
  365. res = fq1.Mul(iToBig(5), iToBig(11))
  366. res = fq1.Inverse(iToBig(4))
  367. res = fq1.Square(iToBig(5))
  368. // new finite field of order 2
  369. nonResidueFq2str := "-1" // i / Beta
  370. nonResidueFq2, ok := new(big.Int).SetString(nonResidueFq2str, 10)
  371. fq2 := Fq2{fq1, nonResidueFq2}
  372. nonResidueFq6 := iiToBig(9, 1)
  373. // basic operations of finite field of order 2
  374. res := fq2.Add(iiToBig(4, 4), iiToBig(3, 4))
  375. res = fq2.Double(iiToBig(5, 3))
  376. res = fq2.Sub(iiToBig(5, 3), iiToBig(7, 2))
  377. res = fq2.Neg(iiToBig(4, 4))
  378. res = fq2.Mul(iiToBig(4, 4), iiToBig(3, 4))
  379. res = fq2.Inverse(iiToBig(4, 4))
  380. res = fq2.Div(iiToBig(4, 4), iiToBig(3, 4))
  381. res = fq2.Square(iiToBig(4, 4))
  382. // new finite field of order 6
  383. nonResidueFq6 := iiToBig(9, 1) // TODO
  384. fq6 := Fq6{fq2, nonResidueFq6}
  385. // define two new values of Finite Field 6, in order to be able to perform the operations
  386. a := [3][2]*big.Int{
  387. iiToBig(1, 2),
  388. iiToBig(3, 4),
  389. iiToBig(5, 6)}
  390. b := [3][2]*big.Int{
  391. iiToBig(12, 11),
  392. iiToBig(10, 9),
  393. iiToBig(8, 7)}
  394. // basic operations of finite field order 6
  395. res := fq6.Add(a, b)
  396. res = fq6.Sub(a, b)
  397. res = fq6.Mul(a, b)
  398. divRes := fq6.Div(mulRes, b)
  399. // new finite field of order 12
  400. q, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10) // i
  401. if !ok {
  402. fmt.Println("error parsing string to big integer")
  403. }
  404. fq1 := NewFq(q)
  405. nonResidueFq2, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208582", 10) // i
  406. assert.True(t, ok)
  407. nonResidueFq6 := iiToBig(9, 1)
  408. fq2 := Fq2{fq1, nonResidueFq2}
  409. fq6 := Fq6{fq2, nonResidueFq6}
  410. fq12 := Fq12{fq6, fq2, nonResidueFq6}
  411. ```
  412. - G1 operations
  413. ```go
  414. bn128, err := NewBn128()
  415. assert.Nil(t, err)
  416. r1 := big.NewInt(int64(33))
  417. r2 := big.NewInt(int64(44))
  418. gr1 := bn128.G1.MulScalar(bn128.G1.G, bn128.Fq1.Copy(r1))
  419. gr2 := bn128.G1.MulScalar(bn128.G1.G, bn128.Fq1.Copy(r2))
  420. grsum1 := bn128.G1.Add(gr1, gr2)
  421. r1r2 := bn128.Fq1.Add(r1, r2)
  422. grsum2 := bn128.G1.MulScalar(bn128.G1.G, r1r2)
  423. a := bn128.G1.Affine(grsum1)
  424. b := bn128.G1.Affine(grsum2)
  425. assert.Equal(t, a, b)
  426. assert.Equal(t, "0x2f978c0ab89ebaa576866706b14787f360c4d6c3869efe5a72f7c3651a72ff00", utils.BytesToHex(a[0].Bytes()))
  427. assert.Equal(t, "0x12e4ba7f0edca8b4fa668fe153aebd908d322dc26ad964d4cd314795844b62b2", utils.BytesToHex(a[1].Bytes()))
  428. ```
  429. - G2 operations
  430. ```go
  431. bn128, err := NewBn128()
  432. assert.Nil(t, err)
  433. r1 := big.NewInt(int64(33))
  434. r2 := big.NewInt(int64(44))
  435. gr1 := bn128.G2.MulScalar(bn128.G2.G, bn128.Fq1.Copy(r1))
  436. gr2 := bn128.G2.MulScalar(bn128.G2.G, bn128.Fq1.Copy(r2))
  437. grsum1 := bn128.G2.Add(gr1, gr2)
  438. r1r2 := bn128.Fq1.Add(r1, r2)
  439. grsum2 := bn128.G2.MulScalar(bn128.G2.G, r1r2)
  440. a := bn128.G2.Affine(grsum1)
  441. b := bn128.G2.Affine(grsum2)
  442. assert.Equal(t, a, b)
  443. ```
  444. ---
  445. To run all tests:
  446. ```
  447. go test ./... -v
  448. ```