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.

463 lines
11 KiB

4 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
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) [![Build Status](https://travis-ci.org/arnaucube/cryptofun.svg?branch=master)](https://travis-ci.org/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 pairing](#bn128)
  12. - [BLS signature](#bls)
  13. ---
  14. ## RSA cryptosystem & Blind signature & Homomorphic Multiplication
  15. - https://en.wikipedia.org/wiki/RSA_(cryptosystem)#
  16. - https://en.wikipedia.org/wiki/Blind_signature
  17. - https://en.wikipedia.org/wiki/Homomorphic_encryption
  18. - [x] GenerateKeyPair
  19. - [x] Encrypt
  20. - [x] Decrypt
  21. - [x] Blind
  22. - [x] Blind Signature
  23. - [x] Unblind Signature
  24. - [x] Verify Signature
  25. - [x] Homomorphic Multiplication
  26. #### Usage
  27. - Key generation, Encryption, Decryption
  28. ```go
  29. // generate key pair
  30. key, err := GenerateKeyPair()
  31. if err!=nil {
  32. fmt.Println(err)
  33. }
  34. mBytes := []byte("Hi")
  35. m := new(big.Int).SetBytes(mBytes)
  36. // encrypt message
  37. c := Encrypt(m, key.PubK)
  38. // decrypt ciphertext
  39. d := Decrypt(c, key.PrivK)
  40. if m == d {
  41. fmt.Println("correctly decrypted")
  42. }
  43. ```
  44. - Blind signatures
  45. ```go
  46. // key generation [Alice]
  47. key, err := GenerateKeyPair()
  48. if err!=nil {
  49. fmt.Println(err)
  50. }
  51. // create new message [Alice]
  52. mBytes := []byte("Hi")
  53. m := new(big.Int).SetBytes(mBytes)
  54. // define r value [Alice]
  55. rVal := big.NewInt(int64(101))
  56. // blind message [Alice]
  57. mBlinded := Blind(m, rVal, key.PubK)
  58. // Blind Sign the blinded message [Bob]
  59. sigma := BlindSign(mBlinded, key.PrivK)
  60. // unblind the blinded signed message, and get the signature of the message [Alice]
  61. mSigned := Unblind(sigma, rVal, key.PubK)
  62. // verify the signature [Alice/Bob/Trudy]
  63. verified := Verify(m, mSigned, key.PubK)
  64. if !verified {
  65. fmt.Println("signature could not be verified")
  66. }
  67. ```
  68. - Homomorphic Multiplication
  69. ```go
  70. // key generation [Alice]
  71. key, err := GenerateKeyPair()
  72. if err!=nil {
  73. fmt.Println(err)
  74. }
  75. // define values [Alice]
  76. n1 := big.NewInt(int64(11))
  77. n2 := big.NewInt(int64(15))
  78. // encrypt the values [Alice]
  79. c1 := Encrypt(n1, key.PubK)
  80. c2 := Encrypt(n2, key.PubK)
  81. // compute homomorphic multiplication with the encrypted values [Bob]
  82. c3c4 := HomomorphicMul(c1, c2, key.PubK)
  83. // decrypt the result [Alice]
  84. d := Decrypt(c3c4, key.PrivK)
  85. // check that the result is the expected
  86. if !bytes.Equal(new(big.Int).Mul(n1, n2).Bytes(), d.Bytes()) {
  87. fmt.Println("decrypted result not equal to expected result")
  88. }
  89. ```
  90. ## Paillier cryptosystem & Homomorphic Addition
  91. - https://en.wikipedia.org/wiki/Paillier_cryptosystem
  92. - https://en.wikipedia.org/wiki/Homomorphic_encryption
  93. - [x] GenerateKeyPair
  94. - [x] Encrypt
  95. - [x] Decrypt
  96. - [x] Homomorphic Addition
  97. #### Usage
  98. - Encrypt, Decrypt
  99. ```go
  100. // key generation
  101. key, err := GenerateKeyPair()
  102. if err!=nil {
  103. fmt.Println(err)
  104. }
  105. mBytes := []byte("Hi")
  106. m := new(big.Int).SetBytes(mBytes)
  107. // encryption
  108. c := Encrypt(m, key.PubK)
  109. // decryption
  110. d := Decrypt(c, key.PubK, key.PrivK)
  111. if m == d {
  112. fmt.Println("ciphertext decrypted correctly")
  113. }
  114. ```
  115. - Homomorphic Addition
  116. ```go
  117. // key generation [Alice]
  118. key, err := GenerateKeyPair()
  119. if err!=nil {
  120. fmt.Println(err)
  121. }
  122. // define values [Alice]
  123. n1 := big.NewInt(int64(110))
  124. n2 := big.NewInt(int64(150))
  125. // encrypt values [Alice]
  126. c1 := Encrypt(n1, key.PubK)
  127. c2 := Encrypt(n2, key.PubK)
  128. // compute homomorphic addition [Bob]
  129. c3c4 := HomomorphicAddition(c1, c2, key.PubK)
  130. // decrypt the result [Alice]
  131. d := Decrypt(c3c4, key.PubK, key.PrivK)
  132. if !bytes.Equal(new(big.Int).Add(n1, n2).Bytes(), d.Bytes()) {
  133. fmt.Println("decrypted result not equal to expected result")
  134. }
  135. ```
  136. ## Shamir Secret Sharing
  137. - https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing
  138. - [x] create secret sharing from number of secrets needed, number of shares, random point p, secret to share
  139. - [x] Lagrange Interpolation to restore the secret from the shares
  140. #### Usage
  141. ```go
  142. // define secret to share
  143. k := 123456789
  144. // define random prime
  145. p, err := rand.Prime(rand.Reader, bits/2)
  146. if err!=nil {
  147. fmt.Println(err)
  148. }
  149. // define how many shares want to generate
  150. nShares := big.NewInt(int64(6))
  151. // define how many shares are needed to recover the secret
  152. nNeededShares := big.NewInt(int64(3))
  153. // create the shares
  154. shares, err := Create(
  155. nNeededShares,
  156. nShares,
  157. p,
  158. big.NewInt(int64(k)))
  159. assert.Nil(t, err)
  160. if err!=nil {
  161. fmt.Println(err)
  162. }
  163. // select shares to use
  164. var sharesToUse [][]*big.Int
  165. sharesToUse = append(sharesToUse, shares[2])
  166. sharesToUse = append(sharesToUse, shares[1])
  167. sharesToUse = append(sharesToUse, shares[0])
  168. // recover the secret using Lagrange Interpolation
  169. secr := LagrangeInterpolation(sharesToUse, p)
  170. // check that the restored secret matches the original secret
  171. if !bytes.Equal(k.Bytes(), secr.Bytes()) {
  172. fmt.Println("reconstructed secret not correspond to original secret")
  173. }
  174. ```
  175. ## Diffie-Hellman
  176. - https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
  177. - [x] key exchange
  178. ## ECC
  179. - https://en.wikipedia.org/wiki/Elliptic-curve_cryptography
  180. - [x] define elliptic curve
  181. - [x] get point at X
  182. - [x] get order of a Point on the elliptic curve
  183. - [x] Add two points on the elliptic curve
  184. - [x] Multiply a point n times on the elliptic curve
  185. #### Usage
  186. - ECC basic operations
  187. ```go
  188. // define new ec
  189. ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
  190. // define two points over the curve
  191. p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(7))}
  192. p2 := Point{big.NewInt(int64(2)), big.NewInt(int64(2))}
  193. // add the two points
  194. q, err := ec.Add(p1, p2)
  195. if err!=nil {
  196. fmt.Println(err)
  197. }
  198. // multiply the two points
  199. q, err := ec.Mul(p, big.NewInt(int64(1)))
  200. if err!=nil {
  201. fmt.Println(err)
  202. }
  203. // get order of a generator point over the elliptic curve
  204. g := Point{big.NewInt(int64(7)), big.NewInt(int64(8))}
  205. order, err := ec.Order(g)
  206. if err!=nil {
  207. fmt.Println(err)
  208. }
  209. ```
  210. ## ECC ElGamal
  211. - https://en.wikipedia.org/wiki/ElGamal_encryption
  212. - [x] ECC ElGamal key generation
  213. - [x] ECC ElGamal Encrypton
  214. - [x] ECC ElGamal Decryption
  215. #### Usage
  216. - NewEG, Encryption, Decryption
  217. ```go
  218. // define new elliptic curve
  219. ec := ecc.NewEC(big.NewInt(int64(1)), big.NewInt(int64(18)), big.NewInt(int64(19)))
  220. // define new point
  221. g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
  222. // define new ElGamal crypto system with the elliptic curve and the point
  223. eg, err := NewEG(ec, g)
  224. if err!=nil {
  225. fmt.Println(err)
  226. }
  227. // define privK&pubK over the elliptic curve
  228. privK := big.NewInt(int64(5))
  229. pubK, err := eg.PubK(privK)
  230. if err!=nil {
  231. fmt.Println(err)
  232. }
  233. // define point to encrypt
  234. m := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(12))}
  235. // encrypt
  236. c, err := eg.Encrypt(m, pubK, big.NewInt(int64(15)))
  237. if err!=nil {
  238. fmt.Println(err)
  239. }
  240. // decrypt
  241. d, err := eg.Decrypt(c, privK)
  242. if err!=nil {
  243. fmt.Println(err)
  244. }
  245. // check that decryption is correct
  246. if !m.Equal(d) {
  247. fmt.Println("decrypted not equal to original")
  248. }
  249. ```
  250. ## ECC ECDSA
  251. - https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
  252. - [x] define ECDSA data structure
  253. - [x] ECDSA Sign
  254. - [x] ECDSA Verify signature
  255. #### Usage
  256. ```go
  257. // define new elliptic curve
  258. ec := ecc.NewEC(big.NewInt(int64(1)), big.NewInt(int64(18)), big.NewInt(int64(19)))
  259. // define new point
  260. g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
  261. // define new ECDSA system
  262. dsa, err := NewDSA(ec, g)
  263. if err!=nil {
  264. fmt.Println(err)
  265. }
  266. // define privK&pubK over the elliptic curve
  267. privK := big.NewInt(int64(5))
  268. pubK, err := dsa.PubK(privK)
  269. if err!=nil {
  270. fmt.Println(err)
  271. }
  272. // hash value to sign
  273. hashval := big.NewInt(int64(40))
  274. // define r
  275. r := big.NewInt(int64(11))
  276. // sign hashed value
  277. sig, err := dsa.Sign(hashval, privK, r)
  278. if err!=nil {
  279. fmt.Println(err)
  280. }
  281. // verify signature
  282. verified, err := dsa.Verify(hashval, sig, pubK)
  283. if err!=nil {
  284. fmt.Println(err)
  285. }
  286. if verified {
  287. fmt.Println("signature correctly verified")
  288. }
  289. ```
  290. ## Schnorr signature
  291. - https://en.wikipedia.org/wiki/Schnorr_signature
  292. - [x] Hash[M || R] (where M is the msg bytes and R is a Point on the ECC, using sha256 hash function)
  293. - [x] Generate Schnorr scheme
  294. - [x] Sign
  295. - [x] Verify signature
  296. #### Usage
  297. ```go
  298. // define new elliptic curve
  299. ec := ecc.NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
  300. // define new point
  301. g := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(27))} // Generator
  302. // define new random r
  303. r := big.NewInt(int64(23)) // random r
  304. // define new Schnorr crypto system using the values
  305. schnorr, sk, err := Gen(ec, g, r)
  306. if err!=nil {
  307. fmt.println(err)
  308. }
  309. // define message to sign
  310. m := []byte("hola")
  311. // 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
  312. h := Hash([]byte("hola"), c)
  313. if h.String() != "34719153732582497359642109898768696927847420320548121616059449972754491425079") {
  314. fmt.Println("not correctly hashed")
  315. }
  316. s, rPoint, err := schnorr.Sign(sk, m)
  317. if err!=nil {
  318. fmt.println(err)
  319. }
  320. // verify Schnorr signature
  321. verified, err := Verify(schnorr.EC, sk.PubK, m, s, rPoint)
  322. if err!=nil {
  323. fmt.println(err)
  324. }
  325. if verified {
  326. fmt.Println("Schnorr signature correctly verified")
  327. }
  328. ```
  329. ## Bn128
  330. Implementation of the bn128 pairing.
  331. Code moved to https://github.com/arnaucube/go-snark/tree/master/bn128
  332. ## BLS
  333. Boneh–Lynn–Shacham (BLS) signature scheme implemented in Go.
  334. https://en.wikipedia.org/wiki/Boneh%E2%80%93Lynn%E2%80%93Shacham
  335. This package uses the BN128 Go implementation from https://github.com/arnaucube/go-snark/tree/master/bn128
  336. ### Usage
  337. ```go
  338. bls, err := NewKeys()
  339. assert.Nil(t, err)
  340. fmt.Println("privK:", bls.PrivK)
  341. fmt.Println("pubK:", bls.PubK)
  342. m := []byte("test")
  343. sig := bls.Sign(m)
  344. fmt.Println("signature:", sig)
  345. verified := bls.Verify(m, sig, bls.PubK)
  346. assert.True(t, verified)
  347. /* out:
  348. privK: 28151522174243194157727175362620544050084772361374505986857263387912025505082855947281432752362814690196305655335201716186584298643231993241609823412370437094839017595372164876997343464950463323765646363122343203470911131219733598647659483557447955173651057370197665461325593653581904430885385707255151472097067657072671643359241937143381958053903725229458882818033464163487351806079175441316235756460455300637131488613568714712448336232283394011955460567718918055245116200622473324300828876609569556897836255866438665750954410544846238847540023603735360532628141508114304504053826700874403280496870140784630677100277
  349. pubK: [528167154220154970470523315181365784447502116458960328551053767278433374201 18282159022449399855128689249640771309991127595389457870089153259100566421596 19728585501269572907574045312283749798205079570296187960832716959652451330253]
  350. signature: [[12832528436266902887734423636380781315321578271441494003771296275495461508593 6964131770814642748778827029569297554111206304527781019989920684169107205085] [6508357389516441729339280841134358160957092583050390612877406497974519092306 12073245715182483402311045895787625736998570529454024932833669602347318770866] [13520730275909614846121720877644124261162513989808465368770765804305866618385 19571107788574492009101590535904131414163790958090376021518899789800327786039]]
  351. verified: true
  352. */
  353. ```
  354. ---
  355. To run all tests:
  356. ```
  357. go test ./... -v
  358. ```