Commit f496f9a5 authored by Niels Möller's avatar Niels Möller
Browse files

* src/publickey_crypto.c (zn_member): Deleted unused method.

(zn_range, zn_invert, zn_mul, zn_exp, zn_exp_ui, zn_add, zn_sub):
Non-static functions replaces the GROUP_COMBINE etc methods.
(make_group_zn, make_ring_zn): Deleted functions...
(make_ssh_group): ... replaced by new funtion.
(make_ssh_group1, make_ssh_ring_srp_1): Use make_ssh_group.
(make_ssh_group14): New function.

* src/publickey_crypto.h (abstract_group): Deleted class and
methods.
(zn_group): Declare class here, and plain functions for using it.
Replaced all uses of struct abstract_group with const struct
zn_group.
(dh_instance): Use const for the dh_method pointer.

Rev: src/publickey_crypto.c:1.47
Rev: src/publickey_crypto.h:1.52
parent 336faece
......@@ -42,8 +42,6 @@
#include "publickey_crypto.h.x"
#undef GABA_DEFINE
#include "publickey_crypto.c.x"
struct keypair *
make_keypair(uint32_t type,
struct lsh_string *public,
......@@ -57,205 +55,126 @@ make_keypair(uint32_t type,
return self;
}
/* Groups */
/* GABA:
(class
(name group_zn)
(super abstract_group)
(vars
(modulo bignum)))
*/
static int
zn_range(struct abstract_group *c, mpz_t x)
int
zn_range(const struct zn_group *G, const mpz_t x)
{
CAST(group_zn, closure, c);
return ( (mpz_sgn(x) == 1) && (mpz_cmp(x, closure->modulo) < 0) );
return ( (mpz_sgn(x) == 1) && (mpz_cmp(x, G->modulo) < 0) );
}
#if 0
static int
zn_member(struct abstract_group *c, mpz_t x)
void
zn_invert(const struct zn_group *G, mpz_t res, const mpz_t x)
{
if (zn_range(c, x))
{
CAST(group_zn, closure, c);
mpz_t t;
int res;
mpz_init(t);
mpz_powm(t, x, closure->order, closure->modulo);
res = !mpz_cmp_ui(t, 1);
mpz_clear(t);
return res;
}
return 0;
}
#endif
static void
zn_invert(struct abstract_group *c, mpz_t res, mpz_t x)
{
CAST(group_zn, closure, c);
/* NOTE: In gmp-2, mpz_invert sometimes generates negative inverses. */
if (!mpz_invert(res, x, closure->modulo))
if (!mpz_invert(res, x, G->modulo))
fatal("zn_invert: element is non-invertible\n");
mpz_fdiv_r(res, res, closure->modulo);
/* NOTE: In gmp-2, mpz_invert sometimes generates negative inverses. */
assert (mpz_sgn(res) > 0);
}
static void
zn_combine(struct abstract_group *c, mpz_t res, mpz_t a, mpz_t b)
void
zn_mul(const struct zn_group *G, mpz_t res, const mpz_t a, const mpz_t b)
{
CAST(group_zn, closure, c);
mpz_mul(res, a, b);
mpz_fdiv_r(res, res, closure->modulo);
}
static void
zn_power(struct abstract_group *c, mpz_t res, mpz_t g, mpz_t e)
{
CAST(group_zn, closure, c);
mpz_powm(res, g, e, closure->modulo);
mpz_fdiv_r(res, res, G->modulo);
}
static void
zn_small_power(struct abstract_group *c, mpz_t res, mpz_t g, uint32_t e)
void
zn_exp(const struct zn_group *G, mpz_t res, const mpz_t g, const mpz_t e)
{
CAST(group_zn, closure, c);
mpz_powm_ui(res, g, e, closure->modulo);
mpz_powm(res, g, e, G->modulo);
}
/* Assumes p is a prime number */
struct abstract_group *
make_group_zn(mpz_t p, mpz_t g, mpz_t order)
void
zn_exp_ui(const struct zn_group *G, mpz_t res, const mpz_t g, uint32_t e)
{
NEW(group_zn, res);
res->super.range = zn_range;
res->super.invert = zn_invert;
res->super.combine = zn_combine;
res->super.power = zn_power; /* Pretty Mutation! Magical Recall! */
res->super.small_power = zn_small_power;
res->super.add = NULL;
res->super.subtract = NULL;
mpz_init_set(res->modulo, p);
mpz_init_set(res->super.generator, g);
mpz_init_set(res->super.order, order);
return &res->super;
mpz_powm_ui(res, g, e, G->modulo);
}
static int
zn_ring_add(struct abstract_group *s,
mpz_t res, mpz_t a, mpz_t b)
int
zn_add(const struct zn_group *G,
mpz_t res, const mpz_t a, const mpz_t b)
{
CAST(group_zn, self, s);
mpz_add(res, a, b);
mpz_fdiv_r(res, res, self->modulo);
mpz_fdiv_r(res, res, G->modulo);
return mpz_sgn(res);
}
static int
zn_ring_subtract(struct abstract_group *s,
mpz_t res, mpz_t a, mpz_t b)
int
zn_sub(const struct zn_group *G,
mpz_t res, const mpz_t a, const mpz_t b)
{
CAST(group_zn, self, s);
mpz_sub(res, a, b);
mpz_fdiv_r(res, res, self->modulo);
mpz_fdiv_r(res, res, G->modulo);
return mpz_sgn(res);
}
/* Assumes p is a prime number, and g a primitive root. */
struct abstract_group *
make_ring_zn(mpz_t p, mpz_t g)
static struct zn_group *
make_ssh_group(const char *prime, unsigned g, int primitive)
{
NEW(group_zn, res);
NEW (zn_group, G);
res->super.range = zn_range;
res->super.invert = zn_invert;
res->super.combine = zn_combine;
res->super.power = zn_power;
res->super.small_power = zn_small_power;
res->super.add = zn_ring_add;
res->super.subtract = zn_ring_subtract;
mpz_init_set(res->modulo, p);
mpz_init_set(res->super.generator, g);
mpz_init_set(res->super.order, p);
mpz_sub_ui(res->super.order, res->super.order, 1);
/* Prime and generator as defined in
* draft-ietf-secsh-transport-07.txt. */
mpz_init_set_str(G->modulo, prime, 16);
mpz_init_set_ui(G->generator, g);
mpz_init(G->order);
mpz_sub_ui(G->order, G->modulo, 1);
return &res->super;
if (!primitive)
mpz_fdiv_q_2exp(G->order, G->order, 1);
return G;
}
struct abstract_group *
/* The group diffie-hellman-group1-sha1, also "Well known group 2" in
RFC 2412. */
const struct zn_group *
make_ssh_group1(void)
{
struct abstract_group *G;
mpz_t p;
mpz_t g;
mpz_t order;
/* Prime and generator as defined in
* draft-ietf-secsh-transport-07.txt. */
mpz_init_set_str(p,
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
"FFFFFFFFFFFFFFFF", 16);
mpz_init_set(order, p);
mpz_sub_ui(order, order, 1);
mpz_fdiv_q_2exp(order, order, 1);
mpz_init_set_ui(g, 2);
G = make_group_zn(p, g, order);
mpz_clear(p);
mpz_clear(g);
mpz_clear(order);
/* 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */
return make_ssh_group("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
"FFFFFFFFFFFFFFFF", 2, 0);
}
return G;
/* The group diffie-hellman-group14-sha1, also "Well known group 14" in
RFC 3526. */
const struct zn_group *
make_ssh_group14(void)
{
/* 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } */
return make_ssh_group("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
"15728E5A8AACAA68FFFFFFFFFFFFFFFF", 2, 0);
}
struct abstract_group *
const struct zn_group *
make_ssh_ring_srp_1(void)
{
struct abstract_group *G;
mpz_t p;
mpz_t g;
/* Same prime as in draft-ietf-secsh-transport-07.txt, but a
* different generator. */
mpz_init_set_str(p,
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
"FFFFFFFFFFFFFFFF", 16);
/* 5 is a primitive root */
mpz_init_set_ui(g, 5);
G = make_ring_zn(p, g);
mpz_clear(p);
mpz_clear(g);
return G;
/* Same prime as in diffie-hellman-group1-sha1, but use the
primitive root 5 as the generator. */
return make_ssh_group("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
"FFFFFFFFFFFFFFFF", 5, 1);
}
......@@ -48,72 +48,48 @@ make_keypair(uint32_t type,
struct signer *private);
/* Groups. For now, assume that all group elements are represented by
* bignums. */
/* Groups. All group elements are represented by bignums. */
/* GABA:
(class
(name abstract_group)
(name zn_group)
(vars
(order bignum)
(modulo bignum)
(generator bignum)
; Checks if a bignum is in the correct range for being a group element.
(range method int "mpz_t x")
;; (member method int "mpz_t x")
(invert method void "mpz_t res" "mpz_t x")
(combine method void "mpz_t res" "mpz_t a" "mpz_t b")
; This provides operations G x G -> G that is unrelated to the
; group operation above. It is needed by SRP. For the group Z/n,
; it can simply be ring addition and subtraction.
; The operations may fail (for instance if the result is
; zero, which is not a member of the multiplicative group). In
; that case, the method returns zero.
(add method int "mpz_t res" "mpz_t a" "mpz_t b")
(subtract method int "mpz_t res" "mpz_t a" "mpz_t b")
; NOTE: Doesn't handle negative exponents
(power method void "mpz_t res" "mpz_t g" "mpz_t e")
(small_power method void "mpz_t res" "mpz_t g" "uint32_t e"))) */
#define GROUP_RANGE(group, x) ((group)->range((group), (x)))
#define GROUP_INVERT(group, res, x) ((group)->invert((group), (res), (x)))
#define GROUP_COMBINE(group, res, a, b) \
((group)->combine((group), (res), (a), (b)))
#define GROUP_POWER(group, res, g, e) \
((group)->power((group), (res), (g), (e)))
#define GROUP_SMALL_POWER(group, res, g, e) \
((group)->small_power((group), (res), (g), (e)))
#define GROUP_ADD(group, res, a, b) \
((group)->add((group), (res), (a), (b)))
#define GROUP_SUBTRACT(group, res, a, b) \
((group)->subtract((group), (res), (a), (b)))
struct abstract_group *
make_group_zn(mpz_t p, mpz_t g, mpz_t order);
struct abstract_group *
make_ring_zn(mpz_t p, mpz_t g);
/* NOTE: The object system is not powerful enough for a proper ring
* class, as we would like
*
* abstract_ring inherits abstract_group,
* group_zn inherits abstract_group
* ring_zn inherits abstract_ring, group_zn
*
* and we don't have multiple inheritance.
*/
(order bignum)))
*/
int
zn_range(const struct zn_group *G, const mpz_t x);
void
zn_invert(const struct zn_group *G, mpz_t res, const mpz_t x);
void
zn_mul(const struct zn_group *G, mpz_t res, const mpz_t x, const mpz_t y);
void
zn_exp(const struct zn_group *G, mpz_t res, const mpz_t x, const mpz_t e);
void
zn_exp_ui(const struct zn_group *G, mpz_t res, const mpz_t x, uint32_t e);
struct abstract_group *
/* Ring structure needed by SRP */
int
zn_add(const struct zn_group *G,
mpz_t res, const mpz_t a, const mpz_t b);
int
zn_sub(const struct zn_group *G,
mpz_t res, const mpz_t a, const mpz_t b);
const struct zn_group *
make_ssh_group1(void);
struct abstract_group *
const struct zn_group *
make_ssh_group14(void);
const struct zn_group *
make_ssh_ring_srp_1(void);
/* DH key exchange, with authentication */
......@@ -121,7 +97,7 @@ make_ssh_ring_srp_1(void);
(class
(name dh_method)
(vars
(G object abstract_group)
(G const object zn_group)
(H const object hash_algorithm)
(random object randomness)))
*/
......@@ -132,7 +108,7 @@ make_ssh_ring_srp_1(void);
(struct
(name dh_instance)
(vars
(method object dh_method)
(method const object dh_method)
(e bignum) ; Client value
(f bignum) ; Server value
......@@ -182,14 +158,14 @@ dh_verify_server_msg(struct dh_instance *self,
struct verifier *v);
void
dh_generate_secret(struct dh_method *self,
dh_generate_secret(const struct dh_method *self,
mpz_t r, mpz_t v);
void
dh_hash_digest(struct dh_instance *self);
struct dh_method *
make_dh(struct abstract_group *G,
make_dh(const struct zn_group *G,
const struct hash_algorithm *H,
struct randomness *r);
......@@ -197,7 +173,7 @@ struct dh_method *
make_dh1(struct randomness *r);
void
init_dh_instance(struct dh_method *m,
init_dh_instance(const struct dh_method *m,
struct dh_instance *self,
struct ssh_connection *c);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment