d5f689 | 2013-11-24 | Martin Nilsson | | /* -*- c -*-
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
*/
#include "global.h"
#include "builtin_functions.h"
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | #include "operators.h"
|
d5f689 | 2013-11-24 | Martin Nilsson | | #include "interpret.h"
#include "module.h"
#include "nettle_config.h"
#ifdef HAVE_LIBHOGWEED
DECLARATIONS
#include "nettle.h"
#include <nettle/dsa.h>
#include <nettle/rsa.h>
#include <gmp.h>
|
2b1c92 | 2013-12-24 | Henrik Grubbström (Grubba) | | #include "bignum.h"
|
877f41 | 2014-01-04 | Henrik Grubbström (Grubba) | | /*! @module Nettle
*/
|
b4d96f | 2014-10-24 | Arne Goedeke | | static void random_func_wrapper(void *f, pike_nettle_size_t num, uint8_t *out)
|
d5f689 | 2013-11-24 | Martin Nilsson | | {
push_int(num);
apply_svalue((struct svalue *)f, 1);
if(TYPEOF(Pike_sp[-1])!=T_STRING)
Pike_error("Random function did not return string value.\n");
|
6ddd9d | 2014-11-05 | Martin Nilsson | | if((unsigned)Pike_sp[-1].u.string->len != (unsigned)num)
|
d5f689 | 2013-11-24 | Martin Nilsson | | Pike_error("Random function did not return correct number of bytes.\n");
memcpy(out, Pike_sp[-1].u.string->str, num);
pop_stack();
}
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl array(object(Gmp.mpz)) @
*! dsa_generate_keypair(int p_bits, int q_bits, @
|
b43231 | 2014-04-06 | Martin Nilsson | | *! function(int(0..):string(0..255)) rnd)
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *!
*! Generates a DSA key pair with @[p_bits] number of bits (sometimes
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! referred to as L) for p, and @[q_bits] number of bits (sometimes
*! referred to as N) for q, using the random function @[rnd].
*!
*! Valid combinations as per FIPS 186-3 are
*! @pre{
*! p_bits q_bits
*! 1024 160
|
230ae0 | 2013-11-25 | Martin Nilsson | | *! 2048 224 (rejected by some versions of Hogweed)
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! 2048 256
*! 3072 256
*! @}
*!
*! @returns
*! @array
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 0
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value p, the modulo.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 1
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value q, the group order.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 2
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value g, the generator.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 3
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value y, the public value.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 4
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value x, the private value.
*! @endarray
*/
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN array(object(Gmp.mpz))
|
b43231 | 2014-04-06 | Martin Nilsson | | dsa_generate_keypair(int p_bits, int q_bits, function(int(0..):string(0..255)) rnd)
|
d5f689 | 2013-11-24 | Martin Nilsson | | {
|
c17a99 | 2014-04-24 | Henrik Grubbström (Grubba) | | #ifdef dsa_params_init
|
1cfe7f | 2014-04-17 | Henrik Grubbström (Grubba) | | /* Nettle 3.0 or later. */
struct dsa_params params;
mpz_t pub;
mpz_t key;
dsa_params_init(¶ms);
if (!dsa_generate_params(¶ms, rnd, random_func_wrapper,
NULL, NULL, p_bits, q_bits)) {
Pike_error("Illegal parameter value.\n");
}
mpz_init(pub);
mpz_init(key);
dsa_generate_keypair(¶ms, pub, key, rnd, random_func_wrapper);
push_bignum((MP_INT *)¶ms.p);
push_bignum((MP_INT *)¶ms.q);
push_bignum((MP_INT *)¶ms.g);
dsa_params_clear(¶ms);
push_bignum((MP_INT *)pub);
push_bignum((MP_INT *)key);
mpz_clear(key);
mpz_clear(pub);
#else
|
d5f689 | 2013-11-24 | Martin Nilsson | | struct dsa_public_key pub;
struct dsa_private_key key;
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | dsa_public_key_init(&pub);
dsa_private_key_init(&key);
|
d5f689 | 2013-11-24 | Martin Nilsson | |
if( !nettle_dsa_generate_keypair(&pub, &key, rnd, random_func_wrapper,
|
14150e | 2014-01-13 | Per Hedbor | | NULL, NULL, p_bits
#ifdef HAVE_DSA_QBITS_KEYPAIR_ARG
, q_bits
#endif
) )
|
d5f689 | 2013-11-24 | Martin Nilsson | | {
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | dsa_private_key_clear(&key);
dsa_public_key_clear(&pub);
|
28aa06 | 2013-12-02 | Martin Nilsson | | Pike_error("Illegal parameter value.\n");
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | push_bignum((MP_INT *)&pub.p);
push_bignum((MP_INT *)&pub.q);
push_bignum((MP_INT *)&pub.g);
push_bignum((MP_INT *)&pub.y);
push_bignum((MP_INT *)&key.x);
dsa_private_key_clear(&key);
dsa_public_key_clear(&pub);
|
c17a99 | 2014-04-24 | Henrik Grubbström (Grubba) | | #endif /* dsa_params_init */
|
d5f689 | 2013-11-24 | Martin Nilsson | |
f_aggregate(5);
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | stack_pop_n_elems_keep_top(args); /* Remove p_bits, q_bits and rnd. */
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | /*! @decl array(object(Gmp.mpz)) @
|
462436 | 2014-01-30 | Henrik Grubbström (Grubba) | | *! rsa_generate_keypair(int bits, int e, @
|
b43231 | 2014-04-06 | Martin Nilsson | | *! function(int(0..):string(0..255)) rnd)
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *!
*! Generates an RSA key pair with a @[bits] sized modulus (n), using
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! the provided value for @[e] and random function @[rnd].
*!
*! @returns
*! @array
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 0
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value n, the modulo.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 1
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value d, the private exponent.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 2
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value p, a prime.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 3
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value q, a prime.
*! @endarray
*/
PIKEFUN array(object(Gmp.mpz))
|
b43231 | 2014-04-06 | Martin Nilsson | | rsa_generate_keypair(int bits, int e, function(int(0..):string(0..255)) rnd)
|
d5f689 | 2013-11-24 | Martin Nilsson | | {
struct rsa_public_key pub;
struct rsa_private_key key;
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | |
rsa_public_key_init(&pub);
rsa_private_key_init(&key);
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | mpz_set_ui((MP_INT *)&pub.e, e);
|
d5f689 | 2013-11-24 | Martin Nilsson | |
if( !nettle_rsa_generate_keypair(&pub, &key, rnd, random_func_wrapper,
NULL, NULL, bits, 0) )
{
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | rsa_private_key_clear(&key);
rsa_public_key_clear(&pub);
|
28aa06 | 2013-12-02 | Martin Nilsson | | Pike_error("Illegal parameter value.\n");
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | push_bignum((MP_INT *)&pub.n);
push_bignum((MP_INT *)&key.d);
push_bignum((MP_INT *)&key.p);
push_bignum((MP_INT *)&key.q);
rsa_private_key_clear(&key);
rsa_public_key_clear(&pub);
|
d5f689 | 2013-11-24 | Martin Nilsson | |
f_aggregate(4);
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | stack_pop_n_elems_keep_top(args); /* Remove bits, e and rnd. */
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
c17a99 | 2014-04-24 | Henrik Grubbström (Grubba) | | #ifdef dsa_params_init
|
29b700 | 2014-04-21 | Henrik Grubbström (Grubba) | |
/*! @class DH_Params
*!
*! Diffie-Hellman Parameters.
*/
PIKECLASS DH_Params
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_CLEAR_STORAGE;
|
29b700 | 2014-04-21 | Henrik Grubbström (Grubba) | | {
CVAR struct dsa_params params;
INIT {
dsa_params_init(&THIS->params);
}
EXIT {
dsa_params_clear(&THIS->params);
}
/*! @decl Gmp.mpz p
*!
*! Prime.
*/
/*! @decl Gmp.mpz g
*!
*! Generator.
*/
/*! @decl Gmp.mpz q
*!
*! Order.
*/
PIKEFUN Gmp_mpz `p()
{
push_bignum(THIS->params.p);
}
PIKEFUN void `p=(Gmp_mpz|int p)
{
convert_svalue_to_bignum(p);
mpz_from_svalue(THIS->params.p, p);
}
PIKEFUN Gmp_mpz `g()
{
push_bignum(THIS->params.g);
}
PIKEFUN void `g=(Gmp_mpz|int g)
{
convert_svalue_to_bignum(g);
mpz_from_svalue(THIS->params.g, g);
}
PIKEFUN Gmp_mpz `q()
{
push_bignum(THIS->params.q);
}
PIKEFUN void `q=(Gmp_mpz|int q)
{
convert_svalue_to_bignum(q);
mpz_from_svalue(THIS->params.q, q);
}
/*! @decl void generate(int p_bits, int q_bits, @
*! function(int(0..):string(8bit)) rnd)
*!
*! Generate a new set of Diffie-Hellman parameters.
*!
*! @note
*! Throws errors for unsupported parameters.
*!
*! @note
*! This function is not available in all installations of Pike.
*/
PIKEFUN void generate(int p_bits, int q_bits,
function(int(0..):string(8bit)) rnd)
{
if (!dsa_generate_params(&THIS->params, rnd, random_func_wrapper,
NULL, NULL, p_bits, q_bits)) {
Pike_error("Illegal parameter value.\n");
}
pop_n_elems(args);
}
/*! @decl array(Gmp.mpz) generate_keypair(function(int(0..):string(8bit)) rnd)
*!
*! Generate a Diffie-Hellman key pair.
*!
*! @returns
*! Returns the following array:
*! @array
*! @elem Gmp.mpz 0
*! The generated public key.
|
a79716 | 2014-04-30 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 1
|
29b700 | 2014-04-21 | Henrik Grubbström (Grubba) | | *! The corresponding private key.
*! @endarray
*/
PIKEFUN array(Gmp_mpz) generate_keypair(function(int(0..):string(8bit)) rnd)
{
int psgn = mpz_sgn(THIS->params.p);
mpz_t pub;
mpz_t key;
if (!psgn) {
SIMPLE_DIVISION_BY_ZERO_ERROR("generate_keypair");
}
if (psgn < 0) {
Pike_error("The prime must be positive.\n");
}
mpz_init(pub);
mpz_init(key);
dsa_generate_keypair(&THIS->params, pub, key, rnd, random_func_wrapper);
push_bignum((MP_INT *)pub);
push_bignum((MP_INT *)key);
mpz_clear(key);
mpz_clear(pub);
f_aggregate(2);
}
}
/*! @endclass
*/
|
c17a99 | 2014-04-24 | Henrik Grubbström (Grubba) | | #endif /* dsa_params_init */
|
29b700 | 2014-04-21 | Henrik Grubbström (Grubba) | |
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_ECDSA_H
#include <nettle/ecc-curve.h>
#include <nettle/ecc.h>
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | #include <nettle/ecdsa.h>
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | /*! @class ECC_Curve
*!
*! Elliptic Curve Definition
*/
PIKECLASS ECC_Curve
{
CVAR const struct ecc_curve *curve;
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | CVAR int field_size;
|
29b700 | 2014-04-21 | Henrik Grubbström (Grubba) | | DECLARE_STORAGE;
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | /*! @decl void create(int(0..) family, int(0..) field_size, int(0..) revision)
*!
*! Initialize the curve.
*/
PIKEFUN void create(int(0..) family, int(0..) field_size, int(0..) revision)
flags ID_STATIC
{
if (THIS->curve) {
Pike_error("The curve has already been initialized!\n");
}
switch(family) {
case 1:
if (revision != 1)
Pike_error("Unsupported revision.\n");
switch(field_size)
{
case 192:
THIS->curve = &nettle_secp_192r1;
break;
case 224:
THIS->curve = &nettle_secp_224r1;
break;
case 256:
THIS->curve = &nettle_secp_256r1;
break;
case 384:
THIS->curve = &nettle_secp_384r1;
break;
case 521:
THIS->curve = &nettle_secp_521r1;
break;
default:
Pike_error("Invalid curve\n");
break;
}
break;
default:
Pike_error("Unknown curve family.\n");
break;
}
THIS->field_size = field_size;
}
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | /*! @decl string(7bit) name()
*!
*! Returns the name of the curve.
*/
PIKEFUN string(7bit) name()
{
if (THIS->curve == &nettle_secp_192r1) {
ref_push_string(MK_STRING("SECP_192R1"));
} else if (THIS->curve == &nettle_secp_224r1) {
ref_push_string(MK_STRING("SECP_224R1"));
} else if (THIS->curve == &nettle_secp_256r1) {
ref_push_string(MK_STRING("SECP_256R1"));
} else if (THIS->curve == &nettle_secp_384r1) {
ref_push_string(MK_STRING("SECP_384R1"));
} else if (THIS->curve == &nettle_secp_521r1) {
ref_push_string(MK_STRING("SECP_521R1"));
} else {
ref_push_string(MK_STRING("UNKNOWN"));
}
}
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | |
/*! @decl int size()
*!
*! @returns
*! Returns the size in bits for a single coordinate on the curve.
*/
PIKEFUN int size()
{
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | push_int(THIS->field_size);
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | }
|
b43231 | 2014-04-06 | Martin Nilsson | | /*! @decl Gmp.mpz new_scalar(function(int(0..):string(8bit)) rnd)
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | *!
*! @param rnd
*! Randomness function to use as source.
*!
*! @returns
*! Returns a random scalar suitable to use as an @[ECDSA] private key
*! or as an ECDH exponent.
*/
|
b43231 | 2014-04-06 | Martin Nilsson | | PIKEFUN object(Gmp.mpz) new_scalar(function(int(0..):string(8bit)) rnd)
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | {
struct ecc_scalar s;
struct object *ret;
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | if (!THIS->curve) Pike_error("No curve defined.\n");
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | ecc_scalar_init(&s, THIS->curve);
ecc_scalar_random(&s, rnd, random_func_wrapper);
push_object(ret = fast_clone_object(get_auto_bignum_program()));
ecc_scalar_get(&s, (mpz_ptr)ret->storage);
ecc_scalar_clear(&s);
}
|
de4514 | 2014-01-02 | Martin Nilsson | | /*! @decl array(Gmp.mpz) `*(Gmp.mpz|int scalar)
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | *!
*! Multiply the curve by a scalar.
*!
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | *! This can be used to get the public key from a private key.
*!
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | *! @returns
*! Returns a new point (x, y) on the curve.
*/
PIKEFUN array(object(Gmp.mpz)) `*(object(Gmp.mpz)|int scalar)
{
struct ecc_scalar s;
struct ecc_point r;
struct object *x;
struct object *y;
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | if (!THIS->curve) Pike_error("No curve defined.\n");
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | convert_svalue_to_bignum(scalar);
ecc_scalar_init(&s, THIS->curve);
ecc_point_init(&r, THIS->curve);
if (!ecc_scalar_set(&s, (mpz_srcptr)scalar->u.object->storage)) {
ecc_scalar_clear(&s);
ecc_point_clear(&r);
SIMPLE_ARG_ERROR("`*", 1, "Invalid scalar for curve.");
}
ecc_point_mul_g(&r, &s);
push_object(x = fast_clone_object(get_auto_bignum_program()));
push_object(y = fast_clone_object(get_auto_bignum_program()));
ecc_point_get(&r, (mpz_ptr)x->storage, (mpz_ptr)y->storage);
ecc_scalar_clear(&s);
ecc_point_clear(&r);
f_aggregate(2);
}
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | |
/*! @decl array(Gmp.mpz) point_mul(Gmp.mpz|int x, Gmp.mpz|int y, @
*! Gmp.mpz|int scalar)
*!
*! Multiply a point on the curve by a scalar.
*!
*! A typical use is for Elliptic Curve Diffie Hellman (ECDH) key exchange.
*!
*! @returns
*! Returns the new point on the curve.
|
bf60e8 | 2014-11-15 | Henrik Grubbström (Grubba) | | *!
*! @throws
*! Throws an error if the point (@[x], @[y]) isn't on the curve.
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | */
PIKEFUN array(object(Gmp.mpz)) point_mul(object(Gmp.mpz)|int x,
object(Gmp.mpz)|int y,
object(Gmp.mpz)|int scalar)
{
struct ecc_point p;
struct ecc_scalar s;
struct ecc_point r;
struct object *rx;
struct object *ry;
if (!THIS->curve) Pike_error("No curve defined.\n");
convert_svalue_to_bignum(x);
convert_svalue_to_bignum(y);
convert_svalue_to_bignum(scalar);
ecc_point_init(&p, THIS->curve);
ecc_scalar_init(&s, THIS->curve);
if (!ecc_point_set(&p,
(mpz_srcptr)x->u.object->storage,
(mpz_srcptr)y->u.object->storage)) {
ecc_scalar_clear(&s);
ecc_point_clear(&p);
SIMPLE_ARG_ERROR("point_mul", 1, "Invalid point on curve.");
}
if (!ecc_scalar_set(&s, (mpz_srcptr)scalar->u.object->storage)) {
ecc_scalar_clear(&s);
ecc_point_clear(&p);
SIMPLE_ARG_ERROR("point_mul", 3, "Invalid scalar for curve.");
}
ecc_point_init(&r, THIS->curve);
ecc_point_mul(&r, &s, &p);
push_object(rx = fast_clone_object(get_auto_bignum_program()));
push_object(ry = fast_clone_object(get_auto_bignum_program()));
ecc_point_get(&r, (mpz_ptr)rx->storage, (mpz_ptr)ry->storage);
ecc_point_clear(&r);
ecc_scalar_clear(&s);
ecc_point_clear(&p);
f_aggregate(2);
stack_pop_n_elems_keep_top(args);
}
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | |
/*! @class ECDSA
*!
*! Elliptic Curve Digital Signing Algorithm
*/
PIKECLASS ECDSA
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT|PROGRAM_CLEAR_STORAGE;
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | {
|
9104d0 | 2014-01-13 | Henrik Grubbström (Grubba) | | /*! @decl inherit __builtin.Nettle.Sign
*/
INHERIT "__builtin.Nettle.Sign";
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | CVAR struct ecc_scalar key;
CVAR struct ecc_point pub;
|
b43231 | 2014-04-06 | Martin Nilsson | | PIKEVAR function(int(0..):string(0..255)) random
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | flags ID_PROTECTED;
INIT
{
const struct ecc_curve *curve =
|
13e2ba | 2014-04-26 | Henrik Grubbström (Grubba) | | (((const struct Nettle_ECC_Curve_struct *)parent_storage(1, Nettle_ECC_Curve_program))->curve);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | if (!curve) Pike_error("No curve selected.\n");
ecc_point_init(&THIS->pub, curve);
ecc_scalar_init(&THIS->key, curve);
|
60afeb | 2014-04-02 | Martin Nilsson | | push_constant_text("Crypto.Random.random_string");
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | APPLY_MASTER("resolv",1);
|
60afeb | 2014-04-02 | Martin Nilsson | | assign_svalue(&THIS->random, Pike_sp-1);
pop_stack();
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | }
EXIT
{
const struct ecc_curve *curve =
|
13e2ba | 2014-04-26 | Henrik Grubbström (Grubba) | | (((const struct Nettle_ECC_Curve_struct *)parent_storage(1, Nettle_ECC_Curve_program))->curve);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | if (!curve) return;
ecc_point_clear(&THIS->pub);
ecc_scalar_clear(&THIS->key);
}
/*! @decl string(7bit) name()
*!
*! Returns the string @expr{"ECDSA"@} followed by
*! the parenthesized name of the curve.
*/
PIKEFUN string(7bit) name()
{
ref_push_string(MK_STRING("ECDSA("));
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | apply_external(1, f_Nettle_ECC_Curve_name_fun_num, 0);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | ref_push_string(MK_STRING(")"));
f_add(3);
}
/*! @decl ECC_Curve get_curve()
*!
*! Get the elliptic curve that is in use.
*/
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | PIKEFUN object(Nettle_ECC_Curve) get_curve()
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | {
struct external_variable_context loc;
loc.o = Pike_fp->current_object;
loc.inherit = Pike_fp->context;
find_external_context(&loc, 1);
ref_push_object_inherit(loc.o, loc.inherit - loc.o->prog->inherits);
}
/*! @decl Gmp.mpz get_private_key()
*!
*! Get the private key.
*/
PIKEFUN object(Gmp.mpz) get_private_key()
{
struct object *ret;
push_object(ret = fast_clone_object(get_auto_bignum_program()));
ecc_scalar_get(&THIS->key, (mpz_ptr)ret->storage);
}
/*! @decl void set_private_key(object(Gmp.mpz)|int k)
*!
|
462436 | 2014-01-30 | Henrik Grubbström (Grubba) | | *! Set the private key (and corresponding private key).
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | *!
*! @note
*! Throws errors if the key isn't valid for the curve.
*/
PIKEFUN void set_private_key(object(Gmp.mpz)|int k)
{
convert_svalue_to_bignum(k);
if (!ecc_scalar_set(&THIS->key, (mpz_srcptr)k->u.object->storage)) {
SIMPLE_ARG_ERROR("set_private_key", 1, "Invalid key for curve.");
}
|
462436 | 2014-01-30 | Henrik Grubbström (Grubba) | | /* Set the corresponding public key, */
ecc_point_mul_g(&THIS->pub, &THIS->key);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | }
/*! @decl object(Gmp.mpz) get_x()
*!
*! Get the x coordinate of the public key.
*!
*! @seealso
*! @[get_y()]
*/
PIKEFUN object(Gmp.mpz) get_x()
{
struct object *ret;
push_object(ret = fast_clone_object(get_auto_bignum_program()));
ecc_point_get(&THIS->pub, (mpz_ptr)ret->storage, NULL);
}
/*! @decl object(Gmp.mpz) get_y()
*!
*! Get the y coordinate of the public key.
*!
*! @seealso
*! @[get_x()]
*/
PIKEFUN object(Gmp.mpz) get_y()
{
struct object *ret;
push_object(ret = fast_clone_object(get_auto_bignum_program()));
ecc_point_get(&THIS->pub, NULL, (mpz_ptr)ret->storage);
}
/*! @decl void set_public_key(object(Gmp.mpz)|int x, object(Gmp.mpz)|int y)
*!
*! Change to the selected point on the curve as public key.
*!
*! @note
*! Throws errors if the point isn't on the curve.
*/
PIKEFUN void set_public_key(object(Gmp.mpz)|int x, object(Gmp.mpz)|int y)
{
convert_svalue_to_bignum(x);
convert_svalue_to_bignum(y);
if (!ecc_point_set(&THIS->pub,
(mpz_srcptr)x->u.object->storage,
(mpz_srcptr)y->u.object->storage)) {
SIMPLE_ARG_ERROR("set_point", 1, "Invalid point on curve.");
}
}
|
b43231 | 2014-04-06 | Martin Nilsson | | /*! @decl void set_random(function(int(0..):string(8bit)) r)
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | *!
*! Set the random function, used to generate keys and parameters,
*! to the function @[r].
*/
|
b43231 | 2014-04-06 | Martin Nilsson | | PIKEFUN void set_random(function(int(0..):string(8bit)) r)
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | {
assign_svalue(&THIS->random, r);
}
/*! @decl int(0..1) raw_verify(string(8bit) digest, @
*! object(Gmp.mpz) r, @
*! object(Gmp.mpz) s)
*!
*! Verify the signature @[r], @[s] against the message digest @[digest].
*/
PIKEFUN int(0..1) raw_verify(string(0..255) digest,
object(Gmp.mpz)|int r,
object(Gmp.mpz)|int s)
{
struct dsa_signature sig;
int ret;
NO_WIDE_STRING(digest);
dsa_signature_init(&sig);
if (!mpz_from_svalue((MP_INT *)&sig.r, r)) {
dsa_signature_clear(&sig);
SIMPLE_ARG_TYPE_ERROR("raw_verify", 1, "Gmp.mpz|int");
}
if (!mpz_from_svalue((MP_INT *)&sig.s, s)) {
dsa_signature_clear(&sig);
SIMPLE_ARG_TYPE_ERROR("raw_verify", 2, "Gmp.mpz|int");
}
ret = ecdsa_verify(&THIS->pub, digest->len, STR0(digest), &sig);
dsa_signature_clear(&sig);
RETURN ret;
}
/*! @decl array(Gmp.mpz) raw_sign(string(8bit) digest)
*!
*! Sign the message digest @[digest]. Returns the signature
*! as two @[Gmp.mpz] objects.
*/
PIKEFUN array(object(Gmp.mpz)) raw_sign(string(8bit) digest)
{
struct dsa_signature sig;
struct object *r, *s;
NO_WIDE_STRING(digest);
dsa_signature_init(&sig);
ecdsa_sign(&THIS->key, &THIS->random, random_func_wrapper,
digest->len, STR0(digest), &sig);
push_bignum((MP_INT *)&sig.r);
push_bignum((MP_INT *)&sig.s);
dsa_signature_clear(&sig);
f_aggregate(2);
stack_pop_n_elems_keep_top(args);
}
/*! @decl void generate_key()
*!
*! Generate a new set of private and public keys on the current curve.
*/
PIKEFUN void generate_key()
{
ecdsa_generate_keypair(&THIS->pub, &THIS->key,
&THIS->random, random_func_wrapper);
}
}
/*! @endclass ECDSA
*/
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | }
/*! @endclass ECC_Curve
*/
#endif /* HAVE_NETTLE_ECDSA_H */
|
877f41 | 2014-01-04 | Henrik Grubbström (Grubba) | | /*! @endmodule Nettle
*/
|
d5f689 | 2013-11-24 | Martin Nilsson | | void
hogweed_init(void)
{
INIT;
}
void
hogweed_exit(void)
{
EXIT;
}
#endif
|