3e93c4 | 2004-02-07 | Martin Nilsson | |
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
3e93c4 | 2004-02-07 | Martin Nilsson | | #pike __REAL_VERSION__
#pragma strict_types
|
e1fb09 | 2014-02-14 | Martin Nilsson | | #require constant(Crypto.Hash)
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
9104d0 | 2014-01-13 | Henrik Grubbström (Grubba) | | inherit Crypto.Sign;
|
119b8d | 2014-08-14 | Henrik Grubbström (Grubba) | |
string(8bit) name() { return "DSA"; }
class State {
inherit ::this_program;
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | protected string _sprintf(int t)
{
return t=='O' && sprintf("%O(%d,%d)", this_program, p->size(), q->size());
}
|
53d1d3 | 2014-04-26 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
010f93 | 2021-04-21 | Henrik Grubbström (Grubba) | | protected Gmp.mpz|zero p;
protected Gmp.mpz|zero q;
protected Gmp.mpz|zero g;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
010f93 | 2021-04-21 | Henrik Grubbström (Grubba) | | protected Gmp.mpz|zero y;
protected Gmp.mpz|zero x;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
e6ceba | 2016-03-14 | Martin Nilsson | | protected function(int(0..):string(8bit)) random = random_string;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
010f93 | 2021-04-21 | Henrik Grubbström (Grubba) | | Gmp.mpz|zero get_p() { return p; }
Gmp.mpz|zero get_q() { return q; }
Gmp.mpz|zero get_g() { return g; }
Gmp.mpz|zero get_y() { return y; }
Gmp.mpz|zero get_x() { return x; }
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
e6ceba | 2016-03-14 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | this_program set_random(function(int(0..):string(8bit)) r)
{
random = r;
return this;
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
string(8bit) name() { return "DSA"; }
this_program set_public_key(Gmp.mpz modulo, Gmp.mpz order,
Gmp.mpz generator, Gmp.mpz key)
{
p = modulo;
q = order;
g = generator;
y = key;
return this;
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
a85906 | 2015-06-02 | Henrik Grubbström (Grubba) | |
|
bbf70b | 2016-10-19 | Henrik Grubbström (Grubba) | | variant this_program set_public_key(.DH.Parameters params,
|
14c29c | 2015-06-04 | Henrik Grubbström (Grubba) | | Gmp.mpz key)
|
a85906 | 2015-06-02 | Henrik Grubbström (Grubba) | | {
p = params->p;
q = params->q;
g = params->g;
y = key;
return this;
}
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
int(0..1) public_key_equal(this_program dsa)
{
return (p == dsa->get_p()) && (q == dsa->get_q()) &&
(g == dsa->get_g()) && (y == dsa->get_y());
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
protected int(0..1) _equal(mixed other)
{
if (!objectp(other) || (object_program(other) != object_program(this)) ||
!public_key_equal([object(this_program)]other)) {
return 0;
}
this_program dsa = [object(this_program)]other;
return x == dsa->get_x();
|
7c383a | 2014-02-22 | Henrik Grubbström (Grubba) | | }
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
this_program set_private_key(Gmp.mpz secret)
{
x = secret;
return this;
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
3f6dd0 | 2013-12-02 | Martin Nilsson | | #if !constant(Nettle.dsa_generate_keypair)
|
3e93c4 | 2004-02-07 | Martin Nilsson | | #define SEED_LENGTH 20
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | protected string(8bit) nist_hash(Gmp.mpz x)
{
string(8bit) s = x->digits(256);
return .SHA1.hash(s[sizeof(s) - SEED_LENGTH..]);
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
protected array(Gmp.mpz) nist_primes(int l)
{
if ( (l < 0) || (l > 8) )
error( "Unsupported key size.\n" );
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | int L = 512 + 64 * l;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | int n = (L-1) / 160;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | for (;;)
{
string(8bit) seed = random(SEED_LENGTH);
Gmp.mpz s = Gmp.mpz(seed, 256);
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | string(8bit) h = [string(8bit)]
(nist_hash(s) ^ nist_hash( [object(Gmp.mpz)](s + 1) ));
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
5490bd | 2015-04-28 | Henrik Grubbström (Grubba) | | h = sprintf("%c%s%c",
[int(8bit)](h[0] | 0x80),
h[1..<1],
[int(8bit)](h[-1] | 1));
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | Gmp.mpz q = Gmp.mpz(h, 256);
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | if (!q->probably_prime_p())
continue;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | int i, j;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | for (i = 0, j = 2; i < 4096; i++, j += n+1)
{
string(8bit) buffer = "";
int k;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | for (k = 0; k<= n; k++)
buffer = nist_hash( [object(Gmp.mpz)](s + j + k) ) + buffer;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | buffer = buffer[sizeof(buffer) - L/8 ..];
buffer[0] = [int(8bit)](buffer[0] | 0x80);
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | Gmp.mpz p = Gmp.mpz(buffer, 256);
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | p -= p % (2 * q) - 1;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | if (p->probably_prime_p())
{
return ({ p, q });
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | | }
}
}
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | protected Gmp.mpz find_generator(Gmp.mpz p, Gmp.mpz q)
|
3e93c4 | 2004-02-07 | Martin Nilsson | | {
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | Gmp.mpz e = [object(Gmp.mpz)]((p - 1) / q);
Gmp.mpz g;
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | do {
g = ([object(Gmp.mpz)](random_number( [object(Gmp.mpz)](p-3) ) + 2))
->powm(e, p);
} while (g == 1);
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | return g;
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
protected void generate_parameters(int bits)
{
if (!bits || bits % 64)
error( "Unsupported key size.\n" );
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | [p, q] = nist_primes(bits / 64 - 8);
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | if (p % q != 1)
error( "Internal error.\n" );
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | if (q->size() != 160)
error( "Internal error.\n" );
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | g = find_generator(p, q);
|
3f6dd0 | 2013-12-02 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | if ( (g == 1) || (g->powm(q, p) != 1))
error( "Internal error.\n" );
}
variant this_program generate_key(int p_bits, int q_bits)
{
if(q_bits!=160)
error("Only 1024/160 supported with Nettle version < 2.0\n");
generate_parameters(1024);
return generate_key();
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
3f6dd0 | 2013-12-02 | Martin Nilsson | | #else // !constant(Nettle.dsa_generate_keypair)
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
variant this_program generate_key(int p_bits, int q_bits)
{
[ p, q, g, y, x ] = Nettle.dsa_generate_keypair(p_bits, q_bits, random);
return this;
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
3f6dd0 | 2013-12-02 | Martin Nilsson | | #endif
|
a85906 | 2015-06-02 | Henrik Grubbström (Grubba) | |
|
bbf70b | 2016-10-19 | Henrik Grubbström (Grubba) | | variant this_program generate_key(.DH.Parameters params)
|
a85906 | 2015-06-02 | Henrik Grubbström (Grubba) | | {
p = params->p;
g = params->g;
q = params->q;
[y, x] = params->generate_keypair(random);
return this;
}
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
a85906 | 2015-06-02 | Henrik Grubbström (Grubba) | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | variant this_program generate_key()
{
if(!p || !q || !g) error("Public parameters not set..\n");
x = [object(Gmp.mpz)](random_number( [object(Gmp.mpz)](q-2) ) + 2);
y = g->powm(x, p);
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | return this;
}
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
3f6dd0 | 2013-12-02 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
#define Sequence Standards.ASN1.Types.Sequence
|
a2a39b | 2014-01-11 | Henrik Grubbström (Grubba) | | #define Integer Standards.ASN1.Types.Integer
#define BitString Standards.ASN1.Types.BitString
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
0c4ea5 | 2015-08-22 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | Sequence pkcs_algorithm_identifier()
{
return
Sequence( ({ Standards.PKCS.Identifiers.dsa_id,
Sequence( ({ Integer(get_p()),
Integer(get_q()),
Integer(get_g())
}) )
}) );
}
|
a2a39b | 2014-01-11 | Henrik Grubbström (Grubba) | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
74664e | 2022-06-02 | Martin Nilsson | | object(Sequence)|zero pkcs_signature_algorithm_id(.Hash hash)
|
a2a39b | 2014-01-11 | Henrik Grubbström (Grubba) | | {
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | switch(hash->name())
{
case "sha1":
return Sequence( ({ Standards.PKCS.Identifiers.dsa_sha_id }) );
break;
case "sha224":
return Sequence( ({ Standards.PKCS.Identifiers.dsa_sha224_id }) );
break;
case "sha256":
return Sequence( ({ Standards.PKCS.Identifiers.dsa_sha256_id }) );
break;
}
return 0;
|
a2a39b | 2014-01-11 | Henrik Grubbström (Grubba) | | }
|
3e93c4 | 2004-02-07 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
0c4ea5 | 2015-08-22 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | Sequence pkcs_public_key()
{
return Sequence(({
pkcs_algorithm_identifier(),
BitString(Integer(get_y())->get_der()),
}));
}
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
a2a39b | 2014-01-11 | Henrik Grubbström (Grubba) | | #undef BitString
#undef Integer
|
b3e4a0 | 2013-10-28 | Martin Nilsson | | #undef Sequence
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
string(8bit) pkcs_sign(string(8bit) message, .Hash h)
{
array sign = map(raw_sign(hash(message, h)), Standards.ASN1.Types.Integer);
return Standards.ASN1.Types.Sequence(sign)->get_der();
}
|
ee804c | 2013-11-21 | Martin Nilsson | |
|
873c99 | 2014-12-23 | Henrik Grubbström (Grubba) | |
|
ee804c | 2013-11-21 | Martin Nilsson | | #define Object Standards.ASN1.Types.Object
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
int(0..1) pkcs_verify(string(8bit) message, .Hash h, string(8bit) sign)
{
|
813c67 | 2022-06-04 | Martin Nilsson | | object(Object)|zero a = Standards.ASN1.Decode.secure_der_decode(sign);
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
if (!a
|| (a->type_name != "SEQUENCE")
|| (sizeof([array]a->elements) != 2)
|| (sizeof( ([array(object(Object))]a->elements)->type_name -
({ "INTEGER" }))))
return 0;
return raw_verify(hash(message, h),
[object(Gmp.mpz)]([array(object(Object))]a->elements)[0]->
|
ee804c | 2013-11-21 | Martin Nilsson | | value,
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | [object(Gmp.mpz)]([array(object(Object))]a->elements)[1]->
|
ee804c | 2013-11-21 | Martin Nilsson | | value);
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | }
|
ee804c | 2013-11-21 | Martin Nilsson | |
#undef Object
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
931d44 | 2021-05-27 | Henrik Grubbström (Grubba) | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | Gmp.mpz hash(string(8bit) msg, .Hash h)
{
string(8bit) digest = h->hash(msg)[..q->size()/8-1];
return [object(Gmp.mpz)](Gmp.mpz(digest, 256) % q);
}
|
352471 | 2015-05-26 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | protected Gmp.mpz random_number(Gmp.mpz n)
{
return [object(Gmp.mpz)](Gmp.mpz(random( [int(0..)](q->size() + 10 / 8)),
256) % n);
}
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | protected Gmp.mpz random_exponent()
{
return [object(Gmp.mpz)](random_number([object(Gmp.mpz)](q - 1)) + 1);
}
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
array(Gmp.mpz) raw_sign(Gmp.mpz h, void|Gmp.mpz k)
{
if(!k) k = random_exponent();
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | Gmp.mpz r = [object(Gmp.mpz)](g->powm(k, p) % q);
|
cdec8c | 2021-11-06 | Henrik Grubbström (Grubba) | | Gmp.mpz s = [object(Gmp.mpz)]((k->invert(q) * (h + [object(Gmp.mpz)](x*r))) % q);
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | return ({ r, s });
}
int(0..1) raw_verify(Gmp.mpz h, Gmp.mpz r, Gmp.mpz s)
{
|
48e769 | 2022-08-28 | Henrik Grubbström (Grubba) | | if ((r > q) || (s > q)) {
return 0;
}
|
c43f04 | 2022-02-09 | Henrik Grubbström (Grubba) | | object(Gmp.mpz)|zero w;
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | if (catch
|
b3e4a0 | 2013-10-28 | Martin Nilsson | | {
w = s->invert(q);
})
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
return 0;
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | |
return r == (g->powm( [object(Gmp.mpz)](w * h % q), p) *
y->powm( [object(Gmp.mpz)](w * r % q), p) % p) % q;
}
|
b3e4a0 | 2013-10-28 | Martin Nilsson | |
|
493402 | 2014-08-14 | Henrik Grubbström (Grubba) | | int(0..) key_size()
{
return p->size();
}
|
119b8d | 2014-08-14 | Henrik Grubbström (Grubba) | | }
protected State `()()
{
return State();
}
|