arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/rsa/rsa.go
rsa/rsa.goRaw
  1package rsa
  2
  3import (
  4	"bytes"
  5	"crypto/rand"
  6	"math/big"
  7)
  8
  9const (
 10	bits = 512 // 2048
 11)
 12
 13var bigOne = big.NewInt(int64(1))
 14
 15// PublicKey stores the public key data
 16type PublicKey struct {
 17	E *big.Int `json:"e"`
 18	N *big.Int `json:"n"`
 19}
 20
 21// PrivateKey stores the private key data
 22type PrivateKey struct {
 23	D *big.Int `json:"d"`
 24	N *big.Int `json:"n"`
 25}
 26
 27// Key stores the public and private key data
 28type Key struct {
 29	PubK  PublicKey
 30	PrivK PrivateKey
 31}
 32
 33// GenerateKeyPair generates a random private and public key
 34func GenerateKeyPair() (key Key, err error) {
 35	p, err := rand.Prime(rand.Reader, bits/2)
 36	if err != nil {
 37		return key, err
 38	}
 39	q, err := rand.Prime(rand.Reader, bits/2)
 40	if err != nil {
 41		return key, err
 42	}
 43
 44	n := new(big.Int).Mul(p, q)
 45	p1 := new(big.Int).Sub(p, bigOne)
 46	q1 := new(big.Int).Sub(q, bigOne)
 47	phi := new(big.Int).Mul(p1, q1)
 48	e := 65537
 49	var pubK PublicKey
 50	pubK.E = big.NewInt(int64(e))
 51	pubK.N = n
 52
 53	d := new(big.Int).ModInverse(big.NewInt(int64(e)), phi)
 54
 55	var privK PrivateKey
 56	privK.D = d
 57	privK.N = n
 58
 59	key.PubK = pubK
 60	key.PrivK = privK
 61	return key, nil
 62}
 63
 64// Encrypt encrypts a message m with given PublicKey
 65func Encrypt(m *big.Int, pubK PublicKey) *big.Int {
 66	c := new(big.Int).Exp(m, pubK.E, pubK.N)
 67	return c
 68}
 69
 70// Decrypt deencrypts a ciphertext c with given PrivateKey
 71func Decrypt(c *big.Int, privK PrivateKey) *big.Int {
 72	m := new(big.Int).Exp(c, privK.D, privK.N)
 73	return m
 74}
 75
 76// Blind blinds a message
 77func Blind(m *big.Int, r *big.Int, pubK PublicKey) *big.Int {
 78	rE := new(big.Int).Exp(r, pubK.E, nil)
 79	mrE := new(big.Int).Mul(m, rE)
 80	mBlinded := new(big.Int).Mod(mrE, pubK.N)
 81	return mBlinded
 82}
 83
 84// BlindSign blind signs a message without knowing the content
 85func BlindSign(m *big.Int, privK PrivateKey) *big.Int {
 86	sigma := new(big.Int).Exp(m, privK.D, privK.N)
 87	return sigma
 88}
 89
 90// Unblind unblinds the Blinded Signature
 91func Unblind(sigma *big.Int, r *big.Int, pubK PublicKey) *big.Int {
 92	r1 := new(big.Int).ModInverse(r, pubK.N)
 93	bsr := new(big.Int).Mul(sigma, r1)
 94	sig := new(big.Int).Mod(bsr, pubK.N)
 95	return sig
 96}
 97
 98// Verify verifies the signature of a message given the PublicKey of the signer
 99func Verify(msg *big.Int, mSigned *big.Int, pubK PublicKey) bool {
100	//decrypt the mSigned with pubK
101	Cd := new(big.Int).Exp(mSigned, pubK.E, nil)
102	m := new(big.Int).Mod(Cd, pubK.N)
103	return bytes.Equal(msg.Bytes(), m.Bytes())
104}
105
106// HomomorphicMul calculates the multiplication of tow encrypted values given a PublicKey
107func HomomorphicMul(c1 *big.Int, c2 *big.Int, pubK PublicKey) *big.Int {
108	c1c2 := new(big.Int).Mul(c1, c2)
109	n2 := new(big.Int).Mul(pubK.N, pubK.N)
110	d := new(big.Int).Mod(c1c2, n2)
111	return d
112}