@ -1 +1,2 @@ |
|||
keys.json |
|||
keys |
@ -0,0 +1,97 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"bytes" |
|||
"crypto" |
|||
"crypto/rand" |
|||
"crypto/rsa" |
|||
"encoding/json" |
|||
"fmt" |
|||
"net/http" |
|||
"time" |
|||
|
|||
"github.com/cryptoballot/fdh" |
|||
"github.com/cryptoballot/rsablind" |
|||
) |
|||
|
|||
func IDs() []Key { |
|||
//read the keys stored in /keys directory
|
|||
keys := readKeys() |
|||
return keys |
|||
} |
|||
func NewID() []Key { |
|||
//generate RSA keys pair
|
|||
reader := rand.Reader |
|||
k, err := rsa.GenerateKey(reader, keysize) |
|||
check(err) |
|||
|
|||
id := hash(time.Now().String()) |
|||
savePEMKey(keysDir+"/"+id+"private.pem", k) |
|||
savePublicPEMKey(keysDir+"/"+id+"public.pem", k.PublicKey) |
|||
|
|||
var key Key |
|||
key.ID = id |
|||
key.PrivK = id + "private.pem" |
|||
key.PubK = id + "public.pem" |
|||
|
|||
key.Date = time.Now() |
|||
fmt.Println(key) |
|||
|
|||
keys := readKeys() |
|||
keys = append(keys, key) |
|||
saveKeys(keys) |
|||
return keys |
|||
} |
|||
|
|||
type AskBlindSign struct { |
|||
M []byte `json:"m"` |
|||
} |
|||
type SignResponse struct { |
|||
Sig []byte `json:"sig"` |
|||
PubK rsa.PublicKey `json:"pubK"` |
|||
} |
|||
|
|||
func BlindAndSendToSign(keyID string) []byte { |
|||
//get the key
|
|||
key := getKeyByKeyID(keyID) |
|||
//privK := openPEMKey(key.PrivK)
|
|||
pubK := openPublicPEMKey(key.PubK) |
|||
|
|||
//TODO pubK to string
|
|||
m := []byte("pubK") //convert pubK to array of bytes
|
|||
//blind the hashed message
|
|||
// We do a SHA256 full-domain-hash expanded to 1536 bits (3/4 the key size)
|
|||
hashed := fdh.Sum(crypto.SHA256, hashize, m) |
|||
blinded, unblinder, err := rsablind.Blind(&pubK, hashed) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
var askBlindSign AskBlindSign |
|||
askBlindSign.M = blinded |
|||
//send blinded to serverIDsigner
|
|||
body := new(bytes.Buffer) |
|||
json.NewEncoder(body).Encode(askBlindSign) |
|||
res, err := http.Post(config.Server+"blindsign", "application/json", body) |
|||
check(err) |
|||
var signResponse SignResponse |
|||
decoder := json.NewDecoder(res.Body) |
|||
err = decoder.Decode(&signResponse) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
defer res.Body.Close() |
|||
|
|||
sig := signResponse.Sig |
|||
serverPubK := signResponse.PubK |
|||
|
|||
//unblind the signedblind
|
|||
unblindedSig := rsablind.Unblind(&serverPubK, sig, unblinder) |
|||
fmt.Println(unblindedSig) |
|||
|
|||
return unblindedSig |
|||
} |
|||
|
|||
func Verify(packPubK string) { |
|||
|
|||
return |
|||
} |
@ -1,5 +1,4 @@ |
|||
{ |
|||
"port": "4100", |
|||
"keysDirectory": "keys", |
|||
"server": "http://127.0.0.1:3130/" |
|||
} |
@ -0,0 +1,12 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"crypto/sha256" |
|||
"encoding/base64" |
|||
) |
|||
|
|||
func hash(s string) string { |
|||
h := sha256.New() |
|||
h.Write([]byte(s)) |
|||
return base64.URLEncoding.EncodeToString(h.Sum(nil)) |
|||
} |
@ -1,54 +0,0 @@ |
|||
package ownrsa |
|||
|
|||
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) |
|||
} |
@ -1,229 +0,0 @@ |
|||
package ownrsa |
|||
|
|||
import ( |
|||
"errors" |
|||
"fmt" |
|||
"math/big" |
|||
"math/rand" |
|||
"strconv" |
|||
"strings" |
|||
"time" |
|||
) |
|||
|
|||
type RSAPublicKey struct { |
|||
E *big.Int `json:"e"` |
|||
N *big.Int `json:"n"` |
|||
} |
|||
type RSAPublicKeyString struct { |
|||
E string `json:"e"` |
|||
N string `json:"n"` |
|||
} |
|||
type RSAPrivateKey struct { |
|||
D *big.Int `json:"d"` |
|||
N *big.Int `json:"n"` |
|||
} |
|||
|
|||
type RSA struct { |
|||
PubK RSAPublicKey |
|||
PrivK RSAPrivateKey |
|||
} |
|||
|
|||
type PackRSA struct { |
|||
PubK string `json:"pubK"` |
|||
PrivK string `json:"privK"` |
|||
Date time.Time `json:"date"` |
|||
PubKSigned string `json:"pubKSigned"` |
|||
Verified bool `json:"verified"` |
|||
} |
|||
|
|||
const maxPrime = 500 |
|||
const minPrime = 100 |
|||
|
|||
func GenerateKeyPair() RSA { |
|||
|
|||
rand.Seed(time.Now().Unix()) |
|||
p := randPrime(minPrime, maxPrime) |
|||
q := randPrime(minPrime, maxPrime) |
|||
fmt.Print("p:") |
|||
fmt.Println(p) |
|||
fmt.Print("q:") |
|||
fmt.Println(q) |
|||
|
|||
n := p * q |
|||
phi := (p - 1) * (q - 1) |
|||
e := 65537 |
|||
var pubK RSAPublicKey |
|||
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 RSAPrivateKey |
|||
privK.D = d |
|||
privK.N = big.NewInt(int64(n)) |
|||
|
|||
var rsa RSA |
|||
rsa.PubK = pubK |
|||
rsa.PrivK = privK |
|||
return rsa |
|||
} |
|||
func Encrypt(m string, pubK RSAPublicKey) []int { |
|||
var c []int |
|||
mBytes := []byte(m) |
|||
for _, byte := range mBytes { |
|||
c = append(c, EncryptInt(int(byte), pubK)) |
|||
} |
|||
return c |
|||
} |
|||
func Decrypt(c []int, privK RSAPrivateKey) string { |
|||
var m string |
|||
var mBytes []byte |
|||
for _, indC := range c { |
|||
mBytes = append(mBytes, byte(DecryptInt(indC, privK))) |
|||
} |
|||
m = string(mBytes) |
|||
return m |
|||
} |
|||
|
|||
func EncryptBigInt(bigint *big.Int, pubK RSAPublicKey) *big.Int { |
|||
Me := new(big.Int).Exp(bigint, pubK.E, nil) |
|||
c := new(big.Int).Mod(Me, pubK.N) |
|||
return c |
|||
} |
|||
func DecryptBigInt(bigint *big.Int, privK RSAPrivateKey) *big.Int { |
|||
Cd := new(big.Int).Exp(bigint, privK.D, nil) |
|||
m := new(big.Int).Mod(Cd, privK.N) |
|||
return m |
|||
} |
|||
|
|||
func EncryptInt(char int, pubK RSAPublicKey) int { |
|||
charBig := big.NewInt(int64(char)) |
|||
Me := charBig.Exp(charBig, pubK.E, nil) |
|||
c := Me.Mod(Me, pubK.N) |
|||
return int(c.Int64()) |
|||
} |
|||
func DecryptInt(val int, privK RSAPrivateKey) int { |
|||
valBig := big.NewInt(int64(val)) |
|||
Cd := valBig.Exp(valBig, privK.D, nil) |
|||
m := Cd.Mod(Cd, privK.N) |
|||
return int(m.Int64()) |
|||
} |
|||
|
|||
func Blind(m []int, r int, pubK RSAPublicKey, privK RSAPrivateKey) []int { |
|||
var mBlinded []int |
|||
rBigInt := big.NewInt(int64(r)) |
|||
for i := 0; i < len(m); i++ { |
|||
mBigInt := big.NewInt(int64(m[i])) |
|||
rE := new(big.Int).Exp(rBigInt, pubK.E, nil) |
|||
mrE := new(big.Int).Mul(mBigInt, rE) |
|||
mrEmodN := new(big.Int).Mod(mrE, privK.N) |
|||
mBlinded = append(mBlinded, int(mrEmodN.Int64())) |
|||
} |
|||
return mBlinded |
|||
} |
|||
|
|||
func BlindSign(m []int, privK RSAPrivateKey) []int { |
|||
var r []int |
|||
for i := 0; i < len(m); i++ { |
|||
mBigInt := big.NewInt(int64(m[i])) |
|||
sigma := new(big.Int).Exp(mBigInt, privK.D, privK.N) |
|||
r = append(r, int(sigma.Int64())) |
|||
} |
|||
return r |
|||
} |
|||
func Unblind(blindsigned []int, r int, pubK RSAPublicKey) []int { |
|||
var mSigned []int |
|||
rBigInt := big.NewInt(int64(r)) |
|||
for i := 0; i < len(blindsigned); i++ { |
|||
bsBigInt := big.NewInt(int64(blindsigned[i])) |
|||
//r1 := new(big.Int).Exp(rBigInt, big.NewInt(int64(-1)), nil)
|
|||
r1 := new(big.Int).ModInverse(rBigInt, pubK.N) |
|||
bsr := new(big.Int).Mul(bsBigInt, r1) |
|||
sig := new(big.Int).Mod(bsr, pubK.N) |
|||
mSigned = append(mSigned, int(sig.Int64())) |
|||
} |
|||
return mSigned |
|||
} |
|||
func Verify(msg []int, mSigned []int, pubK RSAPublicKey) bool { |
|||
if len(msg) != len(mSigned) { |
|||
return false |
|||
} |
|||
var mSignedDecrypted []int |
|||
for _, ms := range mSigned { |
|||
msBig := big.NewInt(int64(ms)) |
|||
//decrypt the mSigned with pubK
|
|||
Cd := new(big.Int).Exp(msBig, pubK.E, nil) |
|||
m := new(big.Int).Mod(Cd, pubK.N) |
|||
mSignedDecrypted = append(mSignedDecrypted, int(m.Int64())) |
|||
} |
|||
fmt.Print("msg signed decrypted: ") |
|||
fmt.Println(mSignedDecrypted) |
|||
r := true |
|||
//check if the mSignedDecrypted == msg
|
|||
for i := 0; i < len(msg); i++ { |
|||
if msg[i] != mSignedDecrypted[i] { |
|||
r = false |
|||
} |
|||
} |
|||
return r |
|||
} |
|||
|
|||
func HomomorphicMultiplication(c1 int, c2 int, pubK RSAPublicKey) int { |
|||
c1BigInt := big.NewInt(int64(c1)) |
|||
c2BigInt := big.NewInt(int64(c2)) |
|||
c1c2 := new(big.Int).Mul(c1BigInt, c2BigInt) |
|||
n2 := new(big.Int).Mul(pubK.N, pubK.N) |
|||
d := new(big.Int).Mod(c1c2, n2) |
|||
r := int(d.Int64()) |
|||
return r |
|||
} |
|||
|
|||
func PubKStringToBigInt(kS RSAPublicKeyString) (RSAPublicKey, error) { |
|||
var k RSAPublicKey |
|||
var ok bool |
|||
k.E, ok = new(big.Int).SetString(kS.E, 10) |
|||
if !ok { |
|||
return k, errors.New("error parsing big int E") |
|||
} |
|||
k.N, ok = new(big.Int).SetString(kS.N, 10) |
|||
if !ok { |
|||
return k, errors.New("error parsing big int N") |
|||
} |
|||
return k, nil |
|||
} |
|||
|
|||
func PackKey(k RSA) PackRSA { |
|||
var p PackRSA |
|||
p.PubK = k.PubK.E.String() + "," + k.PubK.N.String() |
|||
p.PrivK = k.PrivK.D.String() + "," + k.PrivK.N.String() |
|||
return p |
|||
} |
|||
|
|||
func UnpackKey(p PackRSA) RSA { |
|||
var k RSA |
|||
var ok bool |
|||
k.PubK.E, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[0], 10) |
|||
k.PubK.N, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[1], 10) |
|||
k.PrivK.D, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[0], 10) |
|||
k.PrivK.N, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[1], 10) |
|||
if !ok { |
|||
fmt.Println("error on Unpacking Keys") |
|||
} |
|||
return k |
|||
} |
|||
|
|||
func ArrayIntToString(a []int, delim string) string { |
|||
return strings.Trim(strings.Replace(fmt.Sprint(a), " ", delim, -1), "[]") |
|||
} |
|||
func StringToArrayInt(s string, delim string) []int { |
|||
var a []int |
|||
arrayString := strings.Split(s, delim) |
|||
for _, s := range arrayString { |
|||
i, err := strconv.Atoi(s) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
a = append(a, i) |
|||
} |
|||
return a |
|||
} |
@ -0,0 +1,104 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"crypto/rsa" |
|||
"crypto/x509" |
|||
"encoding/asn1" |
|||
"encoding/json" |
|||
"encoding/pem" |
|||
"io/ioutil" |
|||
"os" |
|||
"time" |
|||
) |
|||
|
|||
type Key struct { |
|||
ID string `json:"id"` |
|||
PrivK string `json:"privK"` //path of the PrivK file
|
|||
PubK string `json:"pubK"` //path of the PubK file
|
|||
Date time.Time `json:"date"` |
|||
Verified bool `json:"verified"` |
|||
Signed string `json:"signed"` |
|||
} |
|||
|
|||
func savePEMKey(fileName string, key *rsa.PrivateKey) { |
|||
outFile, err := os.Create(fileName) |
|||
check(err) |
|||
defer outFile.Close() |
|||
|
|||
var privateKey = &pem.Block{ |
|||
Type: "PRIVATE KEY", |
|||
Bytes: x509.MarshalPKCS1PrivateKey(key), |
|||
} |
|||
|
|||
err = pem.Encode(outFile, privateKey) |
|||
check(err) |
|||
} |
|||
func savePublicPEMKey(fileName string, pubkey rsa.PublicKey) { |
|||
asn1Bytes, err := asn1.Marshal(pubkey) |
|||
check(err) |
|||
|
|||
var pemkey = &pem.Block{ |
|||
Type: "PUBLIC KEY", |
|||
Bytes: asn1Bytes, |
|||
} |
|||
|
|||
pemfile, err := os.Create(fileName) |
|||
check(err) |
|||
defer pemfile.Close() |
|||
|
|||
err = pem.Encode(pemfile, pemkey) |
|||
check(err) |
|||
} |
|||
func openPEMKey(path string) (key rsa.PrivateKey) { |
|||
return |
|||
} |
|||
func openPublicPEMKey(path string) (key rsa.PublicKey) { |
|||
return |
|||
} |
|||
func readKeys() []Key { |
|||
path := keysDir + "/keys.json" |
|||
var keys []Key |
|||
|
|||
file, err := ioutil.ReadFile(path) |
|||
check(err) |
|||
content := string(file) |
|||
json.Unmarshal([]byte(content), &keys) |
|||
|
|||
return keys |
|||
} |
|||
|
|||
func saveKeys(keys []Key) { |
|||
jsonKeys, err := json.Marshal(keys) |
|||
check(err) |
|||
err = ioutil.WriteFile(keysDir+"/keys.json", jsonKeys, 0644) |
|||
check(err) |
|||
} |
|||
func getKeyByKeyID(keyID string) (k Key) { |
|||
keys := readKeys() |
|||
for _, key := range keys { |
|||
if key.ID == keyID { |
|||
k = key |
|||
} |
|||
} |
|||
return k |
|||
} |
|||
|
|||
/* |
|||
func getServerPubK(url string) ownrsa.RSAPublicKey { |
|||
r, err := http.Get(url + "/") |
|||
check(err) |
|||
fmt.Println(r) |
|||
|
|||
decoder := json.NewDecoder(r.Body) |
|||
//var sigmaString string
|
|||
var pubK ownrsa.RSAPublicKey |
|||
err = decoder.Decode(&pubK) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
defer r.Body.Close() |
|||
color.Blue("received server pubK:") |
|||
fmt.Println(pubK) |
|||
return pubK |
|||
} |
|||
*/ |
@ -0,0 +1,27 @@ |
|||
-----BEGIN PRIVATE KEY----- |
|||
MIIEpQIBAAKCAQEA061q3ahXEG9rHf/uekmIk4fSvtG8p7OwkjP3PlafFjxeA4BS |
|||
8dkjPUEboXMftQCFrzWc5nLyQR4Ig5xMzjaEbQv/JBdpP/E1nl+fC6ca45Rov0OE |
|||
7OQrDyEPb1qNJ3uQmh+N9ZvTLNndT3bBxtBfmIRyMq+78mMumzNvFbx6zfNpwv9T |
|||
HDgBnfZoAZ7gpIZeKn/yFasQmzFwpy9hfqZ21SCL7GmiU+nAz2TxtyFkUttMeIxD |
|||
gSSKLYxzt6mKdElNv0K97tBU1eRaXz4hpq/I0dtmcidrS/45MtXij6wO1agIvnH+ |
|||
pygSI5QF3rE+lVYaDuKJZ6QBvnNEF9/cu7j/ZQIDAQABAoIBAQDAP+apPnUkpi0B |
|||
aCqtwg9a/qb3TAItxdN+VdgeNAn05gr03x12LiIFRhbUQXzwpXLFOMoxuwAvCBnv |
|||
fot7VqRbbePiYajjvC1Yk7wdlz2iqG2iGK6ngGtjKEGefv1oeJ9Se4oxIb9gItcP |
|||
jupbqXDJUrFtO5JViKMRrlsbwL1AQkWafiBJyfaeO9f6fikrv9dWJCE/wDN6F4XB |
|||
cVZj30GzBVpLfq6cuP1I7o1txNdRivPza4S6zufy53CfkFqsyjehFfvmlMCK+6/p |
|||
6EDd1pag3tfr/+1k1BGKwSgQyOBUYWS3FwW9J6wMm6bkUFmhAgJhl/cQmOPTas1/ |
|||
5OQxmaqZAoGBANthrMTPuMefYypKxbb+AxURpe09W+AVxm3PjtaOWkGKYIKFZD/+ |
|||
q4t9Jgc6H8vj92XMC7fsE8W9hJa5btTvvHzhLp+5lxxpO9idh2E7whFf7JpVs4aZ |
|||
8WhITZKiOja5sMXe0u8/L2zLN8ANmHo4Yh87pKd+DvNYaANYTQxtxvLfAoGBAPcC |
|||
iiwQ4FtlBXba305NqOwwPg126+Jl1hZ1gECHAPpnB05cIq584dDPEW2Crqs3zYEG |
|||
JyvXmAdB+GqVgY2OpRJDCB05kIzevDFSiu4wE7WA2/tMHcP4hNGtnG/iOUyiHPMq |
|||
pdxWDCq7pyvZELl8CHsL1PZ1uVZKqVnn4VBbt7o7AoGBAMRZ4slwZaD9rkLvE5Ea |
|||
PmYAGrOAxJeGxcgJCn5MgMnCcWjAvR5t8NnzFDNJuaXCju5kt2RRfszwOBizNViO |
|||
jfRzk0hQUsiSA4d4TvAfDS6B3YGxDPJ/HEtK02tXmaTbhDVFnyOVOPw10tspD/zs |
|||
NB5iQpfKwtTYnpfH04Y5RuSfAoGAMVzfkgjZXUpl+iepYrOgY3sMm5I9d6QUUa6v |
|||
r7WLG3+FdUJyZ95rHliTSghIsczYE8XQBDH0ntavN1Wja0+ra2fb8kMzwQMuJskx |
|||
HIKdHbOfwqumcyhyGpkQX0edXdQz5uCJ/utvSQbxVJDvh7Hi2/w0VgCWxkjraR0u |
|||
6Ok7YUsCgYEAjiJng9gj3GGZ6noBZ+lcK2VU839yExkJzj68lBzviMeD0kuyVN7R |
|||
fNpUOtjgR1a2paJLyXFq2a2AyhakA6r87GGGAGW3o6TCEw3jTXcc2L3CX113Ee5N |
|||
DbXbE9rXB8OT0q/x1ugoel+nFQMW+wwAigMl50DcENczyStJNQoXP9I= |
|||
-----END PRIVATE KEY----- |
@ -0,0 +1,8 @@ |
|||
-----BEGIN PUBLIC KEY----- |
|||
MIIBCgKCAQEA061q3ahXEG9rHf/uekmIk4fSvtG8p7OwkjP3PlafFjxeA4BS8dkj |
|||
PUEboXMftQCFrzWc5nLyQR4Ig5xMzjaEbQv/JBdpP/E1nl+fC6ca45Rov0OE7OQr |
|||
DyEPb1qNJ3uQmh+N9ZvTLNndT3bBxtBfmIRyMq+78mMumzNvFbx6zfNpwv9THDgB |
|||
nfZoAZ7gpIZeKn/yFasQmzFwpy9hfqZ21SCL7GmiU+nAz2TxtyFkUttMeIxDgSSK |
|||
LYxzt6mKdElNv0K97tBU1eRaXz4hpq/I0dtmcidrS/45MtXij6wO1agIvnH+pygS |
|||
I5QF3rE+lVYaDuKJZ6QBvnNEF9/cu7j/ZQIDAQAB |
|||
-----END PUBLIC KEY----- |