diff options
author | Pedram Fardzadeh <p.fardzadeh@protonmail.com> | 2024-03-11 23:57:29 +0100 |
---|---|---|
committer | t3serakt <t3ss@posteo.de> | 2024-04-10 20:14:53 +0200 |
commit | 934f9aaa70222bf61363e6833c2c4592a076abce (patch) | |
tree | 3fc5c7613a90847f7d1e2fb9c279c23ec65441a6 | |
parent | c810e726b3d67a9bd09b714ed32acf92883fdf67 (diff) | |
download | gnunet-934f9aaa70222bf61363e6833c2c4592a076abce.tar.gz gnunet-934f9aaa70222bf61363e6833c2c4592a076abce.zip |
elligator: API changes for encoding + function documentations
-rw-r--r-- | src/include/gnunet_crypto_lib.h | 46 | ||||
-rw-r--r-- | src/lib/util/crypto_elligator.c | 175 | ||||
-rw-r--r-- | src/lib/util/test_crypto_elligator.c | 88 |
3 files changed, 157 insertions, 152 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 53150bedc..50937324d 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -2664,22 +2664,6 @@ GNUNET_CRYPTO_edx25519_public_key_derive ( | |||
2664 | size_t seedsize, | 2664 | size_t seedsize, |
2665 | struct GNUNET_CRYPTO_Edx25519PublicKey *result); | 2665 | struct GNUNET_CRYPTO_Edx25519PublicKey *result); |
2666 | 2666 | ||
2667 | /** | ||
2668 | * Note: Included in header for testing purposes. GNUNET_CRYPTO_ecdhe_elligator_decoding will be the correct API for the direct map. | ||
2669 | * TODO: Make static. | ||
2670 | * @ingroup crypto | ||
2671 | * Encodes an element of the underlying finite field, so called representative, of Curve25519 to a point on the curve | ||
2672 | * This transformation is deterministic | ||
2673 | * | ||
2674 | * @param representative element of the finite field | ||
2675 | * @param point destination for the calculated point on the curve | ||
2676 | * @param high_y destination set to "True" if corresponding y-coordinate is > 2 ^ 254 - 10 | ||
2677 | */ | ||
2678 | bool | ||
2679 | GNUNET_CRYPTO_ecdhe_elligator_direct_map (uint8_t *point, | ||
2680 | bool *high_y, | ||
2681 | uint8_t *representative); | ||
2682 | |||
2683 | 2667 | ||
2684 | /** | 2668 | /** |
2685 | * @ingroup crypto | 2669 | * @ingroup crypto |
@@ -2687,9 +2671,9 @@ GNUNET_CRYPTO_ecdhe_elligator_direct_map (uint8_t *point, | |||
2687 | * | 2671 | * |
2688 | * @param representative serialized elligator representative of an element of Curves25519's finite field | 2672 | * @param representative serialized elligator representative of an element of Curves25519's finite field |
2689 | * @param point destination for the calculated point on the curve | 2673 | * @param point destination for the calculated point on the curve |
2690 | * @param high_y value pointed to will be set to true if corresponding y-coordinate is > 2 ^ 254 - 10, otherwise 0. Can be set to NULL if not needed. | 2674 | * @param high_y bool pointed to will be set to 'true' if corresponding y-coordinate is > 2 ^ 254 - 10, otherwise 0. Can be set to NULL if not needed. |
2691 | */ | 2675 | */ |
2692 | bool | 2676 | void |
2693 | GNUNET_CRYPTO_ecdhe_elligator_decoding ( | 2677 | GNUNET_CRYPTO_ecdhe_elligator_decoding ( |
2694 | struct GNUNET_CRYPTO_EcdhePublicKey *point, | 2678 | struct GNUNET_CRYPTO_EcdhePublicKey *point, |
2695 | bool *high_y, | 2679 | bool *high_y, |
@@ -2697,23 +2681,25 @@ GNUNET_CRYPTO_ecdhe_elligator_decoding ( | |||
2697 | 2681 | ||
2698 | /** | 2682 | /** |
2699 | * @ingroup crypto | 2683 | * @ingroup crypto |
2700 | * Encodes a point on Curve25519 to a an element of the underlying finite field | 2684 | * Encodes a point on Curve25519 to a an element of the underlying finite field. |
2701 | * This transformation is deterministic | 2685 | * This transformation is deterministic. |
2702 | * | 2686 | * |
2703 | * @param point a point on the curve | 2687 | * @param r storage for the calculated representative |
2688 | * @param pub a point on the curve | ||
2704 | * @param high_y encodes if y-coordinate is > 2 ^254 - 10, which determines the representative value out of two | 2689 | * @param high_y encodes if y-coordinate is > 2 ^254 - 10, which determines the representative value out of two |
2705 | * @param representative destination for the calculated element of the finite field | 2690 | * @return 'true' if the given point can be encoded into a representative. Otherwise 'false' is returned and the content of the representative storage is undefined |
2706 | */ | 2691 | */ |
2707 | bool | 2692 | bool |
2708 | GNUNET_CRYPTO_ecdhe_elligator_inverse_map (uint8_t *representative, | 2693 | GNUNET_CRYPTO_ecdhe_elligator_encoding ( |
2709 | const uint8_t *point, | 2694 | struct GNUNET_CRYPTO_ElligatorRepresentative *r, |
2710 | bool high_y); | 2695 | const struct GNUNET_CRYPTO_EcdhePublicKey *pub, |
2696 | bool high_y); | ||
2711 | 2697 | ||
2712 | 2698 | ||
2713 | /** | 2699 | /** |
2714 | * @ingroup crypto | 2700 | * @ingroup crypto |
2715 | * Generates a valid public key for elligator's inverse map by adding a lower order point to a prime order point | 2701 | * Generates a valid public key for elligator's inverse map by adding a lower order point to a prime order point. |
2716 | * following Method 1 in description https://elligator.org/key-exchange section Step 2: Generate a “special” public key | 2702 | * Following Method 1 in description https://elligator.org/key-exchange section Step 2: Generate a “special” public key. |
2717 | * | 2703 | * |
2718 | * @param pub valid public key for elligator inverse map | 2704 | * @param pub valid public key for elligator inverse map |
2719 | * @param pk private key for generating valid public key | 2705 | * @param pk private key for generating valid public key |
@@ -2727,7 +2713,7 @@ GNUNET_CRYPTO_ecdhe_elligator_generate_public_key ( | |||
2727 | 2713 | ||
2728 | /** | 2714 | /** |
2729 | * @ingroup crypto | 2715 | * @ingroup crypto |
2730 | * Generates a private key for Curve25519 and the elligator representative of the corresponding public key | 2716 | * Generates a private key for Curve25519 and the elligator representative of the corresponding public key. |
2731 | * | 2717 | * |
2732 | * @param repr representative of the public key | 2718 | * @param repr representative of the public key |
2733 | * @param pk Curve25519 private key | 2719 | * @param pk Curve25519 private key |
@@ -2740,8 +2726,8 @@ GNUNET_CRYPTO_ecdhe_elligator_key_create ( | |||
2740 | /** | 2726 | /** |
2741 | * @ingroup crypto | 2727 | * @ingroup crypto |
2742 | * Carries out ecdh encapsulation with given public key and the private key from a freshly created ephemeral key pair. | 2728 | * Carries out ecdh encapsulation with given public key and the private key from a freshly created ephemeral key pair. |
2729 | * Following the terminology in https://eprint.iacr.org/2021/509.pdf. | ||
2743 | * | 2730 | * |
2744 | * Following the terminology in https://eprint.iacr.org/2021/509.pdf | ||
2745 | * @param pub given edwards curve public key (X) | 2731 | * @param pub given edwards curve public key (X) |
2746 | * @param r representative of ephemeral public key A to use for the ECDH (direct_map(r)=A=aG) | 2732 | * @param r representative of ephemeral public key A to use for the ECDH (direct_map(r)=A=aG) |
2747 | * @param key_material where to write the key material H(aX)=H(x(aG)) | 2733 | * @param key_material where to write the key material H(aX)=H(x(aG)) |
@@ -2756,8 +2742,8 @@ GNUNET_CRYPTO_eddsa_elligator_kem_encaps ( | |||
2756 | /** | 2742 | /** |
2757 | * @ingroup crypto | 2743 | * @ingroup crypto |
2758 | * Carries out ecdh decapsulation with own private key and the representative of the received public key. | 2744 | * Carries out ecdh decapsulation with own private key and the representative of the received public key. |
2745 | * Following the terminology in https://eprint.iacr.org/2021/509.pdf. | ||
2759 | * | 2746 | * |
2760 | * Following the terminology in https://eprint.iacr.org/2021/509.pdf | ||
2761 | * @param priv own private key (x) | 2747 | * @param priv own private key (x) |
2762 | * @param r received representative r, from which we can obtain the public key A (direct_map(r)=A=aG) | 2748 | * @param r received representative r, from which we can obtain the public key A (direct_map(r)=A=aG) |
2763 | * @param key_material where to write the key material H(xA)=H(a(xG)) | 2749 | * @param key_material where to write the key material H(xA)=H(a(xG)) |
diff --git a/src/lib/util/crypto_elligator.c b/src/lib/util/crypto_elligator.c index 11bc086a9..91db517b0 100644 --- a/src/lib/util/crypto_elligator.c +++ b/src/lib/util/crypto_elligator.c | |||
@@ -95,87 +95,87 @@ static const uint8_t lookupTable[8][crypto_scalarmult_SCALARBYTES] = { | |||
95 | 95 | ||
96 | // main.c from Kleshnis's elligator implementation | 96 | // main.c from Kleshnis's elligator implementation |
97 | static const unsigned char p_bytes[P_BYTES] = { | 97 | static const unsigned char p_bytes[P_BYTES] = { |
98 | 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 98 | 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
99 | 0xff, 0xff, 0xff, | 99 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
100 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 100 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
101 | 0xff, 0xff, 0x7f | 101 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f |
102 | }; | 102 | }; |
103 | 103 | ||
104 | static const unsigned char negative_1_bytes[P_BYTES] = { | 104 | static const unsigned char negative_1_bytes[P_BYTES] = { |
105 | 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 105 | 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
106 | 0xff, 0xff, 0xff, | 106 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
107 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 107 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
108 | 0xff, 0xff, 0x7f | 108 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f |
109 | }; | 109 | }; |
110 | 110 | ||
111 | static const unsigned char negative_2_bytes[P_BYTES] = { | 111 | static const unsigned char negative_2_bytes[P_BYTES] = { |
112 | 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 112 | 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
113 | 0xff, 0xff, 0xff, | 113 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
114 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 114 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
115 | 0xff, 0xff, 0x7f | 115 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static const unsigned char divide_negative_1_2_bytes[P_BYTES] = { | 118 | static const unsigned char divide_negative_1_2_bytes[P_BYTES] = { |
119 | 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 119 | 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
120 | 0xff, 0xff, 0xff, | 120 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
121 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 121 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
122 | 0xff, 0xff, 0x3f | 122 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f |
123 | }; | 123 | }; |
124 | 124 | ||
125 | static const unsigned char divide_plus_p_3_8_bytes[P_BYTES] = { | 125 | static const unsigned char divide_plus_p_3_8_bytes[P_BYTES] = { |
126 | 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 126 | 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
127 | 0xff, 0xff, 0xff, | 127 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
128 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 128 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
129 | 0xff, 0xff, 0x0f | 129 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f |
130 | }; | 130 | }; |
131 | 131 | ||
132 | static const unsigned char divide_minus_p_1_2_bytes[P_BYTES] = { | 132 | static const unsigned char divide_minus_p_1_2_bytes[P_BYTES] = { |
133 | 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 133 | 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
134 | 0xff, 0xff, 0xff, | 134 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
135 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 135 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
136 | 0xff, 0xff, 0x3f | 136 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f |
137 | }; | 137 | }; |
138 | 138 | ||
139 | static const unsigned char square_root_negative_1_bytes[P_BYTES] = { | 139 | static const unsigned char square_root_negative_1_bytes[P_BYTES] = { |
140 | 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4, 0x78, 0xe4, 0x2f, 0xad, 0x06, | 140 | 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4, |
141 | 0x18, 0x43, 0x2f, | 141 | 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f, |
142 | 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b, 0x0b, 0xdf, 0xc1, 0x4f, 0x80, | 142 | 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b, |
143 | 0x24, 0x83, 0x2b | 143 | 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static const unsigned char A_bytes[P_BYTES] = { | 146 | static const unsigned char A_bytes[P_BYTES] = { |
147 | 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 147 | 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, |
148 | 0x00, 0x00, 0x00, | 148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
149 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 149 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
150 | 0x00, 0x00, 0x00 | 150 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static const unsigned char negative_A_bytes[P_BYTES] = { | 153 | static const unsigned char negative_A_bytes[P_BYTES] = { |
154 | 0xe7, 0x92, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 154 | 0xe7, 0x92, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, |
155 | 0xff, 0xff, 0xff, | 155 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
156 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 156 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
157 | 0xff, 0xff, 0x7f | 157 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static const unsigned char u_bytes[P_BYTES] = { | 160 | static const unsigned char u_bytes[P_BYTES] = { |
161 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 161 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
162 | 0x00, 0x00, 0x00, | 162 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
164 | 0x00, 0x00, 0x00 | 164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static const unsigned char inverted_u_bytes[P_BYTES] = { | 167 | static const unsigned char inverted_u_bytes[P_BYTES] = { |
168 | 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 168 | 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
169 | 0xff, 0xff, 0xff, | 169 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
170 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 170 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
171 | 0xff, 0xff, 0x3f | 171 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static const unsigned char d_bytes[P_BYTES] = { | 174 | static const unsigned char d_bytes[P_BYTES] = { |
175 | 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, | 175 | 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, |
176 | 0x0a, 0x70, 0x00, | 176 | 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, |
177 | 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b, 0xee, | 177 | 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, |
178 | 0x6c, 0x03, 0x52 | 178 | 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 |
179 | }; | 179 | }; |
180 | 180 | ||
181 | static mp_limb_t p[P_LIMBS]; | 181 | static mp_limb_t p[P_LIMBS]; |
@@ -193,6 +193,7 @@ static mp_limb_t d[P_LIMBS]; | |||
193 | 193 | ||
194 | static mp_size_t scratch_space_length; | 194 | static mp_size_t scratch_space_length; |
195 | 195 | ||
196 | // TODO | ||
196 | static void | 197 | static void |
197 | decode_bytes (mp_limb_t *number, const uint8_t *bytes) | 198 | decode_bytes (mp_limb_t *number, const uint8_t *bytes) |
198 | { | 199 | { |
@@ -206,8 +207,7 @@ decode_bytes (mp_limb_t *number, const uint8_t *bytes) | |||
206 | } | 207 | } |
207 | 208 | ||
208 | 209 | ||
209 | // Erases the number | 210 | // TODO |
210 | |||
211 | static void | 211 | static void |
212 | encode_bytes (uint8_t *bytes, mp_limb_t *number) | 212 | encode_bytes (uint8_t *bytes, mp_limb_t *number) |
213 | { | 213 | { |
@@ -218,6 +218,9 @@ encode_bytes (uint8_t *bytes, mp_limb_t *number) | |||
218 | } | 218 | } |
219 | 219 | ||
220 | 220 | ||
221 | /** | ||
222 | * Initialize elligator scratch space. | ||
223 | */ | ||
221 | void __attribute__ ((constructor)) | 224 | void __attribute__ ((constructor)) |
222 | GNUNET_CRYPTO_ecdhe_elligator_initialize () | 225 | GNUNET_CRYPTO_ecdhe_elligator_initialize () |
223 | { | 226 | { |
@@ -268,14 +271,12 @@ GNUNET_CRYPTO_ecdhe_elligator_initialize () | |||
268 | mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS), | 271 | mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS), |
269 | 272 | ||
270 | // For Elligator_2_Curve25519_convert_from_Ed25519 | 273 | // For Elligator_2_Curve25519_convert_from_Ed25519 |
271 | /* | ||
272 | mpn_sec_sqr_itch (P_LIMBS), | 274 | mpn_sec_sqr_itch (P_LIMBS), |
273 | mpn_sec_div_r_itch (P_LIMBS + P_LIMBS, P_LIMBS), | 275 | mpn_sec_div_r_itch (P_LIMBS + P_LIMBS, P_LIMBS), |
274 | mpn_sec_mul_itch (P_LIMBS, P_LIMBS), | 276 | mpn_sec_mul_itch (P_LIMBS, P_LIMBS), |
275 | mpn_sec_add_1_itch (P_LIMBS), | 277 | mpn_sec_add_1_itch (P_LIMBS), |
276 | mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS), | 278 | mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS), |
277 | mpn_sec_sub_1_itch (P_LIMBS) | 279 | mpn_sec_sub_1_itch (P_LIMBS) |
278 | */ | ||
279 | }; | 280 | }; |
280 | 281 | ||
281 | for (size_t i = 0; i < sizeof scratch_space_lengths | 282 | for (size_t i = 0; i < sizeof scratch_space_lengths |
@@ -291,8 +292,14 @@ GNUNET_CRYPTO_ecdhe_elligator_initialize () | |||
291 | } | 292 | } |
292 | 293 | ||
293 | 294 | ||
294 | // Returns trash if the number is a quadratic non-residue | 295 | /** |
295 | 296 | * Calculates the root of a given number. | |
297 | * Returns trash if the number is a quadratic non-residue. | ||
298 | * | ||
299 | * @param root storage for calculated root | ||
300 | * @param number value for which the root is calculated | ||
301 | * @param scratch_space buffer for calculation | ||
302 | */ | ||
296 | static void | 303 | static void |
297 | least_square_root (mp_limb_t *root, | 304 | least_square_root (mp_limb_t *root, |
298 | const mp_limb_t *number, | 305 | const mp_limb_t *number, |
@@ -332,10 +339,14 @@ least_square_root (mp_limb_t *root, | |||
332 | 339 | ||
333 | 340 | ||
334 | bool | 341 | bool |
335 | GNUNET_CRYPTO_ecdhe_elligator_inverse_map (uint8_t *representative, | 342 | GNUNET_CRYPTO_ecdhe_elligator_encoding ( |
336 | const uint8_t *point, | 343 | struct GNUNET_CRYPTO_ElligatorRepresentative *r, |
337 | bool high_y) | 344 | const struct GNUNET_CRYPTO_EcdhePublicKey *pub, |
345 | bool high_y) | ||
338 | { | 346 | { |
347 | uint8_t *representative = (uint8_t *) r->r; | ||
348 | uint8_t *point = (uint8_t *) pub->q_y; | ||
349 | |||
339 | mp_limb_t scratch_space[scratch_space_length]; | 350 | mp_limb_t scratch_space[scratch_space_length]; |
340 | 351 | ||
341 | mp_limb_t a[P_LIMBS + P_LIMBS]; | 352 | mp_limb_t a[P_LIMBS + P_LIMBS]; |
@@ -384,10 +395,21 @@ GNUNET_CRYPTO_ecdhe_elligator_inverse_map (uint8_t *representative, | |||
384 | } | 395 | } |
385 | 396 | ||
386 | 397 | ||
387 | bool | 398 | /** |
388 | GNUNET_CRYPTO_ecdhe_elligator_direct_map (uint8_t *point, | 399 | * Takes a number of the underlying finite field of Curve25519 and projects it into a valid point on that curve. |
389 | bool *high_y, | 400 | * This function works deterministically. |
390 | uint8_t *representative) | 401 | * This step is also known as elligators "decoding" step. |
402 | * Taken from https://github.com/Kleshni/Elligator-2/blob/master/main.c. | ||
403 | * | ||
404 | * @param point storage for calculated point on Curve25519 | ||
405 | * @param high_y The 'high_y' argument of the corresponding GNUNET_CRYPTO_ecdhe_elligator_encoding call | ||
406 | * @param representative Given representative | ||
407 | * @return 'false' if extra step during direct map calculation is needed, otherwise 'true' | ||
408 | */ | ||
409 | static bool | ||
410 | elligator_direct_map (uint8_t *point, | ||
411 | bool *high_y, | ||
412 | uint8_t *representative) | ||
391 | { | 413 | { |
392 | mp_limb_t scratch_space[scratch_space_length]; | 414 | mp_limb_t scratch_space[scratch_space_length]; |
393 | 415 | ||
@@ -444,7 +466,7 @@ GNUNET_CRYPTO_ecdhe_elligator_direct_map (uint8_t *point, | |||
444 | } | 466 | } |
445 | 467 | ||
446 | 468 | ||
447 | bool | 469 | void |
448 | GNUNET_CRYPTO_ecdhe_elligator_decoding ( | 470 | GNUNET_CRYPTO_ecdhe_elligator_decoding ( |
449 | struct GNUNET_CRYPTO_EcdhePublicKey *point, | 471 | struct GNUNET_CRYPTO_EcdhePublicKey *point, |
450 | bool *high_y, | 472 | bool *high_y, |
@@ -459,15 +481,25 @@ GNUNET_CRYPTO_ecdhe_elligator_decoding ( | |||
459 | high_y_ptr = high_y; | 481 | high_y_ptr = high_y; |
460 | 482 | ||
461 | struct GNUNET_CRYPTO_ElligatorRepresentative r_tmp; | 483 | struct GNUNET_CRYPTO_ElligatorRepresentative r_tmp; |
462 | memcpy (&r_tmp, &representative->r, sizeof(r_tmp.r)); | 484 | memcpy (&r_tmp.r, &representative->r, sizeof(r_tmp.r)); |
463 | r_tmp.r[31] &= 63; | 485 | r_tmp.r[31] &= 63; |
464 | // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Print high_y\n"); | 486 | // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Print high_y\n"); |
465 | return GNUNET_CRYPTO_ecdhe_elligator_direct_map ((uint8_t *) point->q_y, | 487 | elligator_direct_map ((uint8_t *) point->q_y, |
466 | high_y_ptr, | 488 | high_y_ptr, |
467 | (uint8_t *) r_tmp.r); | 489 | (uint8_t *) r_tmp.r); |
468 | } | 490 | } |
469 | 491 | ||
470 | 492 | ||
493 | /** | ||
494 | * Takes a number of the underlying finite field of Curve25519 and projects it into a valid point on that curve. | ||
495 | * This function works deterministically. | ||
496 | * This step is also known as elligators "decoding" step. | ||
497 | * Taken from https://github.com/Kleshni/Elligator-2/blob/master/main.c. | ||
498 | * | ||
499 | * @param point storage for calculated point on Curve25519 | ||
500 | * @param source Ed25519 curve point | ||
501 | * @return 'false' if source is not a valid Ed25519 point. In this case the 'point' array will be undefined but dependend on source. | ||
502 | */ | ||
471 | static bool | 503 | static bool |
472 | convert_from_ed_to_curve (uint8_t *point, | 504 | convert_from_ed_to_curve (uint8_t *point, |
473 | const uint8_t *source) | 505 | const uint8_t *source) |
@@ -595,12 +627,11 @@ GNUNET_CRYPTO_ecdhe_elligator_key_create ( | |||
595 | sizeof(int8_t)); | 627 | sizeof(int8_t)); |
596 | high_y = random_tweak & 1; | 628 | high_y = random_tweak & 1; |
597 | 629 | ||
598 | validKey = GNUNET_CRYPTO_ecdhe_elligator_inverse_map ( | 630 | validKey = GNUNET_CRYPTO_ecdhe_elligator_encoding (repr, |
599 | (unsigned char*) &(repr->r), | 631 | &pub, |
600 | (unsigned char*) pub.q_y, | 632 | high_y ? |
601 | high_y ? | 633 | GNUNET_YES : |
602 | GNUNET_YES : | 634 | GNUNET_NO); |
603 | GNUNET_NO); | ||
604 | } | 635 | } |
605 | 636 | ||
606 | // Setting most significant bit and second most significant bit randomly | 637 | // Setting most significant bit and second most significant bit randomly |
diff --git a/src/lib/util/test_crypto_elligator.c b/src/lib/util/test_crypto_elligator.c index 8fd4d4093..2e178b7b1 100644 --- a/src/lib/util/test_crypto_elligator.c +++ b/src/lib/util/test_crypto_elligator.c | |||
@@ -7,36 +7,38 @@ | |||
7 | 7 | ||
8 | 8 | ||
9 | // Test vector from https://github.com/Kleshni/Elligator-2/blob/master/test-vectors.c | 9 | // Test vector from https://github.com/Kleshni/Elligator-2/blob/master/test-vectors.c |
10 | // Using Decoding as a wrapper around direct_map | ||
10 | static int | 11 | static int |
11 | testDirectMap (void) | 12 | testDirectMap (void) |
12 | { | 13 | { |
13 | int ok = GNUNET_OK; | 14 | int ok = GNUNET_OK; |
14 | 15 | ||
15 | uint8_t repr1[32] = { | 16 | uint8_t repr1[32] = { |
16 | 0x17, 0x9f, 0x24, 0x73, 0x0d, 0xed, 0x2c, 0xe3, 0x17, 0x39, 0x08, 0xec, | 17 | 0x95, 0xa1, 0x60, 0x19, 0x04, 0x1d, 0xbe, 0xfe, |
17 | 0x61, 0x96, 0x46, 0x53, | 18 | 0xd9, 0x83, 0x20, 0x48, 0xed, 0xe1, 0x19, 0x28, |
18 | 0xb8, 0x02, 0x7e, 0x38, 0x3f, 0x40, 0x34, 0x6c, 0x1c, 0x9b, 0x4d, 0x2b, | 19 | 0xd9, 0x03, 0x65, 0xf2, 0x4a, 0x38, 0xaa, 0x7a, |
19 | 0xdb, 0x1d, 0xb7, 0x6c | 20 | 0xef, 0x1b, 0x97, 0xe2, 0x39, 0x54, 0x10, 0x1b |
20 | }; | 21 | }; |
21 | 22 | ||
22 | uint8_t point1[32] = { | 23 | uint8_t point1[32] = { |
23 | 0x10, 0x74, 0x54, 0x97, 0xd3, 0x5c, 0x6e, 0xde, 0x6e, 0xa6, 0xb3, 0x30, | 24 | 0x79, 0x4f, 0x05, 0xba, 0x3e, 0x3a, 0x72, 0x95, |
24 | 0x54, 0x6a, 0x6f, 0xcb, | 25 | 0x80, 0x22, 0x46, 0x8c, 0x88, 0x98, 0x1e, 0x0b, |
25 | 0xf1, 0x5c, 0x90, 0x3a, 0x7b, 0xe2, 0x8a, 0xe6, 0x9b, 0x1c, 0xa1, 0x4e, | 26 | 0xe5, 0x78, 0x2b, 0xe1, 0xe1, 0x14, 0x5c, 0xe2, |
26 | 0x0b, 0xf0, 0x9b, 0x60 | 27 | 0xc3, 0xc6, 0xfd, 0xe1, 0x6d, 0xed, 0x53, 0x63 |
27 | }; | 28 | }; |
28 | 29 | ||
29 | uint8_t pointResult[32]; | 30 | struct GNUNET_CRYPTO_EcdhePublicKey pointResult = {0}; |
31 | struct GNUNET_CRYPTO_ElligatorRepresentative representative = {0}; | ||
32 | memcpy (&representative.r, &repr1, sizeof(repr1)); | ||
33 | |||
30 | bool highYResult; | 34 | bool highYResult; |
31 | bool isLeastSqrRoot = GNUNET_CRYPTO_ecdhe_elligator_direct_map (pointResult, | ||
32 | &highYResult, | ||
33 | repr1); | ||
34 | 35 | ||
35 | if (isLeastSqrRoot == false) | 36 | GNUNET_CRYPTO_ecdhe_elligator_decoding ( |
36 | { | 37 | &pointResult, |
37 | ok = GNUNET_OK; | 38 | &highYResult, |
38 | } | 39 | &representative); |
39 | if (memcmp (point1,pointResult,sizeof(point1)) != 0) | 40 | |
41 | if (memcmp (point1, pointResult.q_y, sizeof(point1)) != 0) | ||
40 | { | 42 | { |
41 | ok = GNUNET_SYSERR; | 43 | ok = GNUNET_SYSERR; |
42 | } | 44 | } |
@@ -51,29 +53,33 @@ testInverseMap (void) | |||
51 | { | 53 | { |
52 | int ok = GNUNET_OK; | 54 | int ok = GNUNET_OK; |
53 | uint8_t point1[32] = { | 55 | uint8_t point1[32] = { |
54 | 0x33, 0x95, 0x19, 0x64, 0x00, 0x3c, 0x94, 0x08, 0x78, 0x06, 0x3c, 0xcf, | 56 | 0x33, 0x95, 0x19, 0x64, 0x00, 0x3c, 0x94, 0x08, |
55 | 0xd0, 0x34, 0x8a, 0xf4, | 57 | 0x78, 0x06, 0x3c, 0xcf, 0xd0, 0x34, 0x8a, 0xf4, |
56 | 0x21, 0x50, 0xca, 0x16, 0xd2, 0x64,0x6f, 0x2c, 0x58, 0x56, 0xe8, 0x33, 0x83, | 58 | 0x21, 0x50, 0xca, 0x16, 0xd2, 0x64, 0x6f, 0x2c, |
57 | 0x77, 0xd8, 0x00 | 59 | 0x58, 0x56, 0xe8, 0x33, 0x83, 0x77, 0xd8, 0x00 |
58 | }; | 60 | }; |
59 | 61 | ||
60 | uint8_t repr1[32] = { | 62 | uint8_t repr1[32] = { |
61 | 0x99, 0x9b, 0x59, 0x1b, 0x66, 0x97, 0xd0, 0x74, 0xf2, 0x66, 0x19, 0x22,0x77, | 63 | 0x99, 0x9b, 0x59, 0x1b, 0x66, 0x97, 0xd0, 0x74, |
62 | 0xd5, 0x54, 0xde, | 64 | 0xf2, 0x66, 0x19, 0x22, 0x77, 0xd5, 0x54, 0xde, |
63 | 0xc3, 0xc2, 0x4c, 0x2e,0xf6, 0x10, 0x81, 0x01, 0xf6, 0x3d, 0x94, 0xf7, 0xff, | 65 | 0xc3, 0xc2, 0x4c, 0x2e, 0xf6, 0x10, 0x81, 0x01, |
64 | 0xf3, 0xa0, 0x13 | 66 | 0xf6, 0x3d, 0x94, 0xf7, 0xff, 0xf3, 0xa0, 0x13 |
65 | }; | 67 | }; |
66 | 68 | ||
67 | uint8_t reprResult1[32]; | 69 | // uint8_t reprResult1[32]; |
70 | struct GNUNET_CRYPTO_ElligatorRepresentative r = {0}; | ||
71 | struct GNUNET_CRYPTO_EcdhePublicKey pub = {0}; | ||
72 | memcpy (&pub.q_y,&point1,sizeof(point1)); | ||
68 | bool yHigh1 = false; | 73 | bool yHigh1 = false; |
69 | bool success = GNUNET_CRYPTO_ecdhe_elligator_inverse_map (reprResult1, | 74 | |
70 | point1, | 75 | bool success = GNUNET_CRYPTO_ecdhe_elligator_encoding (&r, |
71 | yHigh1); | 76 | &pub, |
77 | yHigh1); | ||
72 | if (success == false) | 78 | if (success == false) |
73 | { | 79 | { |
74 | ok = GNUNET_SYSERR; | 80 | ok = GNUNET_SYSERR; |
75 | } | 81 | } |
76 | if (memcmp (repr1,reprResult1,sizeof(repr1)) != 0) | 82 | if (memcmp (&repr1,&r.r,sizeof(repr1)) != 0) |
77 | { | 83 | { |
78 | ok = GNUNET_SYSERR; | 84 | ok = GNUNET_SYSERR; |
79 | } | 85 | } |
@@ -104,11 +110,6 @@ testGeneratePkScalarMult (void) | |||
104 | } | 110 | } |
105 | crypto_scalarmult_base (pubPrimeCurve, pk.d); | 111 | crypto_scalarmult_base (pubPrimeCurve, pk.d); |
106 | 112 | ||
107 | // printf ("pubWholeCurve\n"); | ||
108 | // printLittleEndianHex (pubWholeCurve,32); | ||
109 | // printf ("pubPrimeCurve\n"); | ||
110 | // printLittleEndianHex (pubPrimeCurve,32); | ||
111 | // TODO: Currently utilizing ecdsa function for ecdhe testing, due to clamping. Clean this part later. | ||
112 | struct GNUNET_CRYPTO_EcdsaPrivateKey clampedPk; | 113 | struct GNUNET_CRYPTO_EcdsaPrivateKey clampedPk; |
113 | GNUNET_CRYPTO_ecdsa_key_create (&clampedPk); | 114 | GNUNET_CRYPTO_ecdsa_key_create (&clampedPk); |
114 | crypto_scalarmult_base (pubWholeCurve.q_y, clampedPk.d); | 115 | crypto_scalarmult_base (pubWholeCurve.q_y, clampedPk.d); |
@@ -204,14 +205,8 @@ testTimeDecoding (void) | |||
204 | { | 205 | { |
205 | fprintf (stderr, "%s", "."); | 206 | fprintf (stderr, "%s", "."); |
206 | fflush (stderr); | 207 | fflush (stderr); |
207 | if (false == | 208 | GNUNET_CRYPTO_ecdhe_elligator_decoding (&point, NULL, &repr[i]); |
208 | GNUNET_CRYPTO_ecdhe_elligator_decoding (&point, NULL, &repr[i])) | 209 | |
209 | { | ||
210 | fprintf (stderr, | ||
211 | "GNUNET_CRYPTO_ecdhe_elligator_decoding SYSERR\n"); | ||
212 | ok = GNUNET_SYSERR; | ||
213 | continue; | ||
214 | } | ||
215 | } | 210 | } |
216 | 211 | ||
217 | printf ("%d decoded public keys generated in %s\n", | 212 | printf ("%d decoded public keys generated in %s\n", |
@@ -253,13 +248,6 @@ elligatorKEM () | |||
253 | } | 248 | } |
254 | 249 | ||
255 | 250 | ||
256 | /* | ||
257 | *More tests to implement: | ||
258 | * Adding more test vectors from different sources for inverse and direct map | ||
259 | * check if inverse map rightfully fails for points which are not "encodable" | ||
260 | */ | ||
261 | |||
262 | |||
263 | int | 251 | int |
264 | main (int argc, char *argv[]) | 252 | main (int argc, char *argv[]) |
265 | { | 253 | { |