File: rabin.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 (175 lines) | stat: -rw-r--r-- 4,886 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// -*-c++-*-
/* $Id: rabin.h,v 1.20 2005/06/17 00:35:45 fubob Exp $ */

/*
 *
 * Copyright (C) 1998 David Mazieres (dm@uun.org)
 *
 * 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 _RABIN_H_
#define _RABIN_H_ 1

#include "bigint.h"
#include "sha1.h"
#include "blowfish.h"

bigint pre_encrypt (str msg, size_t nbits);
str post_decrypt (const bigint &m, size_t msglen, size_t nbits);
bigint pre_sign (sha1ctx *sc, size_t nbits);
bool post_verify (sha1ctx *sc, const bigint &s, size_t nbits);
bigint pre_sign_r (str msg, size_t nbits);
str post_verify_r (const bigint &s, size_t msglen, size_t nbits);

class rabin_pub {
public:
  const bigint n;		/* Modulus */

protected:
  const int nbits;

  bool E1 (bigint &, const bigint &) const;
  void E2 (bigint &, const bigint &) const;
  void D1 (bigint &, const bigint &) const;

public:
  rabin_pub (const bigint &nn)
    : n (nn), nbits (max ((int) n.nbits () - 5, 0)) {}
  const bigint &modulus () const { return n; }

  bigint encrypt (const str &msg) const {
    bigint m = pre_encrypt (msg, nbits);
    if (!m || !E1 (m, m))
      return 0;
    E2 (m, m);
    return m;
  }
  bool verify (const str &msg, const bigint &s) const {
    bigint m;
    E2 (m, s);
    D1 (m, m);
    sha1ctx sc;
    sc.update (msg.cstr (), msg.len ());
    return post_verify (&sc, m, nbits);
  }
  str verify_r (const bigint &s, size_t msglen) const {
    bigint m;
    E2 (m, s);
    D1 (m, m);
    return post_verify_r (m, msglen, nbits);
  }
};

class rabin_priv : public rabin_pub {
public:
  const bigint p;		/* Smaller prime */
  const bigint q;		/* Larger prime */

protected:
  bigint u;			/* q^(-1) mod p */
  bigint kp;			/* (((p-1)(q-1)+4)/8) % p-1 */
  bigint kq;			/* (((p-1)(q-1)+4)/8) % q-1 */

  void init ();

  void D2 (bigint &, const bigint &, int rsel = 0) const;

public:
  rabin_priv (const bigint &, const bigint &);
  static ptr<rabin_priv> make (const bigint &n1, const bigint &n2);

  str decrypt (const bigint &msg, size_t msglen) const {
    bigint m;
    D2 (m, msg);
    D1 (m, m);
    return post_decrypt (m, msglen, nbits);
  }
  bigint sign (const str &msg) const {
    sha1ctx sc;
    sc.update (msg.cstr (), msg.len ());
    bigint m = pre_sign (&sc, nbits);
    E1 (m, m);
    D2 (m, m, rnd.getword ());
    return m;
  }
  bigint sign_r (const str &msg) const {
    bigint m = pre_sign_r (msg, nbits);
    E1 (m, m);
    D2 (m, m, rnd.getword ());
    return m;
  }
};

rabin_priv rabin_keygen (size_t nbits, u_int iter = 32);

/*
 * Serialized format of a rabin private key:
 *
 * The private key itself is stured using the following XDR data structures:
 *
 * struct keyverf {
 *   asckeytype type;  // SK_RABIN_EKSBF
 *   bigint pubkey;    // The modulus of the public key
 * };
 *
 * struct privkey {
 *   bigint p;         // Smaller prime of secret key
 *   bigint q;         // Larger prime of secret key
 *   sfs_hash verf;    // SHA-1 hash of keyverf structure
 * };
 *
 * Option 1:  The secret key is stored without a passphrase
 *
 * "SK" SK_RABIN_EKSBF ",," privkey "," pubkey "," comment
 *
 *   SK_RABIN_EKSBF - the number 1 in ascii decimal
 *          privkey - a struct privkey, XDR and armor64 encoded
 *           pubkey - the public key modulus in hex starting "0x"
 *          comment - an arbitrary and possibly empty string
 *
 * Option 2:  There is a passphrase
 *
 * "SK" SK_RABIN_EKSBF "," rounds "$" salt "$" ptext "," seckey "," pubkey
 *   "," comment
 *
 *           rounds - the cost paraeter of eksblowfish in ascii decimal
 *             salt - a 16 byte random salt for eksblowfish, armor64 encoded
 *            ptext - arbitrary length string of the user's choice
 *        secretkey - A privkey struct XDR encoded, with 4 null-bytes
 *                    appended if neccesary to make the size a multiple
 *                    of 8 bytes, encrypted once with eksblowfish,
 *                    then armor64 encoded
 *       
 */

class rabin_priv;

enum asckeytype {
  SK_ERROR = 0,			// Keyfile corrupt
  SK_RABIN_EKSBF = 1,		// Rabin secret key encrypted with eksblowfish
};

const size_t SK_RABIN_SALTBITS = 1024;

inline str
file2wstr (str path)
{
  return str2wstr (file2str (path));
}

#endif /* !_RABIN_H_  */