diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/ec/ec_local.h | 5 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ec_mult.c | 203 |
2 files changed, 2 insertions, 206 deletions
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h index c827a8f708..d178665c1f 100644 --- a/src/lib/libcrypto/ec/ec_local.h +++ b/src/lib/libcrypto/ec/ec_local.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_local.h,v 1.14 2023/06/12 18:17:18 jsing Exp $ */ | 1 | /* $OpenBSD: ec_local.h,v 1.15 2023/06/24 17:18:15 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Originally written by Bodo Moeller for the OpenSSL project. | 3 | * Originally written by Bodo Moeller for the OpenSSL project. |
| 4 | */ | 4 | */ |
| @@ -308,9 +308,6 @@ struct ec_point_st { | |||
| 308 | * (ec_lib.c uses these as defaults if group->method->mul is 0) */ | 308 | * (ec_lib.c uses these as defaults if group->method->mul is 0) */ |
| 309 | int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | 309 | int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, |
| 310 | size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); | 310 | size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); |
| 311 | int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); | ||
| 312 | int ec_wNAF_have_precompute_mult(const EC_GROUP *group); | ||
| 313 | |||
| 314 | 311 | ||
| 315 | /* method functions in ecp_smpl.c */ | 312 | /* method functions in ecp_smpl.c */ |
| 316 | int ec_GFp_simple_group_init(EC_GROUP *); | 313 | int ec_GFp_simple_group_init(EC_GROUP *); |
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c index b70e60a1b4..61428eb142 100644 --- a/src/lib/libcrypto/ec/ec_mult.c +++ b/src/lib/libcrypto/ec/ec_mult.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_mult.c,v 1.29 2023/04/11 18:58:20 jsing Exp $ */ | 1 | /* $OpenBSD: ec_mult.c,v 1.30 2023/06/24 17:18:15 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. | 3 | * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. |
| 4 | */ | 4 | */ |
| @@ -97,29 +97,6 @@ static void *ec_pre_comp_dup(void *); | |||
| 97 | static void ec_pre_comp_free(void *); | 97 | static void ec_pre_comp_free(void *); |
| 98 | static void ec_pre_comp_clear_free(void *); | 98 | static void ec_pre_comp_clear_free(void *); |
| 99 | 99 | ||
| 100 | static EC_PRE_COMP * | ||
| 101 | ec_pre_comp_new(const EC_GROUP *group) | ||
| 102 | { | ||
| 103 | EC_PRE_COMP *ret = NULL; | ||
| 104 | |||
| 105 | if (!group) | ||
| 106 | return NULL; | ||
| 107 | |||
| 108 | ret = malloc(sizeof(EC_PRE_COMP)); | ||
| 109 | if (!ret) { | ||
| 110 | ECerror(ERR_R_MALLOC_FAILURE); | ||
| 111 | return ret; | ||
| 112 | } | ||
| 113 | ret->group = group; | ||
| 114 | ret->blocksize = 8; /* default */ | ||
| 115 | ret->numblocks = 0; | ||
| 116 | ret->w = 4; /* default */ | ||
| 117 | ret->points = NULL; | ||
| 118 | ret->num = 0; | ||
| 119 | ret->references = 1; | ||
| 120 | return ret; | ||
| 121 | } | ||
| 122 | |||
| 123 | static void * | 100 | static void * |
| 124 | ec_pre_comp_dup(void *src_) | 101 | ec_pre_comp_dup(void *src_) |
| 125 | { | 102 | { |
| @@ -693,181 +670,3 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | |||
| 693 | free(val_sub); | 670 | free(val_sub); |
| 694 | return ret; | 671 | return ret; |
| 695 | } | 672 | } |
| 696 | |||
| 697 | |||
| 698 | /* ec_wNAF_precompute_mult() | ||
| 699 | * creates an EC_PRE_COMP object with preprecomputed multiples of the generator | ||
| 700 | * for use with wNAF splitting as implemented in ec_wNAF_mul(). | ||
| 701 | * | ||
| 702 | * 'pre_comp->points' is an array of multiples of the generator | ||
| 703 | * of the following form: | ||
| 704 | * points[0] = generator; | ||
| 705 | * points[1] = 3 * generator; | ||
| 706 | * ... | ||
| 707 | * points[2^(w-1)-1] = (2^(w-1)-1) * generator; | ||
| 708 | * points[2^(w-1)] = 2^blocksize * generator; | ||
| 709 | * points[2^(w-1)+1] = 3 * 2^blocksize * generator; | ||
| 710 | * ... | ||
| 711 | * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator | ||
| 712 | * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator | ||
| 713 | * ... | ||
| 714 | * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator | ||
| 715 | * points[2^(w-1)*numblocks] = NULL | ||
| 716 | */ | ||
| 717 | int | ||
| 718 | ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) | ||
| 719 | { | ||
| 720 | const EC_POINT *generator; | ||
| 721 | EC_POINT *tmp_point = NULL, *base = NULL, **var; | ||
| 722 | BIGNUM *order; | ||
| 723 | size_t i, bits, w, pre_points_per_block, blocksize, numblocks, | ||
| 724 | num; | ||
| 725 | EC_POINT **points = NULL; | ||
| 726 | EC_PRE_COMP *pre_comp; | ||
| 727 | int ret = 0; | ||
| 728 | |||
| 729 | /* if there is an old EC_PRE_COMP object, throw it away */ | ||
| 730 | EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free); | ||
| 731 | |||
| 732 | if ((pre_comp = ec_pre_comp_new(group)) == NULL) | ||
| 733 | return 0; | ||
| 734 | |||
| 735 | generator = EC_GROUP_get0_generator(group); | ||
| 736 | if (generator == NULL) { | ||
| 737 | ECerror(EC_R_UNDEFINED_GENERATOR); | ||
| 738 | goto err; | ||
| 739 | } | ||
| 740 | |||
| 741 | BN_CTX_start(ctx); | ||
| 742 | |||
| 743 | if ((order = BN_CTX_get(ctx)) == NULL) | ||
| 744 | goto err; | ||
| 745 | |||
| 746 | if (!EC_GROUP_get_order(group, order, ctx)) | ||
| 747 | goto err; | ||
| 748 | if (BN_is_zero(order)) { | ||
| 749 | ECerror(EC_R_UNKNOWN_ORDER); | ||
| 750 | goto err; | ||
| 751 | } | ||
| 752 | bits = BN_num_bits(order); | ||
| 753 | /* | ||
| 754 | * The following parameters mean we precompute (approximately) one | ||
| 755 | * point per bit. | ||
| 756 | * | ||
| 757 | * TBD: The combination 8, 4 is perfect for 160 bits; for other bit | ||
| 758 | * lengths, other parameter combinations might provide better | ||
| 759 | * efficiency. | ||
| 760 | */ | ||
| 761 | blocksize = 8; | ||
| 762 | w = 4; | ||
| 763 | if (EC_window_bits_for_scalar_size(bits) > w) { | ||
| 764 | /* let's not make the window too small ... */ | ||
| 765 | w = EC_window_bits_for_scalar_size(bits); | ||
| 766 | } | ||
| 767 | numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks | ||
| 768 | * to use for wNAF | ||
| 769 | * splitting */ | ||
| 770 | |||
| 771 | pre_points_per_block = (size_t) 1 << (w - 1); | ||
| 772 | num = pre_points_per_block * numblocks; /* number of points to | ||
| 773 | * compute and store */ | ||
| 774 | |||
| 775 | points = reallocarray(NULL, (num + 1), sizeof(EC_POINT *)); | ||
| 776 | if (!points) { | ||
| 777 | ECerror(ERR_R_MALLOC_FAILURE); | ||
| 778 | goto err; | ||
| 779 | } | ||
| 780 | var = points; | ||
| 781 | var[num] = NULL; /* pivot */ | ||
| 782 | for (i = 0; i < num; i++) { | ||
| 783 | if ((var[i] = EC_POINT_new(group)) == NULL) { | ||
| 784 | ECerror(ERR_R_MALLOC_FAILURE); | ||
| 785 | goto err; | ||
| 786 | } | ||
| 787 | } | ||
| 788 | |||
| 789 | if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) { | ||
| 790 | ECerror(ERR_R_MALLOC_FAILURE); | ||
| 791 | goto err; | ||
| 792 | } | ||
| 793 | if (!EC_POINT_copy(base, generator)) | ||
| 794 | goto err; | ||
| 795 | |||
| 796 | /* do the precomputation */ | ||
| 797 | for (i = 0; i < numblocks; i++) { | ||
| 798 | size_t j; | ||
| 799 | |||
| 800 | if (!EC_POINT_dbl(group, tmp_point, base, ctx)) | ||
| 801 | goto err; | ||
| 802 | |||
| 803 | if (!EC_POINT_copy(*var++, base)) | ||
| 804 | goto err; | ||
| 805 | |||
| 806 | for (j = 1; j < pre_points_per_block; j++, var++) { | ||
| 807 | /* calculate odd multiples of the current base point */ | ||
| 808 | if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) | ||
| 809 | goto err; | ||
| 810 | } | ||
| 811 | |||
| 812 | if (i < numblocks - 1) { | ||
| 813 | /* | ||
| 814 | * get the next base (multiply current one by | ||
| 815 | * 2^blocksize) | ||
| 816 | */ | ||
| 817 | size_t k; | ||
| 818 | |||
| 819 | if (blocksize <= 2) { | ||
| 820 | ECerror(ERR_R_INTERNAL_ERROR); | ||
| 821 | goto err; | ||
| 822 | } | ||
| 823 | if (!EC_POINT_dbl(group, base, tmp_point, ctx)) | ||
| 824 | goto err; | ||
| 825 | for (k = 2; k < blocksize; k++) { | ||
| 826 | if (!EC_POINT_dbl(group, base, base, ctx)) | ||
| 827 | goto err; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | } | ||
| 831 | |||
| 832 | if (!EC_POINTs_make_affine(group, num, points, ctx)) | ||
| 833 | goto err; | ||
| 834 | |||
| 835 | pre_comp->group = group; | ||
| 836 | pre_comp->blocksize = blocksize; | ||
| 837 | pre_comp->numblocks = numblocks; | ||
| 838 | pre_comp->w = w; | ||
| 839 | pre_comp->points = points; | ||
| 840 | points = NULL; | ||
| 841 | pre_comp->num = num; | ||
| 842 | |||
| 843 | if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp, | ||
| 844 | ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free)) | ||
| 845 | goto err; | ||
| 846 | pre_comp = NULL; | ||
| 847 | |||
| 848 | ret = 1; | ||
| 849 | |||
| 850 | err: | ||
| 851 | BN_CTX_end(ctx); | ||
| 852 | ec_pre_comp_free(pre_comp); | ||
| 853 | if (points) { | ||
| 854 | EC_POINT **p; | ||
| 855 | |||
| 856 | for (p = points; *p != NULL; p++) | ||
| 857 | EC_POINT_free(*p); | ||
| 858 | free(points); | ||
| 859 | } | ||
| 860 | EC_POINT_free(tmp_point); | ||
| 861 | EC_POINT_free(base); | ||
| 862 | return ret; | ||
| 863 | } | ||
| 864 | |||
| 865 | |||
| 866 | int | ||
| 867 | ec_wNAF_have_precompute_mult(const EC_GROUP *group) | ||
| 868 | { | ||
| 869 | if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL) | ||
| 870 | return 1; | ||
| 871 | else | ||
| 872 | return 0; | ||
| 873 | } | ||
