On 24/05/12 14:40, Khuc, Chuong D. wrote:
Hello,
I was able to sign my message using the ECDSA 256 function from openssl:
ECDSA_SIG *signature = ECDSA_do_sign( &message[0], message_length, eckey);
And the sign is verified to be valid also. And my question is about
the compression of the signature. I understand that the signature has
an r value and an s value. And there is a way to compress the r value
to a temporary elliptic curve point R. And the value of curve point R
is dependent on the LSB of the y-coordinate somehow. So does anyone
know how to go from (r, s) to a compressed (R,s) in openssl? Thank you
very much.
Regards,
Chuong D. Khuc
I think perhaps your are confusing a couple of things.
A point on an elliptic curve has an x and a y co-ordinate. The ECDSA
signing algorithm constructs a random point on the curve, (what you
called R), performs various calculations and then emits r and s. The
value r is simply the x co-ordinate of the random point without the y
value - so in that sense it is already "compressed".
However what you are describing sounds to me like the point compression
that you can perform on an ECDSA curve generator (or in fact any point
on the curve including the public key). The generator forms part of the
ECDSA parameters.
A point on the curve simply consists of its x and y co-ordinates. Now
for any given x co-ordinate of a valid point on the curve there cannot
be more than 2 valid y co-ordinates and so it turns out that it is
sufficient to only hold the least significant bit of y to distinguish
between the two possibilities.
ECDSA recognises three ways of encoding a point: compressed,
uncompressed and hybrid. This is represented by the
point_conversion_form_t enum in OpenSSL (defined in ec.h):
typedef enum {
/** the point is encoded as z||x, where the octet z specifies
* which solution of the quadratic equation y is */
POINT_CONVERSION_COMPRESSED = 2,
/** the point is encoded as z||x||y, where z is the octet 0x02 */
POINT_CONVERSION_UNCOMPRESSED = 4,
/** the point is encoded as z||x||y, where the octet z specifies
* which solution of the quadratic equation y is */
POINT_CONVERSION_HYBRID = 6
} point_conversion_form_t;
If you want to use compressed form for points you can do so by using the
following function:
void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
There is also an equivalent "get" function:
point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
These functions just call the similar functions defined on the
underlying EC_GROUP object (i.e. the curve itself). This only makes a
difference when a point is converted into some external format. For
example it is used when calling the following:
int i2d_ECPKParameters(const EC_GROUP *x, unsigned char **out);
This creates a DER encoded structure to hold the public parameters for
the curve - including the generator encoded according to the point
conversion form that you specified.
Similarly the following function DER encodes a private key (which is
just a number), along with the public key (which is a point). The public
key will be encoded according to the point conversion form that you
specified:
int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
You can also encode EC_POINT objects directly using:
BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form, BIGNUM *, BN_CTX *);
or
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *ctx);
These convert an EC_POINT object (such as a public key) into a BIGNUM
or an octet string respectively, encoded according to the specified
point conversion form.
Hope that helps,
Matt
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org