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"
|
6dc29f | 2016-03-14 | Martin Nilsson | | #include "mapping.h"
|
f05d05 | 2016-10-08 | Henrik Grubbström (Grubba) | | #include "stralloc.h"
|
6dc29f | 2016-03-14 | Martin Nilsson | | #include "constants.h"
|
d5f689 | 2013-11-24 | Martin Nilsson | |
#include "nettle_config.h"
#ifdef HAVE_LIBHOGWEED
DECLARATIONS
#include "nettle.h"
#include <nettle/dsa.h>
#include <nettle/rsa.h>
|
9071e0 | 2014-10-30 | Martin Nilsson | | /* Includes <gmp.h> */
|
2b1c92 | 2013-12-24 | Henrik Grubbström (Grubba) | | #include "bignum.h"
|
877f41 | 2014-01-04 | Henrik Grubbström (Grubba) | | /*! @module Nettle
*/
|
86e256 | 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");
|
4ae950 | 2016-03-19 | Martin Nilsson | | if((unsigned)Pike_sp[-1].u.string->len != (unsigned)num ||
Pike_sp[-1].u.string->size_shift != 0)
|
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)) {
|
ce83e5 | 2015-05-08 | Martin Nilsson | | dsa_params_clear(¶ms);
|
1cfe7f | 2014-04-17 | Henrik Grubbström (Grubba) | | 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");
}
}
/*! @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>
|
a8acae | 2015-01-27 | Martin Nilsson | | #define SECP192R1 0
#define SECP224R1 1
#define SECP256R1 2
#define SECP384R1 3
#define SECP521R1 4
|
95186a | 2015-02-14 | Henrik Grubbström (Grubba) | | #ifndef ecc_point_equal_p
|
2bc49a | 2016-02-02 | Martin Nilsson | | static int ecc_point_equal_p(const struct ecc_point *a, const struct ecc_point *b)
|
95186a | 2015-02-14 | Henrik Grubbström (Grubba) | | {
return (a->ecc == b->ecc) && !mpn_cmp(a->p, b->p, ecc_size_a(a->ecc));
}
#endif
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | /*! @class ECC_Curve
*!
*! Elliptic Curve Definition
*/
PIKECLASS ECC_Curve
{
|
e56f69 | 2015-01-21 | Henrik Grubbström (Grubba) | | /*! @decl inherit __builtin.Nettle.ECC_Curve
*/
INHERIT "__builtin.Nettle.ECC_Curve";
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | CVAR const struct ecc_curve *curve;
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | |
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | | /* Initialized to the scalar constant 1. */
CVAR struct ecc_scalar scalar_one;
|
29b700 | 2014-04-21 | Henrik Grubbström (Grubba) | | DECLARE_STORAGE;
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | | EXIT
{
|
199b88 | 2016-12-26 | Henrik Grubbström (Grubba) | | if (THIS->curve) {
ecc_scalar_clear(&THIS->scalar_one);
}
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | | }
|
a8acae | 2015-01-27 | Martin Nilsson | | /*! @decl void create(int(0..) curve)
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | *!
*! Initialize the curve.
|
a8acae | 2015-01-27 | Martin Nilsson | | *!
*! @param curve
*! The curve type the object should be initialized as.
*! @int
*! @value Nettle.SECP192R1
*! @value Nettle.SECP224R1
*! @value Nettle.SECP256R1
*! @value Nettle.SECP384R1
*! @value Nettle.SECP521R1
*! @endint
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | */
|
a8acae | 2015-01-27 | Martin Nilsson | | PIKEFUN void create(int(0..) curve)
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | flags ID_STATIC
{
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | | mpz_t mpz_one;
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | if (THIS->curve) {
Pike_error("The curve has already been initialized!\n");
}
|
a8acae | 2015-01-27 | Martin Nilsson | | switch(curve) {
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_CURVE_NETTLE_SECP_192R1
|
a8acae | 2015-01-27 | Martin Nilsson | | case SECP192R1: THIS->curve = &nettle_secp_192r1; break;
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_192R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_224R1
|
a8acae | 2015-01-27 | Martin Nilsson | | case SECP224R1: THIS->curve = &nettle_secp_224r1; break;
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_224R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_256R1
|
a8acae | 2015-01-27 | Martin Nilsson | | case SECP256R1: THIS->curve = &nettle_secp_256r1; break;
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_256R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_384R1
|
a8acae | 2015-01-27 | Martin Nilsson | | case SECP384R1: THIS->curve = &nettle_secp_384r1; break;
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_384R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_521R1
|
a8acae | 2015-01-27 | Martin Nilsson | | case SECP521R1: THIS->curve = &nettle_secp_521r1; break;
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_521R1 */
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | default:
|
a8acae | 2015-01-27 | Martin Nilsson | | Pike_error("Invalid curve\n");
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | break;
}
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | |
ecc_scalar_init(&THIS->scalar_one, THIS->curve);
mpz_init_set_si(mpz_one, 1);
ecc_scalar_set(&THIS->scalar_one, mpz_one);
mpz_clear(mpz_one);
|
3852ef | 2014-01-04 | Henrik Grubbström (Grubba) | | }
|
95186a | 2015-02-14 | Henrik Grubbström (Grubba) | | /*! @decl protected local int(0..1) `==(mixed x)
*!
*! @returns
*! Returns @expr{1@} if @[x] is the same @[Curve],
*! and @expr{0@} (zero) otherwise.
*/
|
5b9d5c | 2015-01-27 | Henrik Grubbström (Grubba) | | PIKEFUN int(0..1) `==(mixed x)
flags ID_PROTECTED|ID_LOCAL;
{
struct Nettle_ECC_Curve_struct *c;
struct inherit *inh;
struct program *p;
if (!x || (TYPEOF(*x) != PIKE_T_OBJECT) ||
!x->u.object || !x->u.object->prog) RETURN 0;
p = x->u.object->prog;
inh = p->inherits + SUBTYPEOF(*x);
p = inh->prog;
if (p != Nettle_ECC_Curve_program) {
int lfun_eq;
if ((low_get_storage(p, Nettle_ECC_Curve_program) == -1) ||
((lfun_eq = FIND_LFUN(p, LFUN_EQ)) == -1)) {
/* p does not inherit ECC.Curve, or has made `==() private. */
RETURN 0;
}
/* Let's see if LFUN::`==() in x traverses down to ECC.Curve. */
/* FIXME: We're recursing via potentially broken code,
* so we probably ought to use CYCLIC here.
*/
lfun_eq += inh->identifier_level;
ref_push_object_inherit(Pike_fp->current_object,
Pike_fp->context -
Pike_fp->current_object->prog->inherits);
apply_low(x->u.object, lfun_eq, 1);
stack_pop_n_elems_keep_top(args);
return;
}
c = (struct Nettle_ECC_Curve_struct *)
(PIKE_OBJ_STORAGE(x->u.object) +
INHERIT_FROM_INT(x->u.object->prog, SUBTYPEOF(*x))->storage_offset +
Nettle_ECC_Curve_storage_offset);
RETURN c->curve == THIS->curve;
}
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | /*! @decl string(7bit) name()
*!
*! Returns the name of the curve.
|
f3df59 | 2016-12-23 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[jose_name()]
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | */
PIKEFUN string(7bit) name()
{
|
adefa4 | 2016-09-24 | Martin Nilsson | | #ifdef HAVE_CURVE_NETTLE_SECP_192R1
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | if (THIS->curve == &nettle_secp_192r1) {
ref_push_string(MK_STRING("SECP_192R1"));
|
adefa4 | 2016-09-24 | Martin Nilsson | | return;
}
#endif /* HAVE_CURVE_NETTLE_SECP_192R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_224R1
if (THIS->curve == &nettle_secp_224r1) {
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | ref_push_string(MK_STRING("SECP_224R1"));
|
adefa4 | 2016-09-24 | Martin Nilsson | | return;
}
#endif /* HAVE_CURVE_NETTLE_SECP_224R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_256R1
if (THIS->curve == &nettle_secp_256r1) {
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | ref_push_string(MK_STRING("SECP_256R1"));
|
adefa4 | 2016-09-24 | Martin Nilsson | | return;
}
#endif /* HAVE_CURVE_NETTLE_SECP_256R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_384R1
if (THIS->curve == &nettle_secp_384r1) {
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | ref_push_string(MK_STRING("SECP_384R1"));
|
adefa4 | 2016-09-24 | Martin Nilsson | | return;
}
#endif /* HAVE_CURVE_NETTLE_SECP_384R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_521R1
if (THIS->curve == &nettle_secp_521r1) {
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | ref_push_string(MK_STRING("SECP_521R1"));
|
adefa4 | 2016-09-24 | Martin Nilsson | | return;
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | }
|
adefa4 | 2016-09-24 | Martin Nilsson | | #endif /* HAVE_CURVE_NETTLE_SECP_521R1 */
ref_push_string(MK_STRING("UNKNOWN"));
|
4885c5 | 2013-12-30 | Henrik Grubbström (Grubba) | | }
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | |
|
f3df59 | 2016-12-23 | Henrik Grubbström (Grubba) | | /*! @decl string(7bit) jose_name()
*!
*! Returns the name of the curve according to JOSE
*! (@rfc{7518:6.2.1.1@}).
*!
*! @returns
*! Returns the JOSE name for supported curves,
*! and @[UNDEFINED] otherwise.
*!
*! @seealso
*! @[name()]
*/
PIKEFUN string(7bit) jose_name()
{
#ifdef HAVE_CURVE_NETTLE_SECP_256R1
if (THIS->curve == &nettle_secp_256r1) {
ref_push_string(MK_STRING("P-256R"));
return;
}
#endif /* HAVE_CURVE_NETTLE_SECP_256R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_384R1
if (THIS->curve == &nettle_secp_384r1) {
ref_push_string(MK_STRING("P-384"));
return;
}
#endif /* HAVE_CURVE_NETTLE_SECP_384R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_521R1
if (THIS->curve == &nettle_secp_521r1) {
ref_push_string(MK_STRING("P-521"));
return;
}
#endif /* HAVE_CURVE_NETTLE_SECP_521R1 */
push_undefined();
}
|
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()
{
|
410767 | 2015-01-28 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_ECC_BIT_SIZE
|
a8acae | 2015-01-27 | Martin Nilsson | | push_int(ecc_bit_size(THIS->curve));
|
410767 | 2015-01-28 | Henrik Grubbström (Grubba) | | #else
if (THIS->curve == &nettle_secp_192r1) {
push_int(192);
} else if (THIS->curve == &nettle_secp_224r1) {
push_int(224);
} else if (THIS->curve == &nettle_secp_256r1) {
push_int(256);
} else if (THIS->curve == &nettle_secp_384r1) {
push_int(384);
} else if (THIS->curve == &nettle_secp_521r1) {
push_int(521);
} else {
push_int(0);
}
#endif
|
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);
|
c3982f | 2014-10-29 | Martin Nilsson | | push_object(ret = fast_clone_object(bignum_program));
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | ecc_scalar_get(&s, (mpz_ptr)ret->storage);
ecc_scalar_clear(&s);
}
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | static int Nettle_ECC_Curve_Point_program_fun_num;
/*! @decl Point `*(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
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | *! Returns a new @[Point] on the curve.
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | */
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | PIKEFUN Nettle_ECC_Curve_Point `*(object(Gmp.mpz)|int scalar)
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | {
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);
|
c3982f | 2014-10-29 | Martin Nilsson | | push_object(x = fast_clone_object(bignum_program));
push_object(y = fast_clone_object(bignum_program));
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | ecc_point_get(&r, (mpz_ptr)x->storage, (mpz_ptr)y->storage);
ecc_scalar_clear(&s);
ecc_point_clear(&r);
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | apply_current(Nettle_ECC_Curve_Point_program_fun_num, 2);
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | }
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | |
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | /*! @decl Point point_mul(Gmp.mpz|int x, Gmp.mpz|int y, @
*! Gmp.mpz|int scalar)
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | *!
*! Multiply a point on the curve by a scalar.
*!
*! A typical use is for Elliptic Curve Diffie Hellman (ECDH) key exchange.
*!
|
7ac157 | 2015-03-06 | Martin Nilsson | | *! This is equivalent to @expr{(Point(x, y) * scalar)@}.
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | *!
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | *! @returns
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | *! Returns the new @[Point] on the curve.
|
cafd1a | 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) | | */
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | PIKEFUN Nettle_ECC_Curve_Point point_mul(object(Gmp.mpz)|int x,
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | 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);
|
c3982f | 2014-10-29 | Martin Nilsson | | push_object(rx = fast_clone_object(bignum_program));
push_object(ry = fast_clone_object(bignum_program));
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | ecc_point_get(&r, (mpz_ptr)rx->storage, (mpz_ptr)ry->storage);
ecc_point_clear(&r);
ecc_scalar_clear(&s);
ecc_point_clear(&p);
|
4b485c | 2015-01-23 | Henrik Grubbström (Grubba) | | apply_current(Nettle_ECC_Curve_Point_program_fun_num, 2);
|
0ba972 | 2013-12-28 | Henrik Grubbström (Grubba) | | stack_pop_n_elems_keep_top(args);
}
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | |
|
923190 | 2014-12-11 | Henrik Grubbström (Grubba) | | /*! @class Point
*!
*! A point on an elliptic curve.
*/
PIKECLASS Point
program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT|PROGRAM_CLEAR_STORAGE;
{
CVAR struct ecc_point point;
|
e56f69 | 2015-01-21 | Henrik Grubbström (Grubba) | | /*! @decl inherit ECC_Curve::Point
*/
EXTRA
{
/* Perform an inherit of the Point class that our parent
* contains via its inherit of __builtin.Nettle.ECC_Curve.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_Point_fun_num =
really_low_find_shared_string_identifier(MK_STRING("Point"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_Point_fun_num >= 0) {
struct program *parent_Point_prog =
low_program_from_function(parent_obj, parent_Point_fun_num);
if (parent_Point_prog) {
parent_Point_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_Point_fun_num);
low_inherit(parent_Point_prog, 0,
parent_Point_fun_num,
1 + 42, 0, NULL);
}
}
}
|
1818b4 | 2015-01-20 | Martin Nilsson | |
|
923190 | 2014-12-11 | Henrik Grubbström (Grubba) | | INIT
{
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | | const struct Nettle_ECC_Curve_struct *parent =
parent_storage(1, Nettle_ECC_Curve_program);
const struct ecc_curve *curve = parent->curve;
|
923190 | 2014-12-11 | Henrik Grubbström (Grubba) | | if (!curve) Pike_error("No curve selected.\n");
ecc_point_init(&THIS->point, curve);
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | |
/* Make sure that the point is on the curve by initializing it to 'g'. */
ecc_point_mul_g(&THIS->point, &parent->scalar_one);
|
923190 | 2014-12-11 | Henrik Grubbström (Grubba) | | }
EXIT
{
|
1ee3c8 | 2016-12-25 | Henrik Grubbström (Grubba) | | const struct Nettle_ECC_Curve_struct *parent =
parent_storage(1, Nettle_ECC_Curve_program);
const struct ecc_curve *curve = parent->curve;
|
923190 | 2014-12-11 | Henrik Grubbström (Grubba) | | if (!curve) return;
ecc_point_clear(&THIS->point);
}
|
95186a | 2015-02-14 | Henrik Grubbström (Grubba) | | /*! @decl protected local int(0..1) _equal(mixed x)
*!
*! @returns
*! Returns @expr{1@} if @[x] is a @[Point] on the same
*! @[Curve] and has the same coordinates, and otherwise
|
7ac157 | 2015-03-06 | Martin Nilsson | | *! returns @expr{0@} (zero).
|
95186a | 2015-02-14 | Henrik Grubbström (Grubba) | | */
PIKEFUN int(0..1) _equal(mixed x)
flags ID_PROTECTED|ID_LOCAL;
{
struct inherit *inh;
struct program *p;
const struct ecc_point *xp;
if (!x || (TYPEOF(*x) != PIKE_T_OBJECT) ||
!x->u.object || !x->u.object->prog) RETURN 0;
p = x->u.object->prog;
inh = p->inherits + SUBTYPEOF(*x);
p = inh->prog;
if (p != Nettle_ECC_Curve_Point_program) {
int lfun__equal;
if ((low_get_storage(p, Nettle_ECC_Curve_Point_program) == -1) ||
((lfun__equal = FIND_LFUN(p, LFUN__EQUAL)) == -1)) {
/* p does not inherit ECC.Curve, or has made _equal() private. */
RETURN 0;
}
/* Let's see if LFUN::_equal() in x traverses down to ECC.Curve. */
/* FIXME: We're recursing via potentially broken code,
* so we probably ought to use CYCLIC here.
*/
lfun__equal += inh->identifier_level;
ref_push_object_inherit(Pike_fp->current_object,
Pike_fp->context -
Pike_fp->current_object->prog->inherits);
apply_low(x->u.object, lfun__equal, 1);
stack_pop_n_elems_keep_top(args);
return;
}
/* Find the other point. */
xp = &((struct Nettle_ECC_Curve_Point_struct *)
(PIKE_OBJ_STORAGE(x->u.object) +
inh->storage_offset +
Nettle_ECC_Curve_Point_storage_offset))->point;
/* Compare and return. */
RETURN ecc_point_equal_p(&(THIS->point), xp);
}
|
923190 | 2014-12-11 | Henrik Grubbström (Grubba) | | /*! @decl string(7bit) name()
*!
*! Returns the string @expr{"Point"@} followed by
*! the parenthesized name of the curve.
*/
PIKEFUN string(7bit) name()
{
ref_push_string(MK_STRING("Point("));
apply_external(1, f_Nettle_ECC_Curve_name_fun_num, 0);
ref_push_string(MK_STRING(")"));
f_add(3);
}
/*! @decl ECC_Curve get_curve()
*!
*! Get the elliptic curve that is in use.
*/
PIKEFUN object(Nettle_ECC_Curve) get_curve()
{
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 object(Gmp.mpz) get_x()
*!
*! Get the x coordinate of the point.
*!
*! @seealso
*! @[get_y()]
*/
PIKEFUN object(Gmp.mpz) get_x()
{
struct object *ret;
push_object(ret = fast_clone_object(bignum_program));
ecc_point_get(&THIS->point, (mpz_ptr)ret->storage, NULL);
}
/*! @decl object(Gmp.mpz) get_y()
*!
*! Get the y coordinate of the point.
*!
*! @seealso
*! @[get_x()]
*/
PIKEFUN object(Gmp.mpz) get_y()
{
struct object *ret;
push_object(ret = fast_clone_object(bignum_program));
ecc_point_get(&THIS->point, NULL, (mpz_ptr)ret->storage);
}
/*! @decl void set(object(Gmp.mpz)|int x, object(Gmp.mpz)|int y)
*!
*! Change to the selected point on the curve.
*!
*! @note
*! Throws errors if the point isn't on the curve.
*/
PIKEFUN void set(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->point,
(mpz_srcptr)x->u.object->storage,
(mpz_srcptr)y->u.object->storage)) {
SIMPLE_ARG_ERROR("set", 1, "Invalid point on curve.");
}
}
/*! @decl Point `*(Gmp.mpz|int scalar)
*!
*! Multiply the 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.
*/
PIKEFUN Nettle_ECC_Curve_Point `*(object(Gmp.mpz)|int scalar)
flags ID_PROTECTED;
{
struct ecc_scalar s;
struct ecc_point r;
struct object *rx;
struct object *ry;
const struct ecc_curve *curve =
(((const struct Nettle_ECC_Curve_struct *)parent_storage(1, Nettle_ECC_Curve_program))->curve);
if (!curve) Pike_error("No curve defined.\n");
convert_svalue_to_bignum(scalar);
ecc_scalar_init(&s, curve);
if (!ecc_scalar_set(&s, (mpz_srcptr)scalar->u.object->storage)) {
ecc_scalar_clear(&s);
SIMPLE_ARG_ERROR("`*", 1, "Invalid scalar for curve.");
}
ecc_point_init(&r, curve);
ecc_point_mul(&r, &s, &THIS->point);
push_object(rx = fast_clone_object(bignum_program));
push_object(ry = fast_clone_object(bignum_program));
ecc_point_get(&r, (mpz_ptr)rx->storage, (mpz_ptr)ry->storage);
ecc_point_clear(&r);
ecc_scalar_clear(&s);
apply_external(1, Nettle_ECC_Curve_Point_program_fun_num, 2);
}
}
/*! @endclass Point
*/
|
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) | | {
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | /*! @decl inherit Point
|
65394a | 2015-05-27 | Henrik Grubbström (Grubba) | | *!
*! This point represents the public key.
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | */
|
65394a | 2015-05-27 | Henrik Grubbström (Grubba) | | EXTRA
{
/* Perform an inherit of the Point class that our parent contains.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_Point_fun_num =
really_low_find_shared_string_identifier(MK_STRING("Point"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_Point_fun_num >= 0) {
struct program *parent_Point_prog =
low_program_from_function(parent_obj, parent_Point_fun_num);
#ifdef PIKE_DEBUG
if (parent_Point_prog != Nettle_ECC_Curve_Point_program) {
Pike_fatal("Unexpected Point program.\n");
}
#endif
if (parent_Point_prog) {
parent_Point_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_Point_fun_num);
low_inherit(parent_Point_prog, 0,
parent_Point_fun_num,
1 + 42, 0, NULL);
}
}
}
|
c88bb1 | 2015-05-27 | 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;
|
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_scalar_init(&THIS->key, curve);
|
6dc29f | 2016-03-14 | Martin Nilsson | |
struct svalue *random =
simple_mapping_string_lookup(get_builtin_constants(), "random_string");
if(!random || (TYPEOF(*random) != T_FUNCTION))
Pike_error("Unable to resolve random function.\n");
assign_svalue(&THIS->random, random);
|
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_scalar_clear(&THIS->key);
}
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | static int f_Nettle_ECC_Curve_ECDSA_inherited_Point_set_fun_num = -1;
EXTRA
{
f_Nettle_ECC_Curve_ECDSA_inherited_Point_set_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
f_Nettle_ECC_Curve_Point_set_fun_num);
}
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | /*! @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;
|
c3982f | 2014-10-29 | Martin Nilsson | | push_object(ret = fast_clone_object(bignum_program));
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | 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)
{
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | struct ecc_point *pub;
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | 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, */
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | pub = &((struct Nettle_ECC_Curve_Point_struct *)
get_inherited_storage(1, Nettle_ECC_Curve_Point_program))->
point;
ecc_point_mul_g(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()
{
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | struct ecc_point *pub;
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | struct object *ret;
|
c3982f | 2014-10-29 | Martin Nilsson | | push_object(ret = fast_clone_object(bignum_program));
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | pub = &((struct Nettle_ECC_Curve_Point_struct *)
get_inherited_storage(1, Nettle_ECC_Curve_Point_program))->
point;
ecc_point_get(pub, (mpz_ptr)ret->storage, NULL);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | }
/*! @decl object(Gmp.mpz) get_y()
*!
*! Get the y coordinate of the public key.
*!
*! @seealso
*! @[get_x()]
*/
PIKEFUN object(Gmp.mpz) get_y()
{
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | struct ecc_point *pub;
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | struct object *ret;
|
c3982f | 2014-10-29 | Martin Nilsson | | push_object(ret = fast_clone_object(bignum_program));
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | pub = &((struct Nettle_ECC_Curve_Point_struct *)
get_inherited_storage(1, Nettle_ECC_Curve_Point_program))->
point;
ecc_point_get(pub, NULL, (mpz_ptr)ret->storage);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | }
/*! @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)
{
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | apply_current(f_Nettle_ECC_Curve_ECDSA_inherited_Point_set_fun_num, args);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | }
|
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)
{
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | struct ecc_point *pub;
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | 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");
}
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | pub = &((struct Nettle_ECC_Curve_Point_struct *)
get_inherited_storage(1, Nettle_ECC_Curve_Point_program))->
point;
ret = ecdsa_verify(pub, digest->len, STR0(digest), &sig);
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | 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()
{
|
c88bb1 | 2015-05-27 | Henrik Grubbström (Grubba) | | struct ecc_point *pub;
pub = &((struct Nettle_ECC_Curve_Point_struct *)
get_inherited_storage(1, Nettle_ECC_Curve_Point_program))->
point;
ecdsa_generate_keypair(pub, &THIS->key,
|
e604c6 | 2014-01-04 | Henrik Grubbström (Grubba) | | &THIS->random, random_func_wrapper);
}
}
/*! @endclass ECDSA
*/
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | }
/*! @endclass ECC_Curve
*/
#endif /* HAVE_NETTLE_ECDSA_H */
|
f05d05 | 2016-10-08 | Henrik Grubbström (Grubba) | | #if defined(HAVE_NETTLE_EDDSA_H) && defined(HAVE_NETTLE_CURVE25519_H)
#include <nettle/curve25519.h>
#include <nettle/eddsa.h>
/*! @class Curve25519
*!
|
c7b301 | 2016-10-09 | Henrik Grubbström (Grubba) | | *! Elliptic Curve Definition for the curve
*! @expr{y^2 = x^2 + 486662 x^2 + x (mod 2^255 - 19)@}.
*!
*! This curve is standardized in @rfc{7748@}.
*!
*! @note
*! The API for this curve differs somewhat from the API
*! used by the other @[Curve]s.
*!
*! @seealso
*! @[Curve], @rfc{7748@}
|
f05d05 | 2016-10-08 | Henrik Grubbström (Grubba) | | */
PIKECLASS Curve25519
{
DECLARE_STORAGE;
/*! @decl string(7bit) name()
*!
*! Returns the name of the curve.
*/
PIKEFUN string(7bit) name()
{
ref_push_string(MK_STRING("Curve25519"));
}
/*! @decl int size()
*!
*! @returns
*! Returns the size in bits for a single coordinate on the curve.
*/
PIKEFUN int size()
{
push_int(255);
}
/*! @decl Gmp.mpz new_scalar(function(int(0..):string(8bit)) rnd)
*!
*! @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.
*/
PIKEFUN string(8bit) new_scalar(function(int(0..):string(8bit)) rnd)
{
push_int(CURVE25519_SIZE);
apply_svalue(rnd, 1);
}
/*! @decl string(8bit) `*(string(8bit) scalar)
*!
*! Multiply the curve by a scalar.
*!
*! This can be used to get the public key from a private key.
*!
*! @returns
*! Returns a new point on the curve.
*/
PIKEFUN string(8bit) `*(string(8bit) scalar)
{
struct pike_string *res;
if (scalar->len != CURVE25519_SIZE) Pike_error("Invalid scalar.\n");
res = begin_shared_string(CURVE25519_SIZE);
curve25519_mul_g(STR0(res), STR0(scalar));
push_string(end_shared_string(res));
}
/*! @decl string(8bit) point_mul(string(8bit) x, string(8bit) 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.
*/
PIKEFUN string(8bit) point_mul(string(8bit) x, string(8bit) scalar)
{
struct pike_string *res;
if (x->len != CURVE25519_SIZE) Pike_error("Invalid x.\n");
if (scalar->len != CURVE25519_SIZE) Pike_error("Invalid scalar.\n");
res = begin_shared_string(CURVE25519_SIZE);
curve25519_mul(STR0(res), STR0(scalar), STR0(x));
push_string(end_shared_string(res));
}
/*! @class EdDSA
*!
*! Edwards Curve Digital Signing Algorithm
*/
PIKECLASS EdDSA
program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT|PROGRAM_CLEAR_STORAGE;
{
/*! @decl inherit __builtin.Nettle.Sign
*/
INHERIT "__builtin.Nettle.Sign";
PIKEVAR string(8bit) private_key flags ID_PRIVATE|ID_HIDDEN;
PIKEVAR string(8bit) public_key flags ID_PRIVATE|ID_HIDDEN;
PIKEVAR function(int(0..):string(0..255)) random
flags ID_PROTECTED;
INIT
{
struct svalue *random =
simple_mapping_string_lookup(get_builtin_constants(), "random_string");
if(!random || (TYPEOF(*random) != T_FUNCTION))
Pike_error("Unable to resolve random function.\n");
assign_svalue(&THIS->random, random);
}
/*! @decl string(7bit) name()
*!
*! Returns the string @expr{"EdDSA"@}.
*/
PIKEFUN string(7bit) name()
{
ref_push_string(MK_STRING("EdDSA"));
}
/*! @decl Curve25519 get_curve()
*!
*! Get the elliptic curve that is in use.
*/
PIKEFUN object(Nettle_Curve25519) get_curve()
{
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 string(8bit) get_private_key()
*!
*! Get the private key.
*/
PIKEFUN string(8bit) get_private_key()
{
if (THIS->private_key) {
ref_push_string(THIS->private_key);
} else {
push_undefined();
}
}
/*! @decl void set_private_key(string(8bit) k)
*!
*! Set the private key (and corresponding public key).
*!
*! @note
*! Throws errors if the key isn't valid for the curve.
*/
PIKEFUN void set_private_key(string(8bit) k)
{
struct pike_string *pub;
if (k->len != ED25519_KEY_SIZE) Pike_error("Invalid private key.\n");
if (THIS->private_key) {
free_string(THIS->private_key);
}
copy_shared_string(THIS->private_key, k);
/* Set the corresponding public key, */
pub = begin_shared_string(ED25519_KEY_SIZE);
ed25519_sha512_public_key(STR0(pub), STR0(k));
if (THIS->public_key) {
free_string(THIS->public_key);
}
THIS->public_key = end_shared_string(pub);
}
/*! @decl string(8bit) get_x()
*!
*! Get the x coordinate of the public key.
*/
PIKEFUN string(8bit) get_x()
{
if (THIS->public_key) {
ref_push_string(THIS->public_key);
} else {
push_undefined();
}
}
/*! @decl void set_public_key(string(8bit) x)
*!
*! 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(string(8bit) x)
{
if (THIS->public_key == x) return;
if (x->len != ED25519_KEY_SIZE) Pike_error("Invalid key.\n");
if (THIS->public_key) {
free_string(THIS->public_key);
}
if (THIS->private_key) {
free_string(THIS->private_key);
THIS->private_key = NULL;
}
copy_shared_string(THIS->public_key, x);
}
/*! @decl void set_random(function(int(0..):string(8bit)) r)
*!
*! Set the random function, used to generate keys and parameters,
*! to the function @[r].
*/
PIKEFUN void set_random(function(int(0..):string(8bit)) r)
{
assign_svalue(&THIS->random, r);
}
/*! @decl int(0..1) raw_verify(string(8bit) message, string(8bit) signature)
*!
*! Verify the @[signature] against the @[message].
*/
PIKEFUN int(0..1) raw_verify(string(8bit) message, string(8bit) signature)
{
if (!THIS->public_key) Pike_error("No public key.\n");
if (signature->len != ED25519_SIGNATURE_SIZE) {
push_int(0);
return;
}
push_int(ed25519_sha512_verify(STR0(THIS->public_key),
message->len, STR0(message),
STR0(signature)));
}
/*! @decl string(8bit) raw_sign(string(8bit) message)
*!
*! Sign the @[message].
*/
PIKEFUN string(8bit) raw_sign(string(8bit) message)
{
struct pike_string *res;
if (!THIS->private_key) Pike_error("No private key.\n");
if (!THIS->public_key) Pike_error("No public key.\n");
res = begin_shared_string(ED25519_SIGNATURE_SIZE);
ed25519_sha512_sign(STR0(THIS->public_key), STR0(THIS->private_key),
message->len, STR0(message),
STR0(res));
push_string(end_shared_string(res));
}
/*! @decl void generate_key()
*!
*! Generate a new set of private and public keys on the current curve.
*/
PIKEFUN void generate_key()
{
push_int(ED25519_KEY_SIZE);
apply_svalue(&THIS->random, 1);
apply_current(f_Nettle_Curve25519_EdDSA_set_private_key_fun_num, 1);
}
}
/*! @endclass EdDSA
*/
}
/*! @endclass Curve25519
*/
#endif /* HAVE_NETTLE_EDDSA_H && HAVE_NETTLE_CURVE25519_H */
|
877f41 | 2014-01-04 | Henrik Grubbström (Grubba) | | /*! @endmodule Nettle
*/
|
d5f689 | 2013-11-24 | Martin Nilsson | | void
hogweed_init(void)
{
INIT;
|
a8acae | 2015-01-27 | Martin Nilsson | |
|
68ab9a | 2015-02-07 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_ECDSA_H
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_CURVE_NETTLE_SECP_192R1
|
a8acae | 2015-01-27 | Martin Nilsson | | ADD_INT_CONSTANT("SECP192R1", SECP192R1, 0);
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_192R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_224R1
|
a8acae | 2015-01-27 | Martin Nilsson | | ADD_INT_CONSTANT("SECP224R1", SECP224R1, 0);
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_224R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_256R1
|
a8acae | 2015-01-27 | Martin Nilsson | | ADD_INT_CONSTANT("SECP256R1", SECP256R1, 0);
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_256R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_384R1
|
a8acae | 2015-01-27 | Martin Nilsson | | ADD_INT_CONSTANT("SECP384R1", SECP384R1, 0);
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_384R1 */
#ifdef HAVE_CURVE_NETTLE_SECP_521R1
|
a8acae | 2015-01-27 | Martin Nilsson | | ADD_INT_CONSTANT("SECP521R1", SECP521R1, 0);
|
21071f | 2016-09-23 | Henrik Grubbström (Grubba) | | #endif /* HAVE_CURVE_NETTLE_SECP_521R1 */
|
68ab9a | 2015-02-07 | Henrik Grubbström (Grubba) | | #endif /* HAVE_NETTLE_ECDSA_H */
|
f05d05 | 2016-10-08 | Henrik Grubbström (Grubba) | |
#ifdef NETTLE_CURVE25519_RFC7748
ADD_INT_CONSTANT("CURVE25519_RFC7748", 1, 0);
#endif
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
void
hogweed_exit(void)
{
EXIT;
}
#endif
|