Wow, that is a lot of good information. Thanks, Matt. And I am still trying to 
digest the first paragraph. So do you mean the R value that I mentioned is 
actually the public key? And if I was provided
with a private key, are the following lines of code appropriate to compute
the public key and get its x-y coordinates?

EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
  if(eckey == NULL)
  {
    printf("ERROR: NULL EC_KEY!\r\n");
  }
  else
  {
    BIGNUM *retbn;
    retbn =  BN_bin2bn(tempkey,32,NULL); // tempkey is an array of 32 u_char
    if(EC_KEY_set_private_key(eckey,retbn)!=1)
    {
      printf("ERROR: Fail to set private key!\r\n");
    }
    EC_POINT* pub_key = EC_POINT_new(EC_KEY_get0_group(eckey));
    if(EC_POINT_mul(EC_KEY_get0_group(eckey),pub_key,retbn,NULL,NULL,NULL) != 1)
    {
      printf("ERROR: Fail to generate public key!\r\n");
    }
    if(EC_KEY_set_public_key(eckey,pub_key) != 1)
    {
      printf("ERROR: Can't set public key!\r\n");
    }
  BIGNUM *x_coord = BN_new();
  BIGNUM *y_coord = BN_new();
// IS THIS THE RIGHT WAY TO GET X-Y COORDINATES?
  if(EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey),
         EC_KEY_get0_public_keyeckey), x_coord, y_coord, NULL)!=1)
  {
    printf("ERROR: Fail to get affine coordinates!\r\n");
  }
}

Regards,
 
Chuong D. Khuc




On 5/24/12 5:40 PM, "Matt Caswell (fr...@baggins.org)" <fr...@baggins.org>
wrote:

>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                           
>majordomo@openssl.org______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to