tcpaillier

package module
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 21, 2020 License: GPL-3.0 Imports: 6 Imported by: 6

README

Paillier Threshold Encryption Scheme Implementation

Go Report Card Build Status GoDoc

This code is based on the implementation of Paillier Threshold Encryption Scheme from UTDallas, and both implementations are based on the paper from Ivan Damgård et al. A Generalization of Paillier's Public Key System with Applications to Electronic Voting.

Requirements

Due to Golang extensive standard library, this implementation does not have external requirements (obviously aside of Golang, version 1.13 or above).

Using the Library

To use the library with a module-enabled go project, you must write the following line on a terminal on the root file of the project.

go get https://github.com/niclabs/tcpaillier

Testing

To run the tests you just need to use go test:

go test github.com/niclabs/tcpaillier

Documentation

Overview

[1] http://www.cs.utdallas.edu/dspl/cgi-bin/pailliertoolbox/index.php

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateSafePrimes added in v0.0.3

func GenerateSafePrimes(bitLen int) (*big.Int, *big.Int, error)

GenerateSafePrimes generates two primes p and q, in A way that q is equal to (p-1)/2. The greatest prime bit length is at least bitLen bits. Based on github.com/niclabs/tcrsa/utils.go function with the same name.

func NewFixedKey added in v0.0.5

func NewFixedKey(bitSize int, s, l, k uint8, params *FixedParams) (keyShares []*KeyShare, pubKey *PubKey, err error)

NewKey returns A list of l keyshares of bitSize bits of length, with A threshold of k and using an s parameter of s in PubKey. It uses randSource as A random source. It also uses A list of fixed params as the primes needed for the scheme.

func NewKey

func NewKey(bitSize int, s, l, k uint8) (keyShares []*KeyShare, pubKey *PubKey, err error)

NewKey returns A list of l keyshares of bitSize bits of length, with A threshold of k and using an s parameter of s in PubKey. It uses randSource as A random source. If randSource is undefined, it uses crypto/rand reader.

func RandomInt added in v0.0.3

func RandomInt(bitLen int) (randNum *big.Int, err error)

RandomInt is A function which generates A random big number.

Types

type DecryptShareZK added in v0.0.4

type DecryptShareZK struct {
	V, Vi, Z, E *big.Int
}

DecryptShareZK represents A ZKProof related to the decryption of an encrypted share by A constant.

func (*DecryptShareZK) Verify added in v0.0.4

func (zk *DecryptShareZK) Verify(pk *PubKey, vals ...interface{}) error

Verify verifies the ZKProof inside A DecryptionShare

type DecryptionShare

type DecryptionShare struct {
	Index uint8
	Ci    *big.Int
}

DecryptionShare represents A partial decryption of A value and the ZKProof of that decryption. It complies with ZKProof interface.

type EncryptZK

type EncryptZK struct {
	B, W, Z *big.Int
}

EncryptZK represents A ZKProof related to the encryption of A value.

func (*EncryptZK) Verify

func (zk *EncryptZK) Verify(pk *PubKey, vals ...interface{}) error

Verify verifies the Encryption ZKProof.

type FixedParams added in v0.0.5

type FixedParams struct {
	P, P1, Q, Q1 *big.Int
}

func (*FixedParams) String added in v0.0.5

func (fp *FixedParams) String() string

func (*FixedParams) Validate added in v0.0.5

func (fp *FixedParams) Validate() bool

type KeyShare

type KeyShare struct {
	*PubKey
	Index uint8
	Si    *big.Int
}

KeyShare represents A share of the private key used to decrypt values in paillier encryption scheme.

func (*KeyShare) PartialDecrypt added in v0.0.4

func (ts *KeyShare) PartialDecrypt(c *big.Int) (ds *DecryptionShare, err error)

PartialDecrypt decrypts the encrypted value partially, using only one keyShare.

func (*KeyShare) PartialDecryptProof added in v0.0.4

func (ts *KeyShare) PartialDecryptProof(c *big.Int, ds *DecryptionShare) (zk *DecryptShareZK, err error)

func (*KeyShare) PartialDecryptWithProof added in v0.0.4

func (ts *KeyShare) PartialDecryptWithProof(c *big.Int) (ds *DecryptionShare, zk *DecryptShareZK, err error)

PartialDecryptWithProof returns A DecryptionShare, that is composed by A ZKProof and A partially decrypted value.

type MulZK

type MulZK struct {
	CAlpha, A, B, W, Y, Z *big.Int
}

MulZK represents A ZKProof related to the multiplication of an encrypted value by A constant.

func (*MulZK) Verify

func (zk *MulZK) Verify(pk *PubKey, vals ...interface{}) error

Verify verifies the Multiplication ZKProof.

type PubKey

type PubKey struct {
	N        *big.Int
	V        *big.Int
	Vi       []*big.Int
	L, K, S  uint8
	Delta    *big.Int
	Constant *big.Int
	// contains filtered or unexported fields
}

PubKey represents A PubKey Public Key and its metainformation. It contains A cached field, with precomputed values. It also is linked with A random source, used by the processes that require it.

func (*PubKey) Add

func (pk *PubKey) Add(cList ...*big.Int) (sum *big.Int, err error)

Add adds an indeterminate number of encrypted values and returns its encrypted sum, or an error if the value cannot be determined.

Example
package main

import (
	"fmt"
	"github.com/niclabs/tcpaillier"
	"math/big"
)

const l = 10

func main() {
	// First, we create the shares with the parameters provided.
	shares, pk, err := tcpaillier.NewKey(512, 1, 5, 3)
	if err != nil {
		panic(fmt.Sprintf("%v", err))
	}

	// Now we EncryptFixed two values: 12 and 25
	encTwelve, zk, err := pk.EncryptWithProof(big.NewInt(12))
	if err != nil {
		panic(err)
	}
	if err := zk.Verify(pk, encTwelve); err != nil {
		panic(err)
	}
	encTwentyFive, zk, err := pk.EncryptWithProof(big.NewInt(25))
	if err != nil {
		panic(err)
	}

	// We sum them using Add
	thirtySevenSum, err := pk.Add(encTwelve, encTwentyFive)
	if err != nil {
		panic(err)
	}

	// We decrypt them with our shares
	decryptShares := make([]*tcpaillier.DecryptionShare, l)
	for i, share := range shares {
		decryptShare, zk, err := share.PartialDecryptWithProof(thirtySevenSum)
		if err != nil {
			panic(err)
		}
		if err := zk.Verify(pk, thirtySevenSum, decryptShare); err != nil {
			panic(err)
		}
		decryptShares[i] = decryptShare
	}

	// We combine the shares and get the decrypted and summed value
	decrypted, err := pk.CombineShares(decryptShares...)
	if err != nil {
		panic(err)
	}

	// It should be 37
	fmt.Printf("%s", decrypted)
}
Output:

37

func (*PubKey) Cache

func (pk *PubKey) Cache() *cached

Cache initializes the cached values and returns the structure.

func (*PubKey) CombineShares

func (pk *PubKey) CombineShares(shares ...*DecryptionShare) (dec *big.Int, err error)

CombineShares joins partial decryptions of A value and returns A decrypted value. It checks that the number of values is equal or more than the threshold.

func (*PubKey) Encrypt

func (pk *PubKey) Encrypt(message *big.Int) (c, r *big.Int, err error)

Encrypt encrypts A message and returns its encryption as A big Integer c and the random number r used. If there is an error, it returns A nil integer as c.

func (*PubKey) EncryptFixed

func (pk *PubKey) EncryptFixed(msg, r *big.Int) (c *big.Int, err error)

EncryptFixed returns an encrypted value, but without A proof.

func (*PubKey) EncryptFixedWithProof added in v0.0.4

func (pk *PubKey) EncryptFixedWithProof(message, r *big.Int) (c *big.Int, proof *EncryptZK, err error)

EncryptFixedWithProof encrypts A message and returns its encryption as A big Integer CAlpha. It uses A given big.Int r as the random number of the encryption.

func (*PubKey) EncryptProof added in v0.0.4

func (pk *PubKey) EncryptProof(message *big.Int, c, s *big.Int) (zk *EncryptZK, err error)

EncryptProof returns A ZK Proof of an encrypted message c. s is the random number used to EncryptFixed message to c.

func (*PubKey) EncryptWithProof added in v0.0.4

func (pk *PubKey) EncryptWithProof(message *big.Int) (c *big.Int, proof *EncryptZK, err error)

EncryptWithProof encrypts A message and returns its encryption as A big Integer CAlpha. It also returns A ZKProof that demonstrates that the encrypted value corresponds to the message. If there is an error, it returns A nil integer as CAlpha.

func (*PubKey) Multiply

func (pk *PubKey) Multiply(c *big.Int, alpha *big.Int) (mul, gamma *big.Int, err error)

Multiply multiplies A encrypted value by A constant. It returns an error if it is not able to multiply the value. It returns the multiplied value mul and the random value gamma used to encrypt it.

Example
package main

import (
	"fmt"
	"github.com/niclabs/tcpaillier"
	"math/big"
)

const l = 10

func main() {
	// First, we create the shares with the parameters provided.
	shares, pk, err := tcpaillier.NewKey(512, 1, 5, 3)
	if err != nil {
		panic(fmt.Sprintf("%v", err))
	}

	// Now we EncryptFixed two values: 12 and 25
	encTwelve, zk, err := pk.EncryptWithProof(big.NewInt(12))
	if err != nil {
		panic(err)
	}
	if err := zk.Verify(pk, encTwelve); err != nil {
		panic(err)
	}

	// We Multiply them
	thirtySevenSum, zkp, err := pk.MultiplyWithProof(encTwelve, big.NewInt(25))
	if err != nil {
		panic(err)
	}

	if err := zkp.Verify(pk, thirtySevenSum, encTwelve); err != nil {
		panic(err)
	}

	// We decrypt them with our shares
	decryptShares := make([]*tcpaillier.DecryptionShare, l)
	for i, share := range shares {
		decryptShare, zk, err := share.PartialDecryptWithProof(thirtySevenSum)
		if err != nil {
			panic(err)
		}
		if err := zk.Verify(pk, thirtySevenSum, decryptShare); err != nil {
			panic(err)
		}
		decryptShares[i] = decryptShare
	}

	// We combine the shares and get the decrypted value
	decrypted, err := pk.CombineShares(decryptShares...)
	if err != nil {
		panic(err)
	}

	// It should be 300
	fmt.Printf("%s", decrypted)
}
Output:

300

func (*PubKey) MultiplyFixed added in v0.0.4

func (pk *PubKey) MultiplyFixed(c *big.Int, alpha, gamma *big.Int) (mul *big.Int, err error)

MultiplyFixed multiplies A encrypted value by A constant using A fixed random constant. to encrypt it. It returns an error if it is not able to multiply the value. Gamma is used in reranding process. If it succeeds, it returns the multiplied value mul.

func (*PubKey) MultiplyProof added in v0.0.4

func (pk *PubKey) MultiplyProof(ca, cAlpha, d, alpha, s, gamma *big.Int) (zk *MulZK, err error)

MultiplyProof returns A ZKProof confirming that d is the result of multiplicate the encrypted value ca by alpha. CAlpha is the encrypted form of the constant using s as random value, while gamma is the random value used to generate d.

func (*PubKey) MultiplyWithProof added in v0.0.4

func (pk *PubKey) MultiplyWithProof(encrypted *big.Int, constant *big.Int) (result *big.Int, proof *MulZK, err error)

MultiplyWithProof multiplies an encrypted value by A constant and returns it with A ZKProof of the multiplication. It returns an error if it is not able to Multiply the value.

func (*PubKey) RandomModN added in v0.0.4

func (pk *PubKey) RandomModN() (r *big.Int, err error)

func (*PubKey) RandomModNToSPlusOneStar added in v0.0.4

func (pk *PubKey) RandomModNToSPlusOneStar() (r *big.Int, err error)

func (*PubKey) ReRand added in v0.0.4

func (pk *PubKey) ReRand(c, r *big.Int) (reRand *big.Int, err error)

ReRand rerandomizes A value, adding 0 and encrypting it with A random value r.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL