Browse Source

rsa encrypt & decrypt, blind signatures, homomorphic multiplication

master
arnaucode 5 years ago
parent
commit
5996bcbe25
4 changed files with 219 additions and 0 deletions
  1. +18
    -0
      README.md
  2. +49
    -0
      prime/prime.go
  3. +98
    -0
      rsa/rsa.go
  4. +54
    -0
      rsa/rsa_test.go

+ 18
- 0
README.md

@ -0,0 +1,18 @@
# cryptofun
Crypto algorithms from scratch. Academic purposes only.
## RSA
- [x] GenerateKeyPair
- [x] Encrypt
- [x] Decrypt
- [x] Blind
- [x] Blind Signature
- [x] Unblind Signature
- [x] Verify Signature
- [x] Homomorphic Multiplication
## Paillier
## ECC
## Shamir Secret Sharing

+ 49
- 0
prime/prime.go

@ -0,0 +1,49 @@
package prime
import "math/rand"
func RandInt(min int, max int) int {
r := rand.Intn(max-min) + min
return r
}
func RandPrime(min int, max int) int {
primes := SieveOfEratosthenes(max)
randN := rand.Intn(len(primes)-0) + 0
return primes[randN]
}
// return list of primes less than N
func SieveOfEratosthenes(N int) (primes []int) {
b := make([]bool, N)
for i := 2; i < N; i++ {
if b[i] == true {
continue
}
primes = append(primes, i)
for k := i * i; k < N; k += i {
b[k] = true
}
}
return
}
func Gcd(a, b int) int {
var bgcd func(a, b, res int) int
bgcd = func(a, b, res int) int {
switch {
case a == b:
return res * a
case a%2 == 0 && b%2 == 0:
return bgcd(a/2, b/2, 2*res)
case a%2 == 0:
return bgcd(a/2, b, res)
case b%2 == 0:
return bgcd(a, b/2, res)
case a > b:
return bgcd(a-b, b, res)
default:
return bgcd(a, b-a, res)
}
}
return bgcd(a, b, 1)
}

+ 98
- 0
rsa/rsa.go

@ -0,0 +1,98 @@
package rsa
import (
"bytes"
"math/big"
"math/rand"
"time"
prime "../prime"
)
const (
MaxPrime = 2000
MinPrime = 500
)
type PublicKey struct {
E *big.Int `json:"e"`
N *big.Int `json:"n"`
}
type PublicKeyString struct {
E string `json:"e"`
N string `json:"n"`
}
type PrivateKey struct {
D *big.Int `json:"d"`
N *big.Int `json:"n"`
}
type Key struct {
PubK PublicKey
PrivK PrivateKey
}
func GenerateKeyPair() (key Key) {
rand.Seed(time.Now().Unix())
p := prime.RandPrime(MinPrime, MaxPrime)
q := prime.RandPrime(MinPrime, MaxPrime)
n := p * q
phi := (p - 1) * (q - 1)
e := 65537
var pubK PublicKey
pubK.E = big.NewInt(int64(e))
pubK.N = big.NewInt(int64(n))
d := new(big.Int).ModInverse(big.NewInt(int64(e)), big.NewInt(int64(phi)))
var privK PrivateKey
privK.D = d
privK.N = big.NewInt(int64(n))
key.PubK = pubK
key.PrivK = privK
return key
}
func Encrypt(m *big.Int, pubK PublicKey) *big.Int {
Me := new(big.Int).Exp(m, pubK.E, nil)
c := new(big.Int).Mod(Me, pubK.N)
return c
}
func Decrypt(c *big.Int, privK PrivateKey) *big.Int {
Cd := new(big.Int).Exp(c, privK.D, nil)
m := new(big.Int).Mod(Cd, privK.N)
return m
}
func Blind(m *big.Int, r *big.Int, pubK PublicKey) *big.Int {
rE := new(big.Int).Exp(r, pubK.E, nil)
mrE := new(big.Int).Mul(m, rE)
mBlinded := new(big.Int).Mod(mrE, pubK.N)
return mBlinded
}
func BlindSign(m *big.Int, privK PrivateKey) *big.Int {
sigma := new(big.Int).Exp(m, privK.D, privK.N)
return sigma
}
func Unblind(sigma *big.Int, r *big.Int, pubK PublicKey) *big.Int {
r1 := new(big.Int).ModInverse(r, pubK.N)
bsr := new(big.Int).Mul(sigma, r1)
sig := new(big.Int).Mod(bsr, pubK.N)
return sig
}
func Verify(msg *big.Int, mSigned *big.Int, pubK PublicKey) bool {
//decrypt the mSigned with pubK
Cd := new(big.Int).Exp(mSigned, pubK.E, nil)
m := new(big.Int).Mod(Cd, pubK.N)
return bytes.Equal(msg.Bytes(), m.Bytes())
}
func HomomorphicMul(c1 *big.Int, c2 *big.Int, pubK PublicKey) *big.Int {
c1c2 := new(big.Int).Mul(c1, c2)
n2 := new(big.Int).Mul(pubK.N, pubK.N)
d := new(big.Int).Mod(c1c2, n2)
return d
}

+ 54
- 0
rsa/rsa_test.go

@ -0,0 +1,54 @@
package rsa
import (
"bytes"
"math/big"
"testing"
)
func TestEncryptDecrypt(t *testing.T) {
key := GenerateKeyPair()
mBytes := []byte("Hi")
m := new(big.Int).SetBytes(mBytes)
c := Encrypt(m, key.PubK)
d := Decrypt(c, key.PrivK)
if m == d {
t.Errorf("m not equal to decrypted")
}
}
func TestBlindSignature(t *testing.T) {
key := GenerateKeyPair()
mBytes := []byte("Hi")
m := new(big.Int).SetBytes(mBytes)
c := Encrypt(m, key.PubK)
d := Decrypt(c, key.PrivK)
if m == d {
t.Errorf("decrypted d not equal to original m")
}
rVal := big.NewInt(int64(101))
mBlinded := Blind(m, rVal, key.PubK)
sigma := BlindSign(mBlinded, key.PrivK)
mSigned := Unblind(sigma, rVal, key.PubK)
verified := Verify(m, mSigned, key.PubK)
if !verified {
t.Errorf("false, signature not verified")
}
}
func TestHomomorphiMultiplication(t *testing.T) {
key := GenerateKeyPair()
n1 := big.NewInt(int64(11))
n2 := big.NewInt(int64(15))
c1 := Encrypt(n1, key.PubK)
c2 := Encrypt(n2, key.PubK)
c3c4 := HomomorphicMul(c1, c2, key.PubK)
d := Decrypt(c3c4, key.PrivK)
if !bytes.Equal(new(big.Int).Mul(n1, n2).Bytes(), d.Bytes()) {
t.Errorf("decrypted result not equal to original result")
}
}

Loading…
Cancel
Save