aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedram Fardzadeh <p.fardzadeh@protonmail.com>2024-03-11 23:57:29 +0100
committert3serakt <t3ss@posteo.de>2024-04-10 20:14:53 +0200
commit934f9aaa70222bf61363e6833c2c4592a076abce (patch)
tree3fc5c7613a90847f7d1e2fb9c279c23ec65441a6
parentc810e726b3d67a9bd09b714ed32acf92883fdf67 (diff)
downloadgnunet-934f9aaa70222bf61363e6833c2c4592a076abce.tar.gz
gnunet-934f9aaa70222bf61363e6833c2c4592a076abce.zip
elligator: API changes for encoding + function documentations
-rw-r--r--src/include/gnunet_crypto_lib.h46
-rw-r--r--src/lib/util/crypto_elligator.c175
-rw-r--r--src/lib/util/test_crypto_elligator.c88
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 */
2678bool
2679GNUNET_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 */
2692bool 2676void
2693GNUNET_CRYPTO_ecdhe_elligator_decoding ( 2677GNUNET_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 */
2707bool 2692bool
2708GNUNET_CRYPTO_ecdhe_elligator_inverse_map (uint8_t *representative, 2693GNUNET_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
97static const unsigned char p_bytes[P_BYTES] = { 97static 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
104static const unsigned char negative_1_bytes[P_BYTES] = { 104static 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
111static const unsigned char negative_2_bytes[P_BYTES] = { 111static 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
118static const unsigned char divide_negative_1_2_bytes[P_BYTES] = { 118static 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
125static const unsigned char divide_plus_p_3_8_bytes[P_BYTES] = { 125static 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
132static const unsigned char divide_minus_p_1_2_bytes[P_BYTES] = { 132static 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
139static const unsigned char square_root_negative_1_bytes[P_BYTES] = { 139static 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
146static const unsigned char A_bytes[P_BYTES] = { 146static 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
153static const unsigned char negative_A_bytes[P_BYTES] = { 153static 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
160static const unsigned char u_bytes[P_BYTES] = { 160static 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
167static const unsigned char inverted_u_bytes[P_BYTES] = { 167static 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
174static const unsigned char d_bytes[P_BYTES] = { 174static 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
181static mp_limb_t p[P_LIMBS]; 181static mp_limb_t p[P_LIMBS];
@@ -193,6 +193,7 @@ static mp_limb_t d[P_LIMBS];
193 193
194static mp_size_t scratch_space_length; 194static mp_size_t scratch_space_length;
195 195
196// TODO
196static void 197static void
197decode_bytes (mp_limb_t *number, const uint8_t *bytes) 198decode_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
211static void 211static void
212encode_bytes (uint8_t *bytes, mp_limb_t *number) 212encode_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*/
221void __attribute__ ((constructor)) 224void __attribute__ ((constructor))
222GNUNET_CRYPTO_ecdhe_elligator_initialize () 225GNUNET_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 */
296static void 303static void
297least_square_root (mp_limb_t *root, 304least_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
334bool 341bool
335GNUNET_CRYPTO_ecdhe_elligator_inverse_map (uint8_t *representative, 342GNUNET_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
387bool 398/**
388GNUNET_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 */
409static bool
410elligator_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
447bool 469void
448GNUNET_CRYPTO_ecdhe_elligator_decoding ( 470GNUNET_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 */
471static bool 503static bool
472convert_from_ed_to_curve (uint8_t *point, 504convert_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
10static int 11static int
11testDirectMap (void) 12testDirectMap (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
263int 251int
264main (int argc, char *argv[]) 252main (int argc, char *argv[])
265{ 253{