637
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
638
const BIGNUM *x_, int y_bit, BN_CTX *ctx)
640
BN_CTX *new_ctx = NULL;
641
BIGNUM *tmp1, *tmp2, *x, *y;
644
/* clear error queue*/
649
ctx = new_ctx = BN_CTX_new();
654
y_bit = (y_bit != 0);
657
tmp1 = BN_CTX_get(ctx);
658
tmp2 = BN_CTX_get(ctx);
661
if (y == NULL) goto err;
663
/* Recover y. We have a Weierstrass equation
664
* y^2 = x^3 + a*x + b,
665
* so y is one of the square roots of x^3 + a*x + b.
669
if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
670
if (group->meth->field_decode == 0)
672
/* field_{sqr,mul} work on standard representation */
673
if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
674
if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
678
if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
679
if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
682
/* tmp1 := tmp1 + a*x */
683
if (group->a_is_minus3)
685
if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
686
if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
687
if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
691
if (group->meth->field_decode)
693
if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
694
if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
698
/* field_mul works on standard representation */
699
if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
702
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
705
/* tmp1 := tmp1 + b */
706
if (group->meth->field_decode)
708
if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
709
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
713
if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
716
if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
718
unsigned long err = ERR_peek_last_error();
720
if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
723
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
726
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
730
if (y_bit != BN_is_odd(y))
736
kron = BN_kronecker(x, &group->field, ctx);
737
if (kron == -2) goto err;
740
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
742
/* BN_mod_sqrt() should have cought this error (not a square) */
743
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
746
if (!BN_usub(y, &group->field, y)) goto err;
748
if (y_bit != BN_is_odd(y))
750
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
754
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
761
BN_CTX_free(new_ctx);
766
size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
767
unsigned char *buf, size_t len, BN_CTX *ctx)
770
BN_CTX *new_ctx = NULL;
773
size_t field_len, i, skip;
775
if ((form != POINT_CONVERSION_COMPRESSED)
776
&& (form != POINT_CONVERSION_UNCOMPRESSED)
777
&& (form != POINT_CONVERSION_HYBRID))
779
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
783
if (EC_POINT_is_at_infinity(group, point))
785
/* encodes to a single 0 octet */
790
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
799
/* ret := required output buffer length */
800
field_len = BN_num_bytes(&group->field);
801
ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
803
/* if 'buf' is NULL, just return required length */
808
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
814
ctx = new_ctx = BN_CTX_new();
823
if (y == NULL) goto err;
825
if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
827
if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
834
skip = field_len - BN_num_bytes(x);
835
if (skip > field_len)
837
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
845
skip = BN_bn2bin(x, buf + i);
847
if (i != 1 + field_len)
849
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
853
if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
855
skip = field_len - BN_num_bytes(y);
856
if (skip > field_len)
858
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
866
skip = BN_bn2bin(y, buf + i);
872
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
880
BN_CTX_free(new_ctx);
887
BN_CTX_free(new_ctx);
892
int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
893
const unsigned char *buf, size_t len, BN_CTX *ctx)
895
point_conversion_form_t form;
897
BN_CTX *new_ctx = NULL;
899
size_t field_len, enc_len;
904
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
910
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
911
&& (form != POINT_CONVERSION_UNCOMPRESSED)
912
&& (form != POINT_CONVERSION_HYBRID))
914
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
917
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
919
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
927
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
931
return EC_POINT_set_to_infinity(group, point);
934
field_len = BN_num_bytes(&group->field);
935
enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
939
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
945
ctx = new_ctx = BN_CTX_new();
953
if (y == NULL) goto err;
955
if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
956
if (BN_ucmp(x, &group->field) >= 0)
958
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
962
if (form == POINT_CONVERSION_COMPRESSED)
964
if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
968
if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
969
if (BN_ucmp(y, &group->field) >= 0)
971
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
974
if (form == POINT_CONVERSION_HYBRID)
976
if (y_bit != BN_is_odd(y))
978
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
983
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
986
if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
988
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
997
BN_CTX_free(new_ctx);
1002
643
int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
1004
645
int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);