+2014-01-04 Niels Möller <nisse@lysator.liu.se>
+
+ * testsuite/testutils.c (test_dsa_sign): #if:ed out, unused.
+ (test_dsa_verify): Use _dsa_verify.
+
+ * dsa-verify.c (_dsa_verify): New function, with a struct
+ dsa_params * as a separate argument.
+ (dsa_verify): Use _dsa_verify.
+ * dsa-sha1-verify.c (dsa_sha1_verify_digest, dsa_sha1_verify): Use
+ _dsa_verify.
+ * dsa-sha256-verify.c (dsa_sha256_verify_digest)
+ (dsa_sha256_verify): Likewise.
+
+ * dsa-sign.c (_dsa_sign): New function, with struct dsa_params *
+ as a separate argument.
+ (dsa_sign): Use _dsa_sign.
+ * dsa-sha1-sign.c (dsa_sha1_sign_digest, dsa_sha1_sign): Use
+ _dsa_sign, cast the struct dsa_public_key * input to a struct
+ dsa_params *.
+ * dsa-sha256-sign.c (dsa_sha256_sign_digest, dsa_sha256_sign):
+ Likewise.
+
+ * dsa.c (dsa_params_init, dsa_params_clear): New functions.
+ (dsa_value_init, dsa_value_clear): New functions.
+ (dsa_public_key_init): Use dsa_params_init.
+ (dsa_public_key_clear): Use dsa_params_clear.
+
+ * dsa.h (dsa_params, dsa_value): New structs.
+
2014-01-03 Niels Möller <nisse@lysator.liu.se>
* shadata.c (main): Zero-pad output values to 8 hex digits.
const uint8_t *digest,
struct dsa_signature *signature)
{
- return dsa_sign(pub, key, random_ctx, random,
- SHA1_DIGEST_SIZE, digest, signature);
+ return _dsa_sign((const struct dsa_params *) pub, key->x,
+ random_ctx, random,
+ SHA1_DIGEST_SIZE, digest, signature);
}
{
uint8_t digest[SHA1_DIGEST_SIZE];
sha1_digest(hash, sizeof(digest), digest);
-
- return dsa_sign(pub, key, random_ctx, random,
- sizeof(digest), digest, signature);
+
+ return _dsa_sign((const struct dsa_params *) pub, key->x,
+ random_ctx, random,
+ sizeof(digest), digest, signature);
}
const uint8_t *digest,
const struct dsa_signature *signature)
{
- return dsa_verify(key, SHA1_DIGEST_SIZE, digest, signature);
+ return _dsa_verify((const struct dsa_params *) key, key->y,
+ SHA1_DIGEST_SIZE, digest, signature);
}
int
uint8_t digest[SHA1_DIGEST_SIZE];
sha1_digest(hash, sizeof(digest), digest);
- return dsa_verify(key, sizeof(digest), digest, signature);
+ return _dsa_verify((const struct dsa_params *) key, key->y,
+ sizeof(digest), digest, signature);
}
const uint8_t *digest,
struct dsa_signature *signature)
{
- return dsa_sign(pub, key, random_ctx, random,
- SHA256_DIGEST_SIZE, digest, signature);
+ return _dsa_sign((const struct dsa_params *) pub, key->x,
+ random_ctx, random,
+ SHA256_DIGEST_SIZE, digest, signature);
}
int
uint8_t digest[SHA256_DIGEST_SIZE];
sha256_digest(hash, sizeof(digest), digest);
- return dsa_sign(pub, key, random_ctx, random,
- sizeof(digest), digest, signature);
+ return _dsa_sign((const struct dsa_params *) pub, key->x,
+ random_ctx, random,
+ sizeof(digest), digest, signature);
}
const uint8_t *digest,
const struct dsa_signature *signature)
{
- return dsa_verify(key, SHA256_DIGEST_SIZE, digest, signature);
+ return _dsa_verify((const struct dsa_params *) key, key->y,
+ SHA256_DIGEST_SIZE, digest, signature);
}
int
uint8_t digest[SHA256_DIGEST_SIZE];
sha256_digest(hash, sizeof(digest), digest);
- return dsa_verify(key, sizeof(digest), digest, signature);
+ return _dsa_verify((const struct dsa_params *) key, key->y,
+ sizeof(digest), digest, signature);
}
int
-dsa_sign(const struct dsa_public_key *pub,
- const struct dsa_private_key *key,
- void *random_ctx, nettle_random_func *random,
- size_t digest_size,
- const uint8_t *digest,
- struct dsa_signature *signature)
+_dsa_sign(const struct dsa_params *params,
+ const mpz_t key,
+ void *random_ctx, nettle_random_func *random,
+ size_t digest_size,
+ const uint8_t *digest,
+ struct dsa_signature *signature)
{
mpz_t k;
mpz_t h;
int res;
/* Select k, 0<k<q, randomly */
- mpz_init_set(tmp, pub->q);
+ mpz_init_set(tmp, params->q);
mpz_sub_ui(tmp, tmp, 1);
mpz_init(k);
mpz_add_ui(k, k, 1);
/* Compute r = (g^k (mod p)) (mod q) */
- mpz_powm(tmp, pub->g, k, pub->p);
- mpz_fdiv_r(signature->r, tmp, pub->q);
+ mpz_powm(tmp, params->g, k, params->p);
+ mpz_fdiv_r(signature->r, tmp, params->q);
/* Compute hash */
mpz_init(h);
- _dsa_hash (h, mpz_sizeinbase(pub->q, 2), digest_size, digest);
+ _dsa_hash (h, mpz_sizeinbase(params->q, 2), digest_size, digest);
/* Compute k^-1 (mod q) */
- if (mpz_invert(k, k, pub->q))
+ if (mpz_invert(k, k, params->q))
{
/* Compute signature s = k^-1 (h + xr) (mod q) */
- mpz_mul(tmp, signature->r, key->x);
- mpz_fdiv_r(tmp, tmp, pub->q);
+ mpz_mul(tmp, signature->r, key);
+ mpz_fdiv_r(tmp, tmp, params->q);
mpz_add(tmp, tmp, h);
mpz_mul(tmp, tmp, k);
- mpz_fdiv_r(signature->s, tmp, pub->q);
+ mpz_fdiv_r(signature->s, tmp, params->q);
res = 1;
}
else
return res;
}
+
+int
+dsa_sign(const struct dsa_value *key,
+ void *random_ctx, nettle_random_func *random,
+ size_t digest_size,
+ const uint8_t *digest,
+ struct dsa_signature *signature)
+{
+ return _dsa_sign (key->params, key->x,
+ random_ctx, random,
+ digest_size, digest, signature);
+}
#include "bignum.h"
int
-dsa_verify(const struct dsa_public_key *key,
+_dsa_verify(const struct dsa_params *params,
+ const mpz_t key,
size_t digest_size,
const uint8_t *digest,
const struct dsa_signature *signature)
int res;
/* Check that r and s are in the proper range */
- if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, key->q) >= 0)
+ if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, params->q) >= 0)
return 0;
- if (mpz_sgn(signature->s) <= 0 || mpz_cmp(signature->s, key->q) >= 0)
+ if (mpz_sgn(signature->s) <= 0 || mpz_cmp(signature->s, params->q) >= 0)
return 0;
mpz_init(w);
/* NOTE: In gmp-2, mpz_invert sometimes generates negative inverses,
* so we need gmp-3 or better. */
- if (!mpz_invert(w, signature->s, key->q))
+ if (!mpz_invert(w, signature->s, params->q))
{
mpz_clear(w);
return 0;
mpz_init(v);
/* The message digest */
- _dsa_hash (tmp, mpz_sizeinbase (key->q, 2), digest_size, digest);
+ _dsa_hash (tmp, mpz_sizeinbase (params->q, 2), digest_size, digest);
/* v = g^{w * h (mod q)} (mod p) */
mpz_mul(tmp, tmp, w);
- mpz_fdiv_r(tmp, tmp, key->q);
+ mpz_fdiv_r(tmp, tmp, params->q);
- mpz_powm(v, key->g, tmp, key->p);
+ mpz_powm(v, params->g, tmp, params->p);
/* y^{w * r (mod q) } (mod p) */
mpz_mul(tmp, signature->r, w);
- mpz_fdiv_r(tmp, tmp, key->q);
+ mpz_fdiv_r(tmp, tmp, params->q);
- mpz_powm(tmp, key->y, tmp, key->p);
+ mpz_powm(tmp, key, tmp, params->p);
/* v = (g^{w * h} * y^{w * r} (mod p) ) (mod q) */
mpz_mul(v, v, tmp);
- mpz_fdiv_r(v, v, key->p);
+ mpz_fdiv_r(v, v, params->p);
- mpz_fdiv_r(v, v, key->q);
+ mpz_fdiv_r(v, v, params->q);
res = !mpz_cmp(v, signature->r);
return res;
}
+
+int
+dsa_verify(const struct dsa_value *pub,
+ size_t digest_size,
+ const uint8_t *digest,
+ const struct dsa_signature *signature)
+{
+ return _dsa_verify (pub->params, pub->x,
+ digest_size, digest,
+ signature);
+}
#include "bignum.h"
+void
+dsa_params_init (struct dsa_params *params)
+{
+ mpz_init(params->p);
+ mpz_init(params->q);
+ mpz_init(params->g);
+}
+
+void
+dsa_params_clear (struct dsa_params *params)
+{
+ mpz_clear(params->p);
+ mpz_clear(params->q);
+ mpz_clear(params->g);
+}
+
+void
+dsa_value_init (struct dsa_value *value, const struct dsa_params *params)
+{
+ value->params = params;
+ mpz_init (value->x);
+}
+
+void
+dsa_value_clear (struct dsa_value *value)
+{
+ mpz_clear (value->x);
+}
+
void
dsa_public_key_init(struct dsa_public_key *key)
{
- mpz_init(key->p);
- mpz_init(key->q);
- mpz_init(key->g);
+ dsa_params_init ((struct dsa_params *) key);
mpz_init(key->y);
}
void
dsa_public_key_clear(struct dsa_public_key *key)
{
- mpz_clear(key->p);
- mpz_clear(key->q);
- mpz_clear(key->g);
+ dsa_params_clear ((struct dsa_params *) key);
mpz_clear(key->y);
}
#endif
/* Name mangling */
+#define dsa_params_init nettle_dsa_params_init
+#define dsa_params_clear nettle_dsa_params_clear
+#define dsa_value_init nettle_dsa_value_init
+#define dsa_value_clear nettle_dsa_value_clear
#define dsa_public_key_init nettle_dsa_public_key_init
#define dsa_public_key_clear nettle_dsa_public_key_clear
#define dsa_private_key_init nettle_dsa_private_key_init
#define dsa_sha256_verify nettle_dsa_sha256_verify
#define dsa_sign nettle_dsa_sign
#define dsa_verify nettle_dsa_verify
+#define _dsa_sign _nettle_dsa_sign
+#define _dsa_verify _nettle_dsa_verify
#define dsa_sha1_sign_digest nettle_dsa_sha1_sign_digest
#define dsa_sha1_verify_digest nettle_dsa_sha1_verify_digest
#define dsa_sha256_sign_digest nettle_dsa_sha256_sign_digest
#define dsa_openssl_private_key_from_der nettle_openssl_provate_key_from_der
#define _dsa_hash _nettle_dsa_hash
+/* For FIPS approved parameters */
#define DSA_SHA1_MIN_P_BITS 512
#define DSA_SHA1_Q_OCTETS 20
#define DSA_SHA1_Q_BITS 160
#define DSA_SHA256_MIN_P_BITS 1024
#define DSA_SHA256_Q_OCTETS 32
#define DSA_SHA256_Q_BITS 256
-
-struct dsa_public_key
+
+/* Tentative new DSA interface */
+struct dsa_params
{
/* Modulo */
mpz_t p;
/* Generator */
mpz_t g;
+};
+
+struct dsa_signature
+{
+ mpz_t r;
+ mpz_t s;
+};
+
+struct dsa_value
+{
+ const struct dsa_params *params;
+ /* For private keys, represents an exponent (0 < x < q). For public
+ keys, represents a group element, 0 < x < p) */
+ mpz_t x;
+};
+
+void
+dsa_params_init (struct dsa_params *params);
+
+void
+dsa_params_clear (struct dsa_params *params);
+
+void
+dsa_value_init (struct dsa_value *value, const struct dsa_params *params);
+
+void
+dsa_value_clear (struct dsa_value *value);
+
+/* Calls mpz_init to initialize bignum storage. */
+void
+dsa_signature_init(struct dsa_signature *signature);
+
+/* Calls mpz_clear to deallocate bignum storage. */
+void
+dsa_signature_clear(struct dsa_signature *signature);
+
+int
+dsa_sign(const struct dsa_value *key,
+ void *random_ctx, nettle_random_func *random,
+ size_t digest_size,
+ const uint8_t *digest,
+ struct dsa_signature *signature);
+
+int
+dsa_verify(const struct dsa_value *pub,
+ size_t digest_size,
+ const uint8_t *digest,
+ const struct dsa_signature *signature);
+
+void
+dsa_generate_params (struct dsa_params *params,
+
+ void *random_ctx, nettle_random_func *random,
+
+ void *progress_ctx, nettle_progress_func *progress,
+ unsigned p_bits, unsigned q_bits);
+
+#if 0
+int
+dsa_generate_keypair (struct dsa_value *pub,
+ struct dsa_value *key,
+
+ void *random_ctx, nettle_random_func *random);
+#endif
+
+/* Old nettle interface, kept for backwards compatibility */
+struct dsa_public_key
+{
+ /* Same as struct dsa_params, but can't use that struct here without
+ breaking backwards compatibility. Layout must be identical, since
+ this is cast to a struct dsa_param pointer for calling _dsa_sign
+ and _dsa_verify */
+ mpz_t p;
+ mpz_t q;
+ mpz_t g;
+
/* Public value */
mpz_t y;
};
mpz_t x;
};
-struct dsa_signature
-{
- mpz_t r;
- mpz_t s;
-};
-
/* Signing a message works as follows:
*
* Store the private key in a dsa_private_key struct.
void
dsa_private_key_clear(struct dsa_private_key *key);
-/* Calls mpz_init to initialize bignum storage. */
-void
-dsa_signature_init(struct dsa_signature *signature);
-
-/* Calls mpz_clear to deallocate bignum storage. */
-void
-dsa_signature_clear(struct dsa_signature *signature);
-
-
int
dsa_sha1_sign(const struct dsa_public_key *pub,
const struct dsa_private_key *key,
const struct dsa_signature *signature);
int
-dsa_sign(const struct dsa_public_key *pub,
- const struct dsa_private_key *key,
- void *random_ctx, nettle_random_func *random,
- size_t digest_size,
- const uint8_t *digest,
- struct dsa_signature *signature);
-
-int
-dsa_verify(const struct dsa_public_key *key,
- size_t digest_size,
- const uint8_t *digest,
- const struct dsa_signature *signature);
-
-/* Maybe obsolete these functions? One can just as well call dsa_sign
- and dsa_verify directly, all that matters is the digest size. */
-int
dsa_sha1_sign_digest(const struct dsa_public_key *pub,
const struct dsa_private_key *key,
void *random_ctx, nettle_random_func *random,
_dsa_hash (mpz_t h, unsigned bit_size,
size_t length, const uint8_t *digest);
+int
+_dsa_sign(const struct dsa_params *params,
+ const mpz_t key,
+ void *random_ctx, nettle_random_func *random,
+ size_t digest_size,
+ const uint8_t *digest,
+ struct dsa_signature *signature);
+
+int
+_dsa_verify(const struct dsa_params *params,
+ const mpz_t pub,
+ size_t digest_size,
+ const uint8_t *digest,
+ const struct dsa_signature *signature);
+
#ifdef __cplusplus
}
#endif
dsa_signature_clear(&signature);
}
+#if 0
void
test_dsa_sign(const struct dsa_public_key *pub,
const struct dsa_private_key *key,
free (bad_digest);
dsa_signature_clear(&signature);
}
+#endif
void
test_dsa_verify(const struct dsa_public_key *pub,
mpz_set (signature.r, ref->r);
mpz_set (signature.s, ref->s);
- ASSERT (dsa_verify (pub, hash->digest_size, digest,
- &signature));
+ ASSERT (_dsa_verify ((struct dsa_params *) pub, pub->y,
+ hash->digest_size, digest,
+ &signature));
/* Try bad signature */
mpz_combit(signature.r, 17);
- ASSERT (!dsa_verify (pub, hash->digest_size, digest,
- &signature));
+ ASSERT (!_dsa_verify ((struct dsa_params *) pub, pub->y,
+ hash->digest_size, digest,
+ &signature));
/* Try bad data */
digest[hash->digest_size / 2-1] ^= 8;
- ASSERT (!dsa_verify (pub, hash->digest_size, digest,
- ref));
+ ASSERT (!_dsa_verify ((struct dsa_params *) pub, pub->y,
+ hash->digest_size, digest,
+ ref));
free (ctx);
free (digest);