paillier

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Mar 11, 2022 License: Apache-2.0 Imports: 8 Imported by: 9

README

Paillier Cryptosystem

Package paillier contains Paillier's cryptosystem (1999). All routines here from pseudocode §2.5. Fig 1: The Paillier Cryptosystem.

This module provides APIs for:

  • generating a safe keypair
  • encryption and decryption
  • adding two encrypted values, Enc(a) and Enc(b), and obtaining Enc(a + b), and
  • multiplying a plain value, a, and an encrypted value Enc(b), and obtaining Enc(a * b).

The encrypted values are represented as big.Int and are serializable. This module also provides JSON serialization for the PublicKey and the SecretKey.

Documentation

Overview

Package paillier contains Paillier's cryptosystem (1999) [P99]. Public-Key Cryptosystems Based on Composite Degree Residuosity Class. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.112.4035&rep=rep1&type=pdf All routines here from pseudocode §2.5. Fig 1: The Paillier Cryptosystem.

This module provides APIs for:

  • generating a safe keypair,
  • encryption and decryption,
  • adding two encrypted values, Enc(a) and Enc(b), and obtaining Enc(a + b), and
  • multiplying a plain value, a, and an encrypted value Enc(b), and obtaining Enc(a * b).

The encrypted values are represented as big.Int and are serializable. This module also provides JSON serialization for the PublicKey and the SecretKey.

Example (EncryptDecrypt)
// Skip this example if -short parameter is passed.
if testing.Short() {
	// Printing the expected output so that the test succeeds.
	fmt.Println("Succeeded in encrypting and decrypting the input message: Hello World!")
	return
}
hexMessage := hex.EncodeToString([]byte("Hello World!"))
mappedMessage, ok := new(big.Int).SetString(hexMessage, 16)
if !ok {
	panic("Error mapping message to scalar point.")
}
pub, sec, err := NewKeys()
if err != nil {
	log.Fatalf("Error in generating keypair: %v", err)
}

// Ignoring the random value that was generated internally by `Encrypt`.
cipher, _, err := pub.Encrypt(mappedMessage)
if err != nil {
	log.Fatalf("Error in Encrypting the message: %v", err)
}

// Now decrypt using the secret key.
decrypted, err := sec.Decrypt(cipher)
if err != nil {
	log.Fatalf("Error in Decrypting the ciphertext: %v", err)
}

decoded := string(decrypted.Bytes())
fmt.Println("Succeeded in encrypting and decrypting the input message:", decoded)
Output:

Succeeded in encrypting and decrypting the input message: Hello World!
Example (HomomorphicAddition)
// Skip this example if -short parameter is passed.
if testing.Short() {
	// Printing the expected output so that the test succeeds.
	fmt.Println("Encrypting 123 and 456 separately.")
	fmt.Println("Adding their encrypted versions together.")
	fmt.Println("Succeeded in decrypting 579")
	return
}
pub, sec, err := NewKeys()
if err != nil {
	log.Fatalf("Error in generating keypair: %v", err)
}

msg1 := tt.B10("123")
msg2 := tt.B10("456")
fmt.Printf("Encrypting %s and %s separately.\n", msg1, msg2)

cipher1, _, err := pub.Encrypt(msg1)
if err != nil {
	log.Fatalf("Error in Encrypting the message: %v", err)
}
cipher2, _, err := pub.Encrypt(msg2)
if err != nil {
	log.Fatalf("Error in Encrypting the message: %v", err)
}

fmt.Println("Adding their encrypted versions together.")
cipher3, err := pub.Add(cipher1, cipher2)
if err != nil {
	log.Fatalf("Error in adding the two ciphertexts: %v", err)
}
decrypted3, err := sec.Decrypt(cipher3)
if err != nil {
	log.Fatalf("Error in Decrypting the ciphertext: %v", err)
}
fmt.Println("Succeeded in decrypting", decrypted3)
Output:

Encrypting 123 and 456 separately.
Adding their encrypted versions together.
Succeeded in decrypting 579
Example (HomomorphicMultiplication)
// Skip this example if -short parameter is passed.
if testing.Short() {
	// Printing the expected output so that the test succeeds.
	fmt.Println("Encrypting 10.")
	fmt.Println("Multiplying plain 5 with the encrypted 10.")
	fmt.Println("Succeeded in decrypting 50.")
	return
}
pub, sec, err := NewKeys()
if err != nil {
	log.Fatalf("Error in generating keypair: %v", err)
}

msg1 := tt.B10("10")
msg2 := tt.B10("5")
fmt.Printf("Encrypting %s.\n", msg1)

cipher1, _, err := pub.Encrypt(msg1)
if err != nil {
	log.Fatalf("Error in Encrypting the message: %v", err)
}

fmt.Printf("Multiplying plain %s with the encrypted %s.\n", msg2, msg1)
cipher3, err := pub.Mul(msg2, cipher1)
if err != nil {
	log.Fatalf("Error in adding the two ciphertexts: %v", err)
}
decrypted3, err := sec.Decrypt(cipher3)
if err != nil {
	log.Fatalf("Error in Decrypting the ciphertext: %v", err)
}
fmt.Printf("Succeeded in decrypting %s.\n", decrypted3)
Output:

Encrypting 10.
Multiplying plain 5 with the encrypted 10.
Succeeded in decrypting 50.

Index

Examples

Constants

View Source
const PaillierPrimeBits = 1024

PaillierPrimeBits is the number of bits used to generate Paillier Safe Primes.

View Source
const PsfProofLength = 13

[spec] 10.2 and ProvePSF, VerifyPSF fig.15

Variables

This section is empty.

Functions

func NewKeys

func NewKeys() (*PublicKey, *SecretKey, error)

NewKeys generates Paillier keys with `bits` sized safe primes.

Types

type Ciphertext

type Ciphertext *big.Int

Ciphertext in Pailler's cryptosystem: a value $c \in Z_{N²}$ .

type PsfProof

type PsfProof []*big.Int

PsfProof is a slice of 13 big.Int's that prove that a Paillier modulus is square-free

func (PsfProof) Verify

func (p PsfProof) Verify(psf *PsfVerifyParams) error

Verify that a Paillier modulus is square-free [spec] §10.fig 15

type PsfProofParams

type PsfProofParams struct {
	Curve     elliptic.Curve
	SecretKey *SecretKey
	Pi        uint32
	Y         *curves.EcPoint
}

PsfProofParams contains the inputs to ProvePSF

func (*PsfProofParams) Prove

func (p *PsfProofParams) Prove() (PsfProof, error)

Prove that a Paillier modulus is square-free [spec] §10.fig 15

type PsfVerifyParams

type PsfVerifyParams struct {
	Curve     elliptic.Curve
	PublicKey *PublicKey
	Pi        uint32
	Y         *curves.EcPoint
}

PsfVerifyParams contains the inputs to VerifyPSF

type PublicKey

type PublicKey struct {
	N  *big.Int // N = PQ
	N2 *big.Int // N² computed and cached to prevent re-computation.
}

PublicKey is a Paillier public key: N = P*Q; for safe primes P,Q.

func NewPubkey

func NewPubkey(n *big.Int) (*PublicKey, error)

NewPubkey initializes a Paillier public key with a given n.

func (*PublicKey) Add

func (pk *PublicKey) Add(c, d Ciphertext) (Ciphertext, error)

Add combines two Paillier ciphertexts.

func (*PublicKey) Encrypt

func (pk *PublicKey) Encrypt(msg *big.Int) (Ciphertext, *big.Int, error)

Encrypt produces a ciphertext on input message.

func (PublicKey) MarshalJSON

func (pk PublicKey) MarshalJSON() ([]byte, error)

MarshalJSON converts the public key into json format.

func (*PublicKey) Mul

func (pk *PublicKey) Mul(a *big.Int, c Ciphertext) (Ciphertext, error)

Mul is equivalent to adding two Paillier exponents.

func (*PublicKey) UnmarshalJSON

func (pk *PublicKey) UnmarshalJSON(bytes []byte) error

UnmarshalJSON converts the json data into this public key.

type PublicKeyJson

type PublicKeyJson struct {
	N *big.Int
}

PublicKeyJson encapsulates the data that is serialized to JSON. It is used internally and not for external use. Public so other pieces can use for serialization.

type SecretKey

type SecretKey struct {
	PublicKey
	Lambda  *big.Int // lcm(P - 1, Q - 1)
	Totient *big.Int // Euler's totient: (P - 1) * (Q - 1)
	U       *big.Int // L((N + 1)^λ(N) mod N²)−1 mod N
}

SecretKey is a Paillier secret key.

func NewSecretKey

func NewSecretKey(p, q *big.Int) (*SecretKey, error)

NewSecretKey computes intermediate values based on safe primes p, q.

func (*SecretKey) Decrypt

func (sk *SecretKey) Decrypt(c Ciphertext) (*big.Int, error)

Decrypt is the reverse operation of Encrypt.

func (SecretKey) MarshalJSON

func (sk SecretKey) MarshalJSON() ([]byte, error)

MarshalJSON converts the secret key into json format.

func (*SecretKey) UnmarshalJSON

func (sk *SecretKey) UnmarshalJSON(bytes []byte) error

UnmarshalJSON converts the json data into this secret key.

type SecretKeyJson

type SecretKeyJson struct {
	N, Lambda, Totient, U *big.Int
}

SecretKeyJson encapsulates the data that is serialized to JSON. It is used internally and not for external use. Public so other pieces can use for serialization.

Jump to

Keyboard shortcuts

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