3737/* Private definitions */
3838/*============================================================================*/
3939
40+ /**
41+ * Domain separation string.
42+ */
43+ #define MAP_STRING (const uint8_t *)"RELIC"
44+
4045#ifdef EP_CTMAP
4146
4247/**
@@ -69,7 +74,43 @@ TMPL_MAP_SSWU(ep, fp, dig_t);
6974 */
7075TMPL_MAP_SVDW (ep , fp , dig_t );
7176
72- #undef EP_MAP_copy_sec
77+ static void ep_map_basic_impl (ep_t p , const uint8_t * bytes , size_t len ) {
78+ bn_t x ;
79+ fp_t t0 ;
80+
81+ bn_null (x );
82+ fp_null (t0 );
83+
84+ RLC_TRY {
85+ bn_new (x );
86+ fp_new (t0 );
87+
88+ bn_read_bin (x , bytes , len );
89+ fp_prime_conv (p -> x , x );
90+ fp_set_dig (p -> z , 1 );
91+
92+ while (1 ) {
93+ ep_rhs (t0 , p -> x );
94+
95+ if (fp_smb (t0 ) == 1 ) {
96+ fp_srt (p -> y , t0 );
97+ p -> coord = BASIC ;
98+ break ;
99+ }
100+
101+ fp_add_dig (p -> x , p -> x , 1 );
102+ }
103+
104+ ep_mul_cof (p , p );
105+ }
106+ RLC_CATCH_ANY {
107+ RLC_THROW (ERR_CAUGHT );
108+ }
109+ RLC_FINALLY {
110+ bn_free (x );
111+ fp_free (t0 );
112+ }
113+ }
73114
74115/**
75116 * Maps an array of uniformly random bytes to a point in a prime elliptic
@@ -82,31 +123,27 @@ TMPL_MAP_SVDW(ep, fp, dig_t);
82123 * @param[in] len - the array length in bytes.
83124 * @param[in] map_fn - the mapping function.
84125 */
85- static void ep_map_from_field (ep_t p , const uint8_t * uniform_bytes , size_t len ,
126+ static void ep_map_sswum_impl (ep_t p , const uint8_t * bytes , size_t len ,
86127 void (* const map_fn )(ep_t , const fp_t )) {
87128 bn_t k ;
88129 fp_t t ;
89130 ep_t q ;
90131 int neg ;
91132 /* enough space for two field elements plus extra bytes for uniformity */
92- const size_t len_per_elm = (FP_PRIME + ep_param_level () + 7 ) / 8 ;
133+ const size_t elm = (FP_PRIME + ep_param_level () + 7 ) / 8 ;
93134
94135 bn_null (k );
95136 fp_null (t );
96137 ep_null (q );
97138
98139 RLC_TRY {
99- if (len != 2 * len_per_elm ) {
100- RLC_THROW (ERR_NO_VALID );
101- }
102-
103140 bn_new (k );
104141 fp_new (t );
105142 ep_new (q );
106143
107144#define EP_MAP_CONVERT_BYTES (IDX ) \
108145 do { \
109- bn_read_bin(k, uniform_bytes + IDX * len_per_elm, len_per_elm); \
146+ bn_read_bin(k, bytes + IDX * elm, elm); \
110147 fp_prime_conv(t, k); \
111148 } while (0)
112149
@@ -153,107 +190,11 @@ static void ep_map_from_field(ep_t p, const uint8_t *uniform_bytes, size_t len,
153190 }
154191}
155192
156- /*============================================================================*/
157- /* Public definitions */
158- /*============================================================================*/
159-
160- #if EP_MAP == BASIC || !defined(STRIP )
161-
162- void ep_map_basic (ep_t p , const uint8_t * msg , size_t len ) {
163- bn_t x ;
164- fp_t t0 ;
165- uint8_t h [RLC_MD_LEN ];
166-
167- bn_null (x );
168- fp_null (t0 );
169-
170- RLC_TRY {
171- bn_new (x );
172- fp_new (t0 );
173-
174- md_map (h , msg , len );
175- bn_read_bin (x , h , RLC_MIN (RLC_FP_BYTES , RLC_MD_LEN ));
176-
177- fp_zero (p -> x );
178- fp_prime_conv (p -> x , x );
179- fp_set_dig (p -> z , 1 );
180-
181- while (1 ) {
182- ep_rhs (t0 , p -> x );
183-
184- if (fp_smb (t0 ) == 1 ) {
185- fp_srt (p -> y , t0 );
186- p -> coord = BASIC ;
187- break ;
188- }
189-
190- fp_add_dig (p -> x , p -> x , 1 );
191- }
192-
193- ep_mul_cof (p , p );
194- }
195- RLC_CATCH_ANY {
196- RLC_THROW (ERR_CAUGHT );
197- }
198- RLC_FINALLY {
199- bn_free (x );
200- fp_free (t0 );
201- }
202- }
203-
204- #endif
205-
206- #if EP_MAP == SSWUM || !defined(STRIP )
207-
208- void ep_map_sswum (ep_t p , const uint8_t * msg , size_t len ) {
209- /* enough space for two field elements plus extra bytes for uniformity */
210- const size_t elm = (FP_PRIME + ep_param_level () + 7 ) / 8 ;
211- uint8_t * r = RLC_ALLOCA (uint8_t , 2 * elm );
212-
213- RLC_TRY {
214- /* for hash_to_field, need to hash to a pseudorandom string */
215- /* XXX(rsw) the below assumes that we want to use MD_MAP for hashing.
216- * Consider making the hash function a per-curve option!
217- */
218- md_xmd (r , 2 * elm , msg , len , (const uint8_t * )"RELIC" , 5 );
219- /* figure out which hash function to use */
220- const int abNeq0 = (ep_curve_opt_a () != RLC_ZERO ) &&
221- (ep_curve_opt_b () != RLC_ZERO );
222- void (* const map_fn )(ep_t , const fp_t ) =
223- (ep_curve_is_ctmap () || abNeq0 ? ep_map_sswu : ep_map_svdw );
224- ep_map_from_field (p , r , 2 * elm , map_fn );
225- }
226- RLC_CATCH_ANY {
227- RLC_THROW (ERR_CAUGHT );
228- }
229- RLC_FINALLY {
230- RLC_FREE (r );
231- }
232- }
233-
234- #endif
235-
236- #if EP_MAP == SWIFT || !defined(STRIP )
237-
238- void ep_map_swift (ep_t p , const uint8_t * msg , size_t len ) {
239- /* enough space for two field elements plus extra bytes for uniformity */
240- const size_t len_per_elm = (FP_PRIME + ep_param_level () + 7 ) / 8 ;
241- uint8_t s , * pseudo_random_bytes = RLC_ALLOCA (uint8_t , 2 * len_per_elm + 1 );
193+ static void ep_map_swift_impl (ep_t p , const uint8_t * random , size_t len ) {
242194 fp_t h [8 ], t1 , t2 , v , w , y , x1 , x2 , x3 , d [3 ];
243195 ctx_t * ctx = core_get ();
244196 bn_t k ;
245-
246- if (ep_curve_is_super ()) {
247- RLC_FREE (pseudo_random_bytes );
248- RLC_THROW (ERR_NO_CONFIG );
249- return ;
250- }
251-
252- if (ctx -> mod18 % 3 == 2 ) {
253- RLC_FREE (pseudo_random_bytes );
254- RLC_THROW (ERR_NO_CONFIG );
255- return ;
256- }
197+ uint8_t s ;
257198
258199 bn_null (k );
259200 fp_null (v );
@@ -286,14 +227,11 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) {
286227 fp_new (h [i ]);
287228 }
288229
289- md_xmd (pseudo_random_bytes , 2 * len_per_elm + 1 , msg , len ,
290- (const uint8_t * )"RELIC" , 5 );
291-
292- bn_read_bin (k , pseudo_random_bytes , len_per_elm );
230+ bn_read_bin (k , random , len / 2 );
293231 fp_prime_conv (t1 , k );
294- bn_read_bin (k , pseudo_random_bytes + len_per_elm , len_per_elm );
232+ bn_read_bin (k , random + len / 2 , len / 2 );
295233 fp_prime_conv (t2 , k );
296- s = pseudo_random_bytes [ 2 * len_per_elm ] & 1 ;
234+ s = random [ len - 1 ] & 1 ;
297235
298236 if (ep_curve_opt_b () == RLC_ZERO ) {
299237 /* h0 = t1^2, h1 = h0^2, h2 = 4a, h3 = h2^3, h4 = h0 * h1 + h3. */
@@ -489,11 +427,115 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) {
489427 fp_free (d [0 ]);
490428 fp_free (d [1 ]);
491429 fp_free (d [2 ]);
492- RLC_FREE (pseudo_random_bytes );
493430 for (size_t i = 0 ; i < 8 ; i ++ ) {
494431 fp_free (h [i ]);
495432 }
496433 }
497434}
498435
436+ /*============================================================================*/
437+ /* Public definitions */
438+ /*============================================================================*/
439+
440+ #if EP_MAP == BASIC || !defined(STRIP )
441+
442+ void ep_map_basic (ep_t p , const uint8_t * msg , size_t len ) {
443+ /* enough space for two field elements plus extra bytes for uniformity */
444+ const size_t elm = (FP_PRIME + ep_param_level () + 7 ) / 8 ;
445+ uint8_t * r = RLC_ALLOCA (uint8_t , elm );
446+
447+ RLC_TRY {
448+ md_xmd (r , elm , msg , len , MAP_STRING , sizeof (MAP_STRING ));
449+ ep_map_basic_impl (p , r , elm );
450+ }
451+ RLC_CATCH_ANY {
452+ RLC_THROW (ERR_CAUGHT );
453+ }
454+ RLC_FINALLY {
455+ RLC_FREE (r );
456+ }
457+ }
458+
459+ #endif
460+
461+ #if EP_MAP == SSWUM || !defined(STRIP )
462+
463+ void ep_map_sswum (ep_t p , const uint8_t * msg , size_t len ) {
464+ /* enough space for two field elements plus extra bytes for uniformity */
465+ const size_t elm = (FP_PRIME + ep_param_level () + 7 ) / 8 ;
466+ uint8_t * r = RLC_ALLOCA (uint8_t , 2 * elm );
467+
468+ RLC_TRY {
469+ /* for hash_to_field, need to hash to a pseudorandom string */
470+ /* XXX(rsw) the below assumes that we want to use MD_MAP for hashing.
471+ * Consider making the hash function a per-curve option!
472+ */
473+ md_xmd (r , 2 * elm , msg , len , MAP_STRING , sizeof (MAP_STRING ));
474+ /* figure out which hash function to use */
475+ const int abNeq0 = (ep_curve_opt_a () != RLC_ZERO ) &&
476+ (ep_curve_opt_b () != RLC_ZERO );
477+ void (* const map_fn )(ep_t , const fp_t ) =
478+ (ep_curve_is_ctmap () || abNeq0 ? ep_map_sswu : ep_map_svdw );
479+
480+ ep_map_sswum_impl (p , r , len , map_fn );
481+ }
482+ RLC_CATCH_ANY {
483+ RLC_THROW (ERR_CAUGHT );
484+ }
485+ RLC_FINALLY {
486+ RLC_FREE (r );
487+ }
488+ }
489+
499490#endif
491+
492+ #if EP_MAP == SWIFT || !defined(STRIP )
493+
494+ void ep_map_swift (ep_t p , const uint8_t * msg , size_t len ) {
495+ /* enough space for two field elements plus extra bytes for uniformity */
496+ const size_t elm = (FP_PRIME + ep_param_level () + 7 ) / 8 ;
497+ uint8_t * r = RLC_ALLOCA (uint8_t , 2 * elm + 1 );
498+ ctx_t * ctx = core_get ();
499+
500+ if (ep_curve_is_super ()) {
501+ RLC_FREE (r );
502+ RLC_THROW (ERR_NO_CONFIG );
503+ return ;
504+ }
505+
506+ if (ctx -> mod18 % 3 == 2 ) {
507+ RLC_FREE (r );
508+ RLC_THROW (ERR_NO_CONFIG );
509+ return ;
510+ }
511+
512+ RLC_TRY {
513+ md_xmd (r , 2 * elm + 1 , msg , len , MAP_STRING , sizeof (MAP_STRING ));
514+
515+ ep_map_swift_impl (p , r , 2 * elm + 1 );
516+ }
517+ RLC_CATCH_ANY {
518+ RLC_THROW (ERR_CAUGHT );
519+ }
520+ RLC_FINALLY {
521+ RLC_FREE (r );
522+ }
523+ }
524+
525+ #endif
526+
527+ void ep_map_rnd (ep_t p , const uint8_t * uniform_bytes , size_t len ) {
528+ #if EP_MAP == BASIC || !defined(STRIP )
529+ ep_map_basic_impl (p , uniform_bytes , len );
530+ #elif EP_MAP == SWIFT || !defined(STRIP )
531+ /* figure out which hash function to use */
532+ const int abNeq0 = (ep_curve_opt_a () != RLC_ZERO ) &&
533+ (ep_curve_opt_b () != RLC_ZERO );
534+ void (* const map_fn )(ep_t , const fp_t ) =
535+ (ep_curve_is_ctmap () || abNeq0 ? ep_map_sswu : ep_map_svdw );
536+
537+ ep_map_sswum_impl (p , bytes , len , map_fn );
538+ #elif EP_MAP == SSWUM || !defined(STRIP )
539+ ep_map_swift_impl (p , uniform_bytes , len );
540+ #endif
541+ }
0 commit comments