
#use wml::openssl-macros area=docs page=ecdsa

<title>Documents, ecdsa(3)</title>

<h1>ecdsa(3)</h1>

#use wml::imp::generic

{:
## What's this? [[s|(<STRONG>[^<].+?)</A>(</STRONG><DD>)|$1$2|sg]]
[[s|<P>\s+<P>|<P>|sg]]
[[s|<P>\s+</|</|sg]]
[[s|<DD>\s*<DT>|<DD>&nbsp;<DT>|sg]]
[[s|<DD>\s*</DL>|<DD>&nbsp;</DL>|sg]]
[[s|\[|&#91;|sg]]
[[s|\]|&#93;|sg]]

<!-- INDEX BEGIN -->

<UL>

	<LI><A HREF="#NAME">NAME</A>
	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
	<LI><A HREF="#RETURN_VALUES">RETURN VALUES</A>
	<LI><A HREF="#EXAMPLES">EXAMPLES</A>
	<LI><A HREF="#CONFORMING_TO">CONFORMING TO</A>
	<LI><A HREF="#SEE_ALSO">SEE ALSO</A>
	<LI><A HREF="#HISTORY">HISTORY</A>
	<LI><A HREF="#AUTHOR">AUTHOR</A>
</UL>
<!-- INDEX END -->

<HR>
<P>
<HR>
<H1><A NAME="NAME">NAME</A></H1>
<P>
ecdsa - Elliptic Curve Digital Signature Algorithm

</P>
<P>
<HR>
<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
<PRE> #include &lt;openssl/ecdsa.h&gt;
</PRE>
<PRE> ECDSA_SIG*     ECDSA_SIG_new(void);
 void           ECDSA_SIG_free(ECDSA_SIG *sig);
 int            i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
 ECDSA_SIG*     d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, 
                long len);
</PRE>
<PRE> ECDSA_SIG*     ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
                        EC_KEY *eckey);
 ECDSA_SIG*     ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
                        const BIGNUM *kinv, const BIGNUM *rp,
                        EC_KEY *eckey);
 int            ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
                        const ECDSA_SIG *sig, EC_KEY* eckey);
 int            ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx,
                        BIGNUM **kinv, BIGNUM **rp);
 int            ECDSA_sign(int type, const unsigned char *dgst,
                        int dgstlen, unsigned char *sig,
                        unsigned int *siglen, EC_KEY *eckey);
 int            ECDSA_sign_ex(int type, const unsigned char *dgst,
                        int dgstlen, unsigned char *sig,
                        unsigned int *siglen, const BIGNUM *kinv, 
                        const BIGNUM *rp, EC_KEY *eckey);
 int            ECDSA_verify(int type, const unsigned char *dgst,
                        int dgstlen, const unsigned char *sig,
                        int siglen, EC_KEY *eckey);
 int            ECDSA_size(const EC_KEY *eckey);
</PRE>
<PRE> const ECDSA_METHOD*    ECDSA_OpenSSL(void);
 void           ECDSA_set_default_method(const ECDSA_METHOD *meth);
 const ECDSA_METHOD*    ECDSA_get_default_method(void);
 int            ECDSA_set_method(EC_KEY *eckey,const ECDSA_METHOD *meth);
</PRE>
<PRE> int            ECDSA_get_ex_new_index(long argl, void *argp,
                        CRYPTO_EX_new *new_func,
                        CRYPTO_EX_dup *dup_func,
                        CRYPTO_EX_free *free_func);
 int            ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
 void*          ECDSA_get_ex_data(EC_KEY *d, int idx);
</PRE>
<P>
<HR>
<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
<P>
The <STRONG>ECDSA_SIG</STRONG> structure consists of two BIGNUMs for the r and s value of a ECDSA
signature (see X9.62 or FIPS 186-2).

</P>
<PRE> struct
        {
        BIGNUM *r;
        BIGNUM *s;
 } ECDSA_SIG;
</PRE>
<P>
<CODE>ECDSA_SIG_new()</CODE> allocates a new <STRONG>ECDSA_SIG</STRONG> structure (note: this function also allocates the BIGNUMs) and initialize
it.

</P>
<P>
<CODE>ECDSA_SIG_free()</CODE> frees the <STRONG>ECDSA_SIG</STRONG> structure <STRONG>sig</STRONG>.

</P>
<P>
<CODE>i2d_ECDSA_SIG()</CODE> creates the DER encoding of the ECDSA
signature
<STRONG>sig</STRONG> and writes the encoded signature to <STRONG>*pp</STRONG> (note: if <STRONG>pp</STRONG>
is NULL <STRONG>i2d_ECDSA_SIG</STRONG> returns the expected length in bytes of the DER encoded signature). <STRONG>i2d_ECDSA_SIG</STRONG> returns the length of the DER encoded signature (or 0 on error).

</P>
<P>
<CODE>d2i_ECDSA_SIG()</CODE> decodes a DER encoded ECDSA signature and
returns the decoded signature in a newly allocated <STRONG>ECDSA_SIG</STRONG> structure.
<STRONG>*sig</STRONG> points to the buffer containing the DER encoded signature of size <STRONG>len</STRONG>.

</P>
<P>
<CODE>ECDSA_size()</CODE> returns the maximum length of a DER encoded ECDSA
signature created with the private EC key <STRONG>eckey</STRONG>.

</P>
<P>
<CODE>ECDSA_sign_setup()</CODE> may be used to precompute parts of the
signing operation. <STRONG>eckey</STRONG> is the private EC key and <STRONG>ctx</STRONG>
is a pointer to <STRONG>BN_CTX</STRONG> structure (or NULL). The precomputed values or returned in <STRONG>kinv</STRONG> and <STRONG>rp</STRONG> and can be used in a later call to <STRONG>ECDSA_sign_ex</STRONG> or <STRONG>ECDSA_do_sign_ex</STRONG>.

</P>
<P>
<CODE>ECDSA_sign()</CODE> is wrapper function for ECDSA_sign_ex with <STRONG>kinv</STRONG>
and <STRONG>rp</STRONG> set to NULL.

</P>
<P>
<CODE>ECDSA_sign_ex()</CODE> computes a digital signature of the <STRONG>dgstlen</STRONG> bytes hash value <STRONG>dgst</STRONG> using the private EC key <STRONG>eckey</STRONG> and the optional pre-computed values <STRONG>kinv</STRONG> and <STRONG>rp</STRONG>. The DER encoded signatures is stored in <STRONG>sig</STRONG> and it's length is returned in <STRONG>sig_len</STRONG>. Note: <STRONG>sig</STRONG>
must point to <STRONG>ECDSA_size</STRONG> bytes of memory. The parameter <STRONG>type</STRONG>
is ignored.

</P>
<P>
<CODE>ECDSA_verify()</CODE> verifies that the signature in <STRONG>sig</STRONG> of size
<STRONG>siglen</STRONG> is a valid ECDSA signature of the hash value value <STRONG>dgst</STRONG> of size <STRONG>dgstlen</STRONG> using the public key <STRONG>eckey</STRONG>. The parameter <STRONG>type</STRONG> is ignored.

</P>
<P>
<CODE>ECDSA_do_sign()</CODE> is wrapper function for ECDSA_do_sign_ex with <STRONG>kinv</STRONG>
and <STRONG>rp</STRONG> set to NULL.

</P>
<P>
<CODE>ECDSA_do_sign_ex()</CODE> computes a digital signature of the <STRONG>dgst_len</STRONG>
bytes hash value <STRONG>dgst</STRONG> using the private key <STRONG>eckey</STRONG> and the optional pre-computed values <STRONG>kinv</STRONG> and <STRONG>rp</STRONG>. The signature is returned in a newly allocated <STRONG>ECDSA_SIG</STRONG> structure (or NULL on error).

</P>
<P>
<CODE>ECDSA_do_verify()</CODE> verifies that the signature <STRONG>sig</STRONG> is a valid ECDSA signature of the hash value <STRONG>dgst</STRONG> of size <STRONG>dgst_len</STRONG>
using the public key <STRONG>eckey</STRONG>.

</P>
<P>
<HR>
<H1><A NAME="RETURN_VALUES">RETURN VALUES</A></H1>
<P>
<CODE>ECDSA_size()</CODE> returns the maximum length signature or 0 on
error.

</P>
<P>
<CODE>ECDSA_sign_setup()</CODE> and <CODE>ECDSA_sign()</CODE> return 1 if
successful or 0 on error.

</P>
<P>
<CODE>ECDSA_verify()</CODE> and <CODE>ECDSA_do_verify()</CODE> return 1 for
a valid signature, 0 for an invalid signature and -1 on error. The error
codes can be obtained by <A HREF="../crypto/ERR_get_error.html#">ERR_get_error(3)</A>.

</P>
<P>
<HR>
<H1><A NAME="EXAMPLES">EXAMPLES</A></H1>
<P>
Creating a ECDSA signature of given SHA-1 hash value using the named curve
secp192k1.

</P>
<P>
First step: create a EC_KEY object (note: this part is <STRONG>not</STRONG> ECDSA specific)

</P>
<PRE> int        ret;
 ECDSA_SIG *sig;
 EC_KEY    *eckey = EC_KEY_new();
 if (eckey == NULL)
        {
        /* error */
        }
 key-&gt;group = EC_GROUP_new_by_nid(NID_secp192k1);
 if (key-&gt;group == NULL)
        {
        /* error */
        }
 if (!EC_KEY_generate_key(eckey))
        {
        /* error */
        }
</PRE>
<P>
Second step: compute the ECDSA signature of a SHA-1 hash value using <STRONG>ECDSA_do_sign</STRONG> 

 

</P>
<PRE> sig = ECDSA_do_sign(digest, 20, eckey);
 if (sig == NULL)
        {
        /* error */
        }
</PRE>
<P>
or using <STRONG>ECDSA_sign</STRONG>



</P>
<PRE> unsigned char *buffer, *pp;
 int            buf_len;
 buf_len = ECDSA_size(eckey);
 buffer  = OPENSSL_malloc(buf_len);
 pp = buffer;
 if (!ECDSA_sign(0, dgst, dgstlen, pp, &amp;buf_len, eckey);
        {
        /* error */
        }
</PRE>
<P>
Third step: verify the created ECDSA signature using <STRONG>ECDSA_do_verify</STRONG>



</P>
<PRE> ret = ECDSA_do_verify(digest, 20, sig, eckey);
</PRE>
<P>
or using <STRONG>ECDSA_verify</STRONG>



</P>
<PRE> ret = ECDSA_verify(0, digest, 20, buffer, buf_len, eckey);
</PRE>
<P>
and finally evaluate the return value:

</P>
<PRE> if (ret == -1)
        {
        /* error */
        }
 else if (ret == 0)
        {
        /* incorrect signature */
        }
 else   /* ret == 1 */
        {
        /* signature ok */
        }
</PRE>
<P>
<HR>
<H1><A NAME="CONFORMING_TO">CONFORMING TO</A></H1>
<P>
ANSI X9.62, US Federal Information Processing Standard FIPS 186-2 (Digital
Signature Standard, DSS)

</P>
<P>
<HR>
<H1><A NAME="SEE_ALSO">SEE ALSO</A></H1>
<P>
<A HREF="../crypto/dsa.html#">dsa(3)</A>, <A HREF="../crypto/rsa.html#">rsa(3)</A>



</P>
<P>
<HR>
<H1><A NAME="HISTORY">HISTORY</A></H1>
<P>
The ecdsa implementation was first introduced in OpenSSL 0.9.8

</P>
<P>
<HR>
<H1><A NAME="AUTHOR">AUTHOR</A></H1>
<P>
Nils Larsch for the OpenSSL project (http://www.openssl.org).

</P>
:}


