Files
paillier/encoding.go
T
Piotr Dyraga d892a58e4b Cleared up Paillier scheme API
The code for generating private key is based on approach described in [KL 08], construction 11.32 which is compatible with the one described in [DJN 10], section 3.2 except that instead of generating Lamda private key compontent from LCM of `p` and `q` we use Euler's totient function as suggested in [KL 08]. I cleared up naming as well as removed G and Mu parameters from Paillier key. For the modification of Paillier scheme we use, where g = n + 1, N is the only one parameter needed for a public key. Also, Mu is needed only for Decrypting and can be computed there from Lambda and N so there is no need to keep it in the private key.

I added documentation to <Key, Enc, Dec> functions with an important note that `p` and `q` supplied to `CreatePrivateKey` must be either of equal length or `gcd(pq, (p-1)(q-1)) = 1` which is assured if both primes are of equal length. This requirement is mentioned both in [KL 08] and [DJN 10].

[KL 08]:  Jonathan Katz, Yehuda Lindell, (2008)
          Introduction to Modern Cryptography: Principles and Protocols,
          Chapman & Hall/CRC

[DJN 10]: Ivan Damgard, Mads Jurik, Jesper Buus Nielsen, (2010)
          A Generalization of Paillier’s Public-Key System
          with Applications to Electronic Voting
          Aarhus University, Dept. of Computer Science, BRICS
2018-05-24 18:41:10 +02:00

244 lines
6.2 KiB
Go

package paillier
// all the methods relative to the set/get json/bson should be stored
// in this file.
import (
"encoding/json"
"errors"
"fmt"
"math/big"
"gopkg.in/mgo.v2/bson"
)
func fromHex(hex string) (*big.Int, error) {
n, err := new(big.Int).SetString(hex, 16)
if !err {
msg := fmt.Sprintf("Cannot convert %s to int as hexadecimal", hex)
return nil, errors.New(msg)
}
return n, nil
}
func all(oks []bool) bool {
for _, ok := range oks {
if !ok {
return false
}
}
return true
}
type dbCypher struct {
C string
}
func (this *Cypher) GetBSON() (interface{}, error) {
return &dbCypher{fmt.Sprintf("%x", this.C)}, nil
}
func (cypher *Cypher) SetBSON(raw bson.Raw) error {
c := dbCypher{}
if err := raw.Unmarshal(&c); err != nil {
return err
}
var ok bool
cypher.C, ok = new(big.Int).SetString(c.C, 16)
if !ok {
return errors.New("big int not in hexadecimal format")
}
return nil
}
type dbThresholdKey struct {
TotalNumberOfDecryptionServers int
Threshold int
V string
Vi []string
N string
G string
}
func (this *dbThresholdKey) FromThresholdKey(key *ThresholdKey) {
this.TotalNumberOfDecryptionServers = key.TotalNumberOfDecryptionServers
this.Threshold = key.Threshold
this.V = fmt.Sprintf("%x", key.V)
this.N = fmt.Sprintf("%x", key.N)
this.G = fmt.Sprintf("%x", key.G)
this.Vi = make([]string, len(key.Vi))
for i, vi := range key.Vi {
this.Vi[i] = fmt.Sprintf("%x", vi)
}
}
func (this *dbThresholdKey) ToThresholdKey(key *ThresholdKey) error {
key.TotalNumberOfDecryptionServers = this.TotalNumberOfDecryptionServers
key.Threshold = this.Threshold
oks := make([]bool, 3)
key.V, oks[0] = new(big.Int).SetString(this.V, 16)
key.N, oks[1] = new(big.Int).SetString(this.N, 16)
key.G, oks[2] = new(big.Int).SetString(this.G, 16)
if !all(oks) {
return errors.New("not hexadecimal")
}
key.Vi = make([]*big.Int, len(this.Vi))
var ok bool
for i, vi := range this.Vi {
key.Vi[i], ok = new(big.Int).SetString(vi, 16)
if !ok {
return errors.New("not hexadecimal")
}
}
return nil
}
func (this *ThresholdKey) GetBSON() (interface{}, error) {
r := new(dbThresholdKey)
r.FromThresholdKey(this)
return r, nil
}
func (this *ThresholdKey) SetBSON(raw bson.Raw) error {
r := new(dbThresholdKey)
if err := raw.Unmarshal(r); err != nil {
return err
}
return r.ToThresholdKey(this)
}
type dbPrivateKey struct {
N string `bson:",omitempty"`
G string `bson:",omitempty"`
Lambda string `bson:",omitempty"`
Mu string `bson:",omitempty"`
}
func (this *PrivateKey) GetBSON() (interface{}, error) {
m := make(map[string]string)
if this.N != nil {
m["n"] = fmt.Sprintf("%x", this.N)
}
if this.Lambda != nil {
m["lambda"] = fmt.Sprintf("%x", this.Lambda)
}
return m, nil
}
func (this *PrivateKey) SetBSON(raw bson.Raw) error {
var err error = nil
c := new(dbPrivateKey)
raw.Unmarshal(c)
if c.N != "" {
this.N, err = fromHex(c.N)
if err != nil {
return err
}
}
if c.Lambda != "" {
this.Lambda, err = fromHex(c.Lambda)
if err != nil {
return err
}
}
return err
}
type dbPartialDecryptionZKP struct {
Z string `json:"z"`
E string `json:"e"`
C string `json:"c"`
V string `json:"v"`
G string `json:"g"`
N string `json:"n"`
Vi []string `json:"vi"`
Decryption string `json:"decryption"`
Id int `json:"id"`
TotalNumberOfDecryptionServers int `json:"total_number_of_decryption_servers"`
Threshold int `json:"threshold"`
}
func (this *dbPartialDecryptionZKP) FromPartialDecryptionZKP(pd *PartialDecryptionZKP) {
this.Id = pd.Id
this.TotalNumberOfDecryptionServers = pd.Key.TotalNumberOfDecryptionServers
this.Threshold = pd.Key.Threshold
this.Z = fmt.Sprintf("%x", pd.Z)
this.E = fmt.Sprintf("%x", pd.E)
this.G = fmt.Sprintf("%x", pd.Key.G)
this.N = fmt.Sprintf("%x", pd.Key.N)
this.C = fmt.Sprintf("%x", pd.C)
this.V = fmt.Sprintf("%x", pd.Key.V)
this.Decryption = fmt.Sprintf("%x", pd.Decryption)
this.Vi = make([]string, len(pd.Key.Vi))
for i, vi := range pd.Key.Vi {
this.Vi[i] = fmt.Sprintf("%x", vi)
}
}
func (this *dbPartialDecryptionZKP) ToPartialDecryptionZKP(pd *PartialDecryptionZKP) error {
pd.Key = new(ThresholdKey)
var oks = make([]bool, 7)
pd.Id = this.Id
pd.Key.TotalNumberOfDecryptionServers = this.TotalNumberOfDecryptionServers
pd.Key.Threshold = this.Threshold
pd.Z, oks[0] = new(big.Int).SetString(this.Z, 16)
pd.E, oks[1] = new(big.Int).SetString(this.E, 16)
pd.C, oks[2] = new(big.Int).SetString(this.C, 16)
pd.Key.V, oks[3] = new(big.Int).SetString(this.V, 16)
pd.Key.G, oks[4] = new(big.Int).SetString(this.G, 16)
pd.Key.N, oks[5] = new(big.Int).SetString(this.N, 16)
pd.Decryption, oks[6] = new(big.Int).SetString(this.Decryption, 16)
if !all(oks) {
fmt.Println(oks)
fmt.Println(this.E, "|", this.Z, "|", this.C, "|", this.V, "|", this.Decryption)
return errors.New("numbers not in hexadecimal format")
}
pd.Key.Vi = make([]*big.Int, len(this.Vi))
var ok bool
for i, vi := range this.Vi {
pd.Key.Vi[i], ok = new(big.Int).SetString(vi, 16)
if !ok {
return errors.New("numbers not in hexadecimal format")
}
}
return nil
}
func (this *PartialDecryptionZKP) MarshalJSON() ([]byte, error) {
db := new(dbPartialDecryptionZKP)
db.FromPartialDecryptionZKP(this)
return json.Marshal(db)
}
func (this *PartialDecryptionZKP) UnmarshalJSON(data []byte) error {
db := new(dbPartialDecryptionZKP)
if err := json.Unmarshal(data, db); err != nil {
return err
}
return db.ToPartialDecryptionZKP(this)
}
func (this *PartialDecryptionZKP) GetBSON() (interface{}, error) {
db := new(dbPartialDecryptionZKP)
db.FromPartialDecryptionZKP(this)
return db, nil
}
func (this *PartialDecryptionZKP) SetBSON(raw bson.Raw) error {
db := new(dbPartialDecryptionZKP)
if err := raw.Unmarshal(db); err != nil {
return err
}
return db.ToPartialDecryptionZKP(this)
}