From 04c29c0a975148b92c9fd4100a21968da0ee9cc4 Mon Sep 17 00:00:00 2001 From: Maxim Savchenko Date: Mon, 9 Mar 2009 16:33:20 -0400 Subject: [PATCH] ECDSA OpenSSL interface --- basis/openssl/libcrypto/libcrypto.factor | 64 +++++++++++++++++- extra/ecdsa/authors.txt | 1 + extra/ecdsa/ecdsa-tests.factor | 30 +++++++++ extra/ecdsa/ecdsa.factor | 86 ++++++++++++++++++++++++ extra/ecdsa/summary.txt | 1 + 5 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 extra/ecdsa/authors.txt create mode 100644 extra/ecdsa/ecdsa-tests.factor create mode 100644 extra/ecdsa/ecdsa.factor create mode 100644 extra/ecdsa/summary.txt diff --git a/basis/openssl/libcrypto/libcrypto.factor b/basis/openssl/libcrypto/libcrypto.factor index 9cbed1f752..1a25b4d019 100644 --- a/basis/openssl/libcrypto/libcrypto.factor +++ b/basis/openssl/libcrypto/libcrypto.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2007 Elie CHAFTARI +! Copyright (C) 2007 Elie CHAFTARI, 2009 Maxim Savchenko ! See http://factorcode.org/license.txt for BSD license. ! ! Tested with OpenSSL 0.9.8a_0 on Mac OS X 10.4.9 PowerPC @@ -159,3 +159,65 @@ FUNCTION: int RSA_check_key ( void* rsa ) ; FUNCTION: void RSA_free ( void* rsa ) ; FUNCTION: int RSA_print_fp ( void* fp, void* x, int offset ) ; + +! =============================================== +! objects.h +! =============================================== + +FUNCTION: int OBJ_sn2nid ( char* s ) ; + +! =============================================== +! bn.h +! =============================================== + +FUNCTION: int BN_num_bits ( void* a ) ; + +FUNCTION: void* BN_bin2bn ( void* s, int len, void* ret ) ; + +FUNCTION: int BN_bn2bin ( void* a, void* to ) ; + +FUNCTION: void BN_clear_free ( void* a ) ; + +! =============================================== +! ec.h +! =============================================== + +CONSTANT: POINT_CONVERSION_COMPRESSED 2 +CONSTANT: POINT_CONVERSION_UNCOMPRESSED 4 +CONSTANT: POINT_CONVERSION_HYBRID 6 + +FUNCTION: int EC_GROUP_get_degree ( void* group ) ; + +FUNCTION: void* EC_POINT_new ( void* group ) ; + +FUNCTION: void EC_POINT_clear_free ( void* point ) ; + +FUNCTION: int EC_POINT_point2oct ( void* group, void* point, int form, void* buf, int len, void* ctx ) ; + +FUNCTION: int EC_POINT_oct2point ( void* group, void* point, void* buf, int len, void* ctx ) ; + +FUNCTION: void* EC_KEY_new_by_curve_name ( int nid ) ; + +FUNCTION: void EC_KEY_free ( void* r ) ; + +FUNCTION: int EC_KEY_set_private_key ( void* key, void* priv_key ) ; + +FUNCTION: int EC_KEY_set_public_key ( void* key, void* pub_key ) ; + +FUNCTION: int EC_KEY_generate_key ( void* eckey ) ; + +FUNCTION: void* EC_KEY_get0_group ( void* key ) ; + +FUNCTION: void* EC_KEY_get0_private_key ( void* key ) ; + +FUNCTION: void* EC_KEY_get0_public_key ( void* key ) ; + +! =============================================== +! ecdsa.h +! =============================================== + +FUNCTION: int ECDSA_size ( void* eckey ) ; + +FUNCTION: int ECDSA_sign ( int type, void* dgst, int dgstlen, void* sig, void* siglen, void* eckey ) ; + +FUNCTION: int ECDSA_verify ( int type, void* dgst, int dgstlen, void* sig, int siglen, void* eckey ) ; diff --git a/extra/ecdsa/authors.txt b/extra/ecdsa/authors.txt new file mode 100644 index 0000000000..f97e1bfbf9 --- /dev/null +++ b/extra/ecdsa/authors.txt @@ -0,0 +1 @@ +Maxim Savchenko diff --git a/extra/ecdsa/ecdsa-tests.factor b/extra/ecdsa/ecdsa-tests.factor new file mode 100644 index 0000000000..897ee63a95 --- /dev/null +++ b/extra/ecdsa/ecdsa-tests.factor @@ -0,0 +1,30 @@ +! Copyright (C) 2009 Maxim Savchenko +! See http://factorcode.org/license.txt for BSD license. + +USING: namespaces ecdsa tools.test checksums checksums.openssl ; +IN: ecdsa.tests + +SYMBOLS: priv-key pub-key signature ; + +: message ( -- msg ) "Hello world!" ; + +[ ] ! Generating keys +[ + "prime256v1" [ generate-key get-private-key get-public-key ] with-ec + pub-key set priv-key set +] unit-test + +[ ] ! Signing message +[ + message "sha256" checksum-bytes + priv-key get + "prime256v1" [ set-private-key ecdsa-sign ] with-ec + signature set +] unit-test + +[ t ] ! Verifying signature +[ + message "sha256" checksum-bytes + signature get pub-key get + "prime256v1" [ set-public-key ecdsa-verify ] with-ec +] unit-test \ No newline at end of file diff --git a/extra/ecdsa/ecdsa.factor b/extra/ecdsa/ecdsa.factor new file mode 100644 index 0000000000..78b528d4ad --- /dev/null +++ b/extra/ecdsa/ecdsa.factor @@ -0,0 +1,86 @@ +! Copyright (C) 2009 Maxim Savchenko +! See http://factorcode.org/license.txt for BSD license. + +USING: kernel accessors sequences sequences.private destructors math namespaces + locals openssl openssl.libcrypto byte-arrays bit-arrays.private + alien.c-types ; + +IN: ecdsa + + ( curve -- key ) + OBJ_sn2nid dup zero? [ "Unknown curve name" throw ] when + EC_KEY_new_by_curve_name dup ssl-error ec-key boa ; + +: ec-key-handle ( -- handle ) + ec-key get dup handle>> [ nip ] [ already-disposed ] if* ; + +TUPLE: openssl-bignum < openssl-object ; + +M: openssl-bignum free-handle BN_clear_free ; + +TUPLE: ec-point < openssl-object ; + +M: ec-point free-handle EC_POINT_clear_free ; + +PRIVATE> + +: with-ec ( curve quot -- ) + swap [ ec-key rot with-variable ] with-disposal ; inline + +: generate-key ( -- ) + ec-key get handle>> EC_KEY_generate_key ssl-error ; + +: set-private-key ( bin -- ) + ec-key-handle swap + dup length f BN_bin2bn dup ssl-error dup openssl-bignum boa + [ drop EC_KEY_set_private_key ssl-error ] with-disposal ; + +:: set-public-key ( BIN -- ) + ec-key-handle :> KEY + KEY EC_KEY_get0_group :> GROUP + GROUP EC_POINT_new dup ssl-error :> POINT + POINT ec-point boa + [ + drop + GROUP POINT BIN dup length f EC_POINT_oct2point ssl-error + KEY POINT EC_KEY_set_public_key ssl-error + ] with-disposal ; + +: get-private-key ( -- bin/f ) + ec-key-handle EC_KEY_get0_private_key + dup [ dup BN_num_bits bits>bytes tuck BN_bn2bin drop ] when ; + +:: get-public-key ( -- bin/f ) + ec-key-handle :> KEY + KEY EC_KEY_get0_public_key dup + [| PUB | + KEY EC_KEY_get0_group :> GROUP + GROUP EC_GROUP_get_degree bits>bytes 1+ :> LEN + LEN :> BIN + GROUP PUB POINT_CONVERSION_COMPRESSED BIN LEN f + EC_POINT_point2oct ssl-error + BIN + ] when ; + +:: ecdsa-sign ( DGST -- sig ) + ec-key-handle :> KEY + KEY ECDSA_size dup ssl-error :> SIG + "uint" :> LEN + 0 DGST dup length SIG LEN KEY ECDSA_sign ssl-error + LEN *uint SIG resize ; + +: ecdsa-verify ( dgst sig -- ? ) + ec-key-handle [ 0 -rot [ dup length ] bi@ ] dip ECDSA_verify 0 > ; \ No newline at end of file diff --git a/extra/ecdsa/summary.txt b/extra/ecdsa/summary.txt new file mode 100644 index 0000000000..8f952c36a5 --- /dev/null +++ b/extra/ecdsa/summary.txt @@ -0,0 +1 @@ +Elliptic Curve Digital Signature Algorithm (OpenSSL realisation)