Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/arnaucube/cryptofun
Crypto algorithms from scratch in Go. Learning purposes only. ECC, BN128 pairing, Paillier, RSA, Homomorphic computation, ElGamal, Schnorr, ECDSA, BLS, ...
https://github.com/arnaucube/cryptofun
Last synced: about 10 hours ago
JSON representation
Crypto algorithms from scratch in Go. Learning purposes only. ECC, BN128 pairing, Paillier, RSA, Homomorphic computation, ElGamal, Schnorr, ECDSA, BLS, ...
- Host: GitHub
- URL: https://github.com/arnaucube/cryptofun
- Owner: arnaucube
- License: gpl-3.0
- Created: 2018-07-21T10:38:14.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-07-22T18:00:10.000Z (over 2 years ago)
- Last Synced: 2024-08-01T22:46:22.409Z (3 months ago)
- Language: Go
- Homepage:
- Size: 72.3 KB
- Stars: 74
- Watchers: 5
- Forks: 18
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 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)
Crypto algorithms from scratch. Academic purposes only.
- [RSA cryptosystem & Blind signature & Homomorphic Multiplication](#rsa-cryptosystem--blind-signature--homomorphic-multiplication)
- [Paillier cryptosystem & Homomorphic Addition](#paillier-cryptosystem--homomorphic-addition)
- [Shamir Secret Sharing](#shamir-secret-sharing)
- [Diffie-Hellman](#diffie-hellman)
- [ECC](#ecc)
- [ECC ElGamal](#ecc-elgamal)
- [ECC ECDSA](#ecc-ecdsa)
- [Schnorr signature](#schnorr-signature)
- [Bn128 pairing](#bn128)
- [BLS signature](#bls)---
## RSA cryptosystem & Blind signature & Homomorphic Multiplication
- https://en.wikipedia.org/wiki/RSA_(cryptosystem)#
- https://en.wikipedia.org/wiki/Blind_signature
- https://en.wikipedia.org/wiki/Homomorphic_encryption- [x] GenerateKeyPair
- [x] Encrypt
- [x] Decrypt
- [x] Blind
- [x] Blind Signature
- [x] Unblind Signature
- [x] Verify Signature
- [x] Homomorphic Multiplication#### Usage
- Key generation, Encryption, Decryption
```go
// generate key pair
key, err := GenerateKeyPair()
if err!=nil {
fmt.Println(err)
}
mBytes := []byte("Hi")
m := new(big.Int).SetBytes(mBytes)// encrypt message
c := Encrypt(m, key.PubK)// decrypt ciphertext
d := Decrypt(c, key.PrivK)
if m == d {
fmt.Println("correctly decrypted")
}
```- Blind signatures
```go
// key generation [Alice]
key, err := GenerateKeyPair()
if err!=nil {
fmt.Println(err)
}// create new message [Alice]
mBytes := []byte("Hi")
m := new(big.Int).SetBytes(mBytes)// define r value [Alice]
rVal := big.NewInt(int64(101))// blind message [Alice]
mBlinded := Blind(m, rVal, key.PubK)// Blind Sign the blinded message [Bob]
sigma := BlindSign(mBlinded, key.PrivK)// unblind the blinded signed message, and get the signature of the message [Alice]
mSigned := Unblind(sigma, rVal, key.PubK)// verify the signature [Alice/Bob/Trudy]
verified := Verify(m, mSigned, key.PubK)
if !verified {
fmt.Println("signature could not be verified")
}
```- Homomorphic Multiplication
```go
// key generation [Alice]
key, err := GenerateKeyPair()
if err!=nil {
fmt.Println(err)
}// define values [Alice]
n1 := big.NewInt(int64(11))
n2 := big.NewInt(int64(15))// encrypt the values [Alice]
c1 := Encrypt(n1, key.PubK)
c2 := Encrypt(n2, key.PubK)// compute homomorphic multiplication with the encrypted values [Bob]
c3c4 := HomomorphicMul(c1, c2, key.PubK)// decrypt the result [Alice]
d := Decrypt(c3c4, key.PrivK)// check that the result is the expected
if !bytes.Equal(new(big.Int).Mul(n1, n2).Bytes(), d.Bytes()) {
fmt.Println("decrypted result not equal to expected result")
}
```## Paillier cryptosystem & Homomorphic Addition
- https://en.wikipedia.org/wiki/Paillier_cryptosystem
- https://en.wikipedia.org/wiki/Homomorphic_encryption- [x] GenerateKeyPair
- [x] Encrypt
- [x] Decrypt
- [x] Homomorphic Addition#### Usage
- Encrypt, Decrypt
```go
// key generation
key, err := GenerateKeyPair()
if err!=nil {
fmt.Println(err)
}mBytes := []byte("Hi")
m := new(big.Int).SetBytes(mBytes)// encryption
c := Encrypt(m, key.PubK)// decryption
d := Decrypt(c, key.PubK, key.PrivK)
if m == d {
fmt.Println("ciphertext decrypted correctly")
}
```- Homomorphic Addition
```go
// key generation [Alice]
key, err := GenerateKeyPair()
if err!=nil {
fmt.Println(err)
}// define values [Alice]
n1 := big.NewInt(int64(110))
n2 := big.NewInt(int64(150))// encrypt values [Alice]
c1 := Encrypt(n1, key.PubK)
c2 := Encrypt(n2, key.PubK)// compute homomorphic addition [Bob]
c3c4 := HomomorphicAddition(c1, c2, key.PubK)// decrypt the result [Alice]
d := Decrypt(c3c4, key.PubK, key.PrivK)
if !bytes.Equal(new(big.Int).Add(n1, n2).Bytes(), d.Bytes()) {
fmt.Println("decrypted result not equal to expected result")
}
```## Shamir Secret Sharing
- https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing- [x] create secret sharing from number of secrets needed, number of shares, random point p, secret to share
- [x] Lagrange Interpolation to restore the secret from the shares#### Usage
```go
// define secret to share
k := 123456789// define random prime
p, err := rand.Prime(rand.Reader, bits/2)
if err!=nil {
fmt.Println(err)
}// define how many shares want to generate
nShares := big.NewInt(int64(6))// define how many shares are needed to recover the secret
nNeededShares := big.NewInt(int64(3))// create the shares
shares, err := Create(
nNeededShares,
nShares,
p,
big.NewInt(int64(k)))
assert.Nil(t, err)
if err!=nil {
fmt.Println(err)
}// select shares to use
var sharesToUse [][]*big.Int
sharesToUse = append(sharesToUse, shares[2])
sharesToUse = append(sharesToUse, shares[1])
sharesToUse = append(sharesToUse, shares[0])// recover the secret using Lagrange Interpolation
secr := LagrangeInterpolation(sharesToUse, p)// check that the restored secret matches the original secret
if !bytes.Equal(k.Bytes(), secr.Bytes()) {
fmt.Println("reconstructed secret not correspond to original secret")
}
```## Diffie-Hellman
- https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange- [x] key exchange
## ECC
- https://en.wikipedia.org/wiki/Elliptic-curve_cryptography- [x] define elliptic curve
- [x] get point at X
- [x] get order of a Point on the elliptic curve
- [x] Add two points on the elliptic curve
- [x] Multiply a point n times on the elliptic curve#### Usage
- ECC basic operations
```go
// define new ec
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))// define two points over the curve
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(7))}
p2 := Point{big.NewInt(int64(2)), big.NewInt(int64(2))}// add the two points
q, err := ec.Add(p1, p2)
if err!=nil {
fmt.Println(err)
}// multiply the two points
q, err := ec.Mul(p, big.NewInt(int64(1)))
if err!=nil {
fmt.Println(err)
}// get order of a generator point over the elliptic curve
g := Point{big.NewInt(int64(7)), big.NewInt(int64(8))}
order, err := ec.Order(g)
if err!=nil {
fmt.Println(err)
}
```## ECC ElGamal
- https://en.wikipedia.org/wiki/ElGamal_encryption- [x] ECC ElGamal key generation
- [x] ECC ElGamal Encrypton
- [x] ECC ElGamal Decryption#### Usage
- NewEG, Encryption, Decryption
```go
// define new elliptic curve
ec := ecc.NewEC(big.NewInt(int64(1)), big.NewInt(int64(18)), big.NewInt(int64(19)))// define new point
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}// define new ElGamal crypto system with the elliptic curve and the point
eg, err := NewEG(ec, g)
if err!=nil {
fmt.Println(err)
}// define privK&pubK over the elliptic curve
privK := big.NewInt(int64(5))
pubK, err := eg.PubK(privK)
if err!=nil {
fmt.Println(err)
}// define point to encrypt
m := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(12))}// encrypt
c, err := eg.Encrypt(m, pubK, big.NewInt(int64(15)))
if err!=nil {
fmt.Println(err)
}// decrypt
d, err := eg.Decrypt(c, privK)
if err!=nil {
fmt.Println(err)
}// check that decryption is correct
if !m.Equal(d) {
fmt.Println("decrypted not equal to original")
}
```## ECC ECDSA
- https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm- [x] define ECDSA data structure
- [x] ECDSA Sign
- [x] ECDSA Verify signature#### Usage
```go
// define new elliptic curve
ec := ecc.NewEC(big.NewInt(int64(1)), big.NewInt(int64(18)), big.NewInt(int64(19)))
// define new point
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}// define new ECDSA system
dsa, err := NewDSA(ec, g)
if err!=nil {
fmt.Println(err)
}// define privK&pubK over the elliptic curve
privK := big.NewInt(int64(5))
pubK, err := dsa.PubK(privK)
if err!=nil {
fmt.Println(err)
}// hash value to sign
hashval := big.NewInt(int64(40))// define r
r := big.NewInt(int64(11))// sign hashed value
sig, err := dsa.Sign(hashval, privK, r)
if err!=nil {
fmt.Println(err)
}// verify signature
verified, err := dsa.Verify(hashval, sig, pubK)
if err!=nil {
fmt.Println(err)
}
if verified {
fmt.Println("signature correctly verified")
}
```## Schnorr signature
- https://en.wikipedia.org/wiki/Schnorr_signature- [x] Hash[M || R] (where M is the msg bytes and R is a Point on the ECC, using sha256 hash function)
- [x] Generate Schnorr scheme
- [x] Sign
- [x] Verify signature#### Usage
```go
// define new elliptic curve
ec := ecc.NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
// define new point
g := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(27))} // Generator
// define new random r
r := big.NewInt(int64(23)) // random r// define new Schnorr crypto system using the values
schnorr, sk, err := Gen(ec, g, r)
if err!=nil {
fmt.println(err)
}// define message to sign
m := []byte("hola")// 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
h := Hash([]byte("hola"), c)
if h.String() != "34719153732582497359642109898768696927847420320548121616059449972754491425079") {
fmt.Println("not correctly hashed")
}s, rPoint, err := schnorr.Sign(sk, m)
if err!=nil {
fmt.println(err)
}// verify Schnorr signature
verified, err := Verify(schnorr.EC, sk.PubK, m, s, rPoint)
if err!=nil {
fmt.println(err)
}
if verified {
fmt.Println("Schnorr signature correctly verified")
}
```## Bn128
Implementation of the bn128 pairing.
Code moved to https://github.com/arnaucube/go-snark/tree/master/bn128## BLS
Boneh–Lynn–Shacham (BLS) signature scheme implemented in Go.
https://en.wikipedia.org/wiki/Boneh%E2%80%93Lynn%E2%80%93ShachamThis package uses the BN128 Go implementation from https://github.com/arnaucube/go-snark/tree/master/bn128
### Usage
```go
bls, err := NewKeys()
assert.Nil(t, err)fmt.Println("privK:", bls.PrivK)
fmt.Println("pubK:", bls.PubK)m := []byte("test")
sig := bls.Sign(m)
fmt.Println("signature:", sig)verified := bls.Verify(m, sig, bls.PubK)
assert.True(t, verified)/* out:
privK: 28151522174243194157727175362620544050084772361374505986857263387912025505082855947281432752362814690196305655335201716186584298643231993241609823412370437094839017595372164876997343464950463323765646363122343203470911131219733598647659483557447955173651057370197665461325593653581904430885385707255151472097067657072671643359241937143381958053903725229458882818033464163487351806079175441316235756460455300637131488613568714712448336232283394011955460567718918055245116200622473324300828876609569556897836255866438665750954410544846238847540023603735360532628141508114304504053826700874403280496870140784630677100277
pubK: [528167154220154970470523315181365784447502116458960328551053767278433374201 18282159022449399855128689249640771309991127595389457870089153259100566421596 19728585501269572907574045312283749798205079570296187960832716959652451330253]
signature: [[12832528436266902887734423636380781315321578271441494003771296275495461508593 6964131770814642748778827029569297554111206304527781019989920684169107205085] [6508357389516441729339280841134358160957092583050390612877406497974519092306 12073245715182483402311045895787625736998570529454024932833669602347318770866] [13520730275909614846121720877644124261162513989808465368770765804305866618385 19571107788574492009101590535904131414163790958090376021518899789800327786039]]
verified: true
*/
```---
To run all tests:
```
go test ./... -v
```