File: paillier.h

package info (click to toggle)
sfs 1%3A0.8-0%2Bpre20060720.1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 9,668 kB
  • ctags: 14,317
  • sloc: cpp: 78,358; ansic: 15,494; sh: 9,540; yacc: 786; makefile: 706; perl: 676; lex: 553; python: 146; sed: 70
file content (138 lines) | stat: -rw-r--r-- 4,441 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// -*-c++-*-
/* $Id: paillier.h,v 1.6 2006/02/25 02:02:40 mfreed Exp $ */

/*
 *
 * Copyright (C) 2005 Michael J. Freedman (mfreedman at alum.mit.edu)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 */

#ifndef _PAILLIER_H_
#define _PAILLIER_H_ 1

#include "homoenc.h"

// Use Chinese Remaindering for fast decryption
#define _PAILLIER_CRT_ 1

class paillier_pub : public virtual homoenc_pub {
public:
  const bigint n;		/* Modulus */
  const bigint g;		/* Basis g */
  const size_t nbits;

protected:
  bool fast;
  bigint nsq;	   	        /* Modulus^2 */
  // _FAST_PAILLIER_  
  bigint gn;                    /* g^N % nsq */

  void init ();

public:
  paillier_pub (const bigint &nn);
  paillier_pub (const bigint &nn, const bigint &gg);
  virtual ~paillier_pub () {}

  virtual const size_t &mod_size      () const { return nbits; }
  virtual const bigint &ptext_modulus () const { return n;     }
  virtual const bigint &ctext_modulus () const { return nsq;   }

  virtual bool encrypt (crypt_ctext *c, const bigint &msg, bool recover) const;
  virtual bool encrypt (crypt_ctext *c, const str &msg,
			bool recover = true) const
  { return homoenc_pub::encrypt (c, msg, recover); }

  virtual crypt_keytype ctext_type () const { return CRYPT_PAILLIER; }

  // Resulting ciphertext is sum of msgs' corresponding plaintexts
  // ctext = ctext1*ctext2 ==> ptext = ptext1 + ptext2
  virtual void add (crypt_ctext *c, const crypt_ctext &msg1, 
		    const crypt_ctext &msg2) const;

  // Resulting ciphertext is msg's corresponding plaintext * constant
  // ctext = ctext^const ==> ptext = const * ptext 
  virtual void mult (crypt_ctext *c, const crypt_ctext &msg, 
		     const bigint &cons) const;
};


class paillier_priv : public paillier_pub, public virtual homoenc_priv {
public:
  const bigint p;		/* Smaller prime */
  const bigint q;	        /* Larger prime  */
  const bigint a;               /* For fast decryption */

protected:
  bigint p1;		        /* p-1             */
  bigint q1;		        /* q-1             */

  bigint k;	       	        /* lcm (p-1)(q-1)  */
  bigint psq;                   /* p^2             */
  bigint qsq;                   /* q^2             */

#if _PAILLIER_CRT_
  // Pre-computations
  bigint rp;                    /* q^{-1} % p */
  bigint rq;                    /* p^{-1} % q */

  bigint two_p;			/* 2^|p| */
  bigint two_q;			/* 2^|q| */

  bigint lp;			/* p^{-1} % 2^|p| */
  bigint lq;			/* q^{-1} % 2^|q| */

  bigint hp;			/* Lp (g^a % p^2) ^ {-1} % p */
  bigint hq;			/* Lq (g^a % q^2) ^ {-1} % q */
#else
  bigint two_n;                 /* 2^|n| */
  bigint ln;                    /* n^{-1} % 2^|n| */
  bigint hn;                    /* Ln (g^k % n^2) ^ {-1} % n */
#endif

  void init ();

  void CRT (bigint &, bigint &) const;
  void D   (bigint &, const bigint &) const;

public:
  paillier_priv (const bigint &pp, const bigint &qq, const bigint *nn = NULL);
  paillier_priv (const bigint &pp, const bigint &qq, 
		 const bigint &aa, const bigint &gg, 
		 const bigint &kk, const bigint *nn = NULL);
  virtual ~paillier_priv () {}

  // Use the slower version, yet more standard cryptographic assumptions
  static ptr<paillier_priv> make (const bigint &p, const bigint &q);
  // Use the fast decryption version
  static ptr<paillier_priv> make (const bigint &p, const bigint &q,
				  const bigint &a);

  virtual str decrypt (const crypt_ctext &msg, size_t msglen,
		       bool recover = true) const;
};


// Paillier without fast decryption
paillier_priv paillier_skeygen  (size_t nbits, u_int iter = 32);

// Paillier with fast decryption
// abits gives length of subgroup [e.g., 160 bits for 1024-bit keys]
paillier_priv paillier_keygen  (size_t nbits, size_t abits, u_int iter = 32);

#endif /* !_PAILLIER_H_  */