/* * RELIC is an Efficient LIbrary for Cryptography * Copyright (c) 2009 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file * for contact information. * * RELIC is free software; you can redistribute it and/or modify it under the * terms of the version 2.1 (or later) of the GNU Lesser General Public License * as published by the Free Software Foundation; or version 2.0 of the Apache * License as published by the Apache Software Foundation. See the LICENSE files * for more details. * * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the LICENSE files for more details. * * You should have received a copy of the GNU Lesser General Public or the * Apache License along with RELIC. If not, see * or . */ /** * @defgroup eb Elliptic curves over binary fields */ /** * @file * * Interface of the module for arithmetic on binary elliptic curves. * * @ingroup eb */ #ifndef RLC_EB_H #define RLC_EB_H #include "relic_fb.h" #include "relic_bn.h" #include "relic_conf.h" #include "relic_types.h" #include "relic_label.h" /*============================================================================*/ /* Constant definitions */ /*============================================================================*/ /** * Binary elliptic curve identifiers. */ enum { /** NIST B-163 binary curve. */ NIST_B163 = 1, /** NIST K-163 Koblitz curve. */ NIST_K163, /** NIST B-133 binary curve. */ NIST_B233, /** NIST K-233 Koblitz curve. */ NIST_K233, /** Curve over 2^{251} used in eBATs. */ EBACS_B251, /** Curve over 2^{257} good for halving. */ HALVE_B257, /** SECG K-239 binary curve. */ SECG_K239, /** NIST B-283 binary curve. */ NIST_B283, /** NIST K-283 Koblitz curve. */ NIST_K283, /** NIST B-409 binary curve. */ NIST_B409, /** NIST K-409 Koblitz curve. */ NIST_K409, /** NIST B-571 binary curve. */ NIST_B571, /** NIST K-571 Koblitz curve. */ NIST_K571, }; /** * Size of a precomputation table using the binary method. */ #define RLC_EB_TABLE_BASIC (RLC_FB_BITS) /** * Size of a precomputation table using the single-table comb method. */ #define RLC_EB_TABLE_COMBS (1 << EB_DEPTH) /** * Size of a precomputation table using the double-table comb method. */ #define RLC_EB_TABLE_COMBD (1 << (EB_DEPTH + 1)) /** * Size of a precomputation table using the w-(T)NAF method. */ #define RLC_EB_TABLE_LWNAF (1 << (EB_DEPTH - 2)) /** * Size of a precomputation table using the chosen algorithm. */ #if EB_FIX == BASIC #define RLC_EB_TABLE RLC_EB_TABLE_BASIC #elif EB_FIX == COMBS #define RLC_EB_TABLE RLC_EB_TABLE_COMBS #elif EB_FIX == COMBD #define RLC_EB_TABLE RLC_EB_TABLE_COMBD #elif EB_FIX == LWNAF #define RLC_EB_TABLE RLC_EB_TABLE_LWNAF #endif /** * Maximum size of a precomputation table. */ #ifdef STRIP #define RLC_EB_TABLE_MAX RLC_EB_TABLE #else #define RLC_EB_TABLE_MAX RLC_MAX(RLC_EB_TABLE_BASIC, RLC_EB_TABLE_COMBD) #endif /*============================================================================*/ /* Type definitions */ /*============================================================================*/ /** * Represents an elliptic curve point over a binary field. */ typedef struct { /** The first coordinate. */ fb_st x; /** The second coordinate. */ fb_st y; /** The third coordinate (projective representation). */ fb_st z; /** Flag to indicate the coordinate system of this point. */ int coord; } eb_st; /** * Pointer to an elliptic curve point. */ #if ALLOC == AUTO typedef eb_st eb_t[1]; #else typedef eb_st *eb_t; #endif /*============================================================================*/ /* Macro definitions */ /*============================================================================*/ /** * Initializes a point on a binary elliptic curve with a null value. * * @param[out] A - the point to initialize. */ #if ALLOC == AUTO #define eb_null(A) /* empty */ #else #define eb_null(A) A = NULL; #endif /** * Calls a function to allocate a point on a binary elliptic curve. * * @param[out] A - the new point. * @throw ERR_NO_MEMORY - if there is no available memory. */ #if ALLOC == DYNAMIC #define eb_new(A) \ A = (eb_t)calloc(1, sizeof(eb_st)); \ if (A == NULL) { \ RLC_THROW(ERR_NO_MEMORY); \ } \ #elif ALLOC == AUTO #define eb_new(A) /* empty */ #endif /** * Calls a function to clean and free a point on a binary elliptic curve. * * @param[out] A - the point to clean and free. */ #if ALLOC == DYNAMIC #define eb_free(A) \ if (A != NULL) { \ free(A); \ A = NULL; \ } \ #elif ALLOC == AUTO #define eb_free(A) /* empty */ #endif /** * Negates a binary elliptic curve point. Computes R = -P. * * @param[out] R - the result. * @param[in] P - the point to negate. */ #if EB_ADD == BASIC #define eb_neg(R, P) eb_neg_basic(R, P) #elif EB_ADD == PROJC #define eb_neg(R, P) eb_neg_projc(R, P) #endif /** * Adds two binary elliptic curve points. Computes R = P + Q. * * @param[out] R - the result. * @param[in] P - the first point to add. * @param[in] Q - the second point to add. */ #if EB_ADD == BASIC #define eb_add(R, P, Q) eb_add_basic(R, P, Q); #elif EB_ADD == PROJC #define eb_add(R, P, Q) eb_add_projc(R, P, Q); #endif /** * Subtracts a binary elliptic curve point from another. Computes R = P - Q. * * @param[out] R - the result. * @param[in] P - the first point. * @param[in] Q - the second point. */ #if EB_ADD == BASIC #define eb_sub(R, P, Q) eb_sub_basic(R, P, Q) #elif EB_ADD == PROJC #define eb_sub(R, P, Q) eb_sub_projc(R, P, Q) #endif /** * Doubles a binary elliptic curve point. Computes R = 2P. * * @param[out] R - the result. * @param[in] P - the point to double. */ #if EB_ADD == BASIC #define eb_dbl(R, P) eb_dbl_basic(R, P); #elif EB_ADD == PROJC #define eb_dbl(R, P) eb_dbl_projc(R, P); #endif /** * Multiplies a binary elliptic curve point by an integer. Computes R = [k]P. * * @param[out] R - the result. * @param[in] P - the point to multiply. * @param[in] K - the integer. */ #if EB_MUL == BASIC #define eb_mul(R, P, K) eb_mul_basic(R, P, K) #elif EB_MUL == LODAH #define eb_mul(R, P, K) eb_mul_lodah(R, P, K) #elif EB_MUL == HALVE #define eb_mul(R, P, K) eb_mul_halve(R, P, K) #elif EB_MUL == LWNAF #define eb_mul(R, P, K) eb_mul_lwnaf(R, P, K) #elif EB_MUL == RWNAF #define eb_mul(R, P, K) eb_mul_rwnaf(R, P, K) #endif /** * Builds a precomputation table for multiplying a fixed binary elliptic point * point. * * @param[out] T - the precomputation table. * @param[in] P - the point to multiply. */ #if EB_FIX == BASIC #define eb_mul_pre(T, P) eb_mul_pre_basic(T, P) #elif EB_FIX == COMBS #define eb_mul_pre(T, P) eb_mul_pre_combs(T, P) #elif EB_FIX == COMBD #define eb_mul_pre(T, P) eb_mul_pre_combd(T, P) #elif EB_FIX == LWNAF #define eb_mul_pre(T, P) eb_mul_pre_lwnaf(T, P) #endif /** * Multiplies a fixed binary elliptic point using a precomputation table. * Computes R = [k]P. * * @param[out] R - the result. * @param[in] T - the precomputation table. * @param[in] K - the integer. */ #if EB_FIX == BASIC #define eb_mul_fix(R, T, K) eb_mul_fix_basic(R, T, K) #elif EB_FIX == COMBS #define eb_mul_fix(R, T, K) eb_mul_fix_combs(R, T, K) #elif EB_FIX == COMBD #define eb_mul_fix(R, T, K) eb_mul_fix_combd(R, T, K) #elif EB_FIX == LWNAF #define eb_mul_fix(R, T, K) eb_mul_fix_lwnaf(R, T, K) #endif /** * Multiplies and adds two binary elliptic curve points simultaneously. Computes * R = [k]P + [m]Q. * * @param[out] R - the result. * @param[in] P - the first point to multiply. * @param[in] K - the first integer. * @param[in] Q - the second point to multiply. * @param[in] M - the second integer, */ #if EB_SIM == BASIC #define eb_mul_sim(R, P, K, Q, M) eb_mul_sim_basic(R, P, K, Q, M) #elif EB_SIM == TRICK #define eb_mul_sim(R, P, K, Q, M) eb_mul_sim_trick(R, P, K, Q, M) #elif EB_SIM == INTER #define eb_mul_sim(R, P, K, Q, M) eb_mul_sim_inter(R, P, K, Q, M) #elif EB_SIM == JOINT #define eb_mul_sim(R, P, K, Q, M) eb_mul_sim_joint(R, P, K, Q, M) #endif /*============================================================================*/ /* Function prototypes */ /*============================================================================*/ /** * Initializes the binary elliptic curve arithmetic module. */ void eb_curve_init(void); /** * Finalizes the binary elliptic curve arithmetic module. */ void eb_curve_clean(void); /** * Returns the a-coefficient of the currently configured binary elliptic * curve. * * @return the a-coefficient of the elliptic curve. */ dig_t *eb_curve_get_a(void); /** * Returns the b-coefficient of the currently configured binary elliptic * curve. * * @return the b-coefficient of the elliptic curve. */ dig_t *eb_curve_get_b(void); /** * Returns a optimization identifier based on the a-coefficient of the curve. * * @return the optimization identifier. */ int eb_curve_opt_a(void); /** * Returns a optimization identifier based on the b-coefficient of the curve. * * @return the optimization identifier. */ int eb_curve_opt_b(void); /** * Tests if the configured binary elliptic curve is a Koblitz curve. * * @return 1 if the binary elliptic curve is a Koblitz curve, 0 otherwise. */ int eb_curve_is_kbltz(void); /** * Returns the generator of the group of points in the binary elliptic curve. * * @param[out] g - the returned generator. */ void eb_curve_get_gen(eb_t g); /** * Returns the precomputation table for the generator. * * @return the table. */ const eb_t *eb_curve_get_tab(void); /** * Returns the order of the group of points in the binary elliptic curve. * * @param[out] n - the returned order. */ void eb_curve_get_ord(bn_t n); /** * Returns the cofactor of the binary elliptic curve. * * @param[out] n - the returned cofactor. */ void eb_curve_get_cof(bn_t h); /** * Configures an ordinary binary elliptic curve by its coefficients and * generator. * * @param[in] a - the a-coefficient of the curve. * @param[in] b - the b-coefficient of the curve. * @param[in] g - the generator. * @param[in] n - the order of the generator. * @param[in] h - the cofactor of the group order. */ void eb_curve_set(const fb_t a, const fb_t b, const eb_t g, const bn_t n, const bn_t h); /** * Configures a new binary elliptic curve by its parameter identifier. * * @param[in] param - the parameters identifier. */ void eb_param_set(int param); /** * Configures some set of curve parameters for the current security level. */ int eb_param_set_any(void); /** * Configures a set of curve parameters without endormorphisms for the current * security level. * * @return RLC_OK if there is a curve at this security level, RLC_ERR otherwise. */ int eb_param_set_any_plain(void); /** * Configures a set of Koblitz curve parameters for the current security level. * * @return RLC_OK if there is a curve at this security level, RLC_ERR otherwise. */ int eb_param_set_any_kbltz(void); /** * Returns the parameter identifier of the currently configured binary elliptic * curve. * * @return the parameter identifier. */ int eb_param_get(void); /** * Prints the current configured binary elliptic curve. */ void eb_param_print(void); /** * Returns the current security level. */ int eb_param_level(void); /** * Tests if a point on a binary elliptic curve is at the infinity. * * @param[in] p - the point to test. * @return 1 if the point is at infinity, 0 otherise. */ int eb_is_infty(const eb_t p); /** * Assigns a binary elliptic curve point to the point at infinity. * * @param[out] p - the point to assign. */ void eb_set_infty(eb_t p); /** * Copies the second argument to the first argument. * * @param[out] r - the result. * @param[in] p - the binary elliptic curve point to copy. */ void eb_copy(eb_t r, const eb_t p); /** * Compares two binary elliptic curve points. * * @param[in] p - the first binary elliptic curve point. * @param[in] q - the second binary elliptic curve point. * @return RLC_EQ if p == q and RLC_NE if p != q. */ int eb_cmp(const eb_t p, const eb_t q); /** * Assigns a random value to a binary elliptic curve point. * * @param[out] p - the binary elliptic curve point to assign. */ void eb_rand(eb_t p); /** * Randomizes coordinates of a binary elliptic curve point. * * @param[out] r - the blinded binary elliptic curve point. * @param[in] p - the binary elliptic curve point to blind. */ void eb_blind(eb_t r, const eb_t p); /** * Computes the right-hand side of the elliptic curve equation at a certain * elliptic curve point. * * @param[out] rhs - the result. * @param[in] p - the point. */ void eb_rhs(fb_t rhs, const eb_t p); /** Tests if a point is in the curve. * * @param[in] p - the point to test. */ int eb_on_curve(const eb_t p); /** * Builds a precomputation table for multiplying a random binary elliptic point. * * @param[out] t - the precomputation table. * @param[in] p - the point to multiply. * @param[in] w - the window width. */ void eb_tab(eb_t *t, const eb_t p, int w); /** * Prints a binary elliptic curve point. * * @param[in] p - the binary elliptic curve point to print. */ void eb_print(const eb_t p); /** * Returns the number of bytes necessary to store a binary elliptic curve point * with optional point compression. * * @param[in] a - the binary field element. * @param[in] pack - the flag to indicate compression. * @return the number of bytes. */ int eb_size_bin(const eb_t a, int pack); /** * Reads a binary elliptic curve point from a byte vector in big-endian format. * * @param[out] a - the result. * @param[in] bin - the byte vector. * @param[in] len - the buffer capacity. * @throw ERR_NO_VALID - if the encoded point is invalid. * @throw ERR_NO_BUFFER - if the buffer capacity is invalid. */ void eb_read_bin(eb_t a, const uint8_t *bin, int len); /** * Writes a binary field element to a byte vector in big-endian format with * optional point compression. * * @param[out] bin - the byte vector. * @param[in] len - the buffer capacity. * @param[in] a - the binary elliptic curve point to write. * @param[in] pack - the flag to indicate point compression. * @throw ERR_NO_BUFFER - if the buffer capacity is invalid. */ void eb_write_bin(uint8_t *bin, int len, const eb_t a, int pack); /** * Negates a binary elliptic curve point represented by affine coordinates. * * @param[out] r - the result. * @param[in] p - the point to negate. */ void eb_neg_basic(eb_t r, const eb_t p); /** * Negates a binary elliptic curve point represented by projective coordinates. * * @param[out] r - the result. * @param[in] p - the point to negate. */ void eb_neg_projc(eb_t r, const eb_t p); /** * Adds two binary elliptic curve points represented in affine coordinates. * * @param[out] r - the result. * @param[in] p - the first point to add. * @param[in] q - the second point to add. */ void eb_add_basic(eb_t r, const eb_t p, const eb_t q); /** * Adds two binary elliptic curve points represented in projective coordinates. * Computes R = P + Q. * * @param[out] r - the result. * @param[in] p - the first point to add. * @param[in] q - the second point to add. */ void eb_add_projc(eb_t r, const eb_t p, const eb_t q); /** * Subtracts a binary elliptic curve point from another, both points represented * by affine coordinates. * * @param[out] r - the result. * @param[in] p - the first point. * @param[in] q - the second point. */ void eb_sub_basic(eb_t r, const eb_t p, const eb_t q); /** * Subtracts a binary elliptic curve point from another, both points represented * by projective coordinates. * * @param[out] r - the result. * @param[in] p - the first point. * @param[in] q - the second point. */ void eb_sub_projc(eb_t r, const eb_t p, const eb_t q); /** * Doubles a binary elliptic curve point represented in affine coordinates. * * @param[out] r - the result. * @param[in] p - the point to double. */ void eb_dbl_basic(eb_t r, const eb_t p); /** * Doubles a binary elliptic curve point represented in projective coordinates. * * @param[out] r - the result. * @param[in] p - the point to double. */ void eb_dbl_projc(eb_t r, const eb_t p); /** * Halves a point represented in affine coordinates. * * @param[out] r - the result. * @param[in] p - the point to halve. */ void eb_hlv(eb_t r, const eb_t p); /** * Computes the Frobenius map of a binary elliptic curve point on a Koblitz * curve. Computes R = \tau(P) = \tau(x, y) = (x^2, y^2). * * @param[out] r - the result. * @param[in] p - the point. */ void eb_frb(eb_t r, const eb_t p); /** * Multiplies a binary elliptic point by an integer using the binary method. * * @param[out] r - the result. * @param[in] p - the point to multiply. * @param[in] k - the integer. */ void eb_mul_basic(eb_t r, const eb_t p, const bn_t k); /** * Multiplies a binary elliptic point by an integer using the constant-time * Lopez-Dahab point multiplication method. * * @param[out] r - the result. * @param[in] p - the point to multiply. * @param[in] k - the integer. */ void eb_mul_lodah(eb_t r, const eb_t p, const bn_t k); /** * Multiplies a binary elliptic point by an integer using the left-to-right * w-NAF method. If the binary curve is a Koblitz curve, w-TNAF is used. * * @param[out] r - the result. * @param[in] p - the point to multiply. * @param[in] k - the integer. */ void eb_mul_lwnaf(eb_t r, const eb_t p, const bn_t k); /** * Multiplies a binary elliptic point by an integer using the right-to-left * w-NAF method. If the binary curve is a Koblitz curve, w-TNAF is used. * * @param[out] r - the result. * @param[in] p - the point to multiply. * @param[in] k - the integer. */ void eb_mul_rwnaf(eb_t r, const eb_t p, const bn_t k); /** * Multiplies a binary elliptic point by an integer using the halving method. * * @param[out] r - the result. * @param[in] p - the point to multiply. * @param[in] k - the integer. */ void eb_mul_halve(eb_t r, const eb_t p, const bn_t k); /** * Multiplies the generator of a binary elliptic curve by an integer. * * @param[out] r - the result. * @param[in] k - the integer. */ void eb_mul_gen(eb_t r, const bn_t k); /** * Multiplies a binary elliptic point by a small positive integer. * * @param[out] r - the result. * @param[in] p - the point to multiply. * @param[in] k - the integer. */ void eb_mul_dig(eb_t r, const eb_t p, const dig_t k); /** * Builds a precomputation table for multiplying a fixed binary elliptic point * using the binary method. * * @param[out] t - the precomputation table. * @param[in] p - the point to multiply. */ void eb_mul_pre_basic(eb_t *t, const eb_t p); /** * Builds a precomputation table for multiplying a fixed binary elliptic point * using Yao's windowing method. * * @param[out] t - the precomputation table. * @param[in] p - the point to multiply. */ void eb_mul_pre_yaowi(eb_t *t, const eb_t p); /** * Builds a precomputation table for multiplying a fixed binary elliptic point * using the NAF windowing method. * * @param[out] t - the precomputation table. * @param[in] p - the point to multiply. */ void eb_mul_pre_nafwi(eb_t *t, const eb_t p); /** * Builds a precomputation table for multiplying a fixed binary elliptic point * using the single-table comb method. * * @param[out] t - the precomputation table. * @param[in] p - the point to multiply. */ void eb_mul_pre_combs(eb_t *t, const eb_t p); /** * Builds a precomputation table for multiplying a fixed binary elliptic point * using the double-table comb method. * * @param[out] t - the precomputation table. * @param[in] p - the point to multiply. */ void eb_mul_pre_combd(eb_t *t, const eb_t p); /** * Builds a precomputation table for multiplying a fixed binary elliptic point * using the w-(T)NAF method. * * @param[out] t - the precomputation table. * @param[in] p - the point to multiply. */ void eb_mul_pre_lwnaf(eb_t *t, const eb_t p); /** * Multiplies a fixed binary elliptic point using a precomputation table and * the binary method. * * @param[out] r - the result. * @param[in] t - the precomputation table. * @param[in] k - the integer. */ void eb_mul_fix_basic(eb_t r, const eb_t *t, const bn_t k); /** * Multiplies a fixed binary elliptic point using a precomputation table and * Yao's windowing method * * @param[out] r - the result. * @param[in] t - the precomputation table. * @param[in] k - the integer. */ void eb_mul_fix_yaowi(eb_t r, const eb_t *t, const bn_t k); /** * Multiplies a fixed binary elliptic point using a precomputation table and * the w-(T)NAF method. * * @param[out] r - the result. * @param[in] t - the precomputation table. * @param[in] k - the integer. */ void eb_mul_fix_nafwi(eb_t r, const eb_t *t, const bn_t k); /** * Multiplies a fixed binary elliptic point using a precomputation table and * the single-table comb method. * * @param[out] r - the result. * @param[in] t - the precomputation table. * @param[in] k - the integer. */ void eb_mul_fix_combs(eb_t r, const eb_t *t, const bn_t k); /** * Multiplies a fixed binary elliptic point using a precomputation table and * the double-table comb method. * * @param[out] r - the result. * @param[in] t - the precomputation table. * @param[in] k - the integer. */ void eb_mul_fix_combd(eb_t r, const eb_t *t, const bn_t k); /** * Multiplies a fixed binary elliptic point using a precomputation table and * the w-(T)NAF method. * * @param[out] r - the result. * @param[in] t - the precomputation table. * @param[in] k - the integer. */ void eb_mul_fix_lwnaf(eb_t r, const eb_t *t, const bn_t k); /** * Multiplies and adds two binary elliptic curve points simultaneously using * scalar multiplication and point addition. * * @param[out] r - the result. * @param[in] p - the first point to multiply. * @param[in] k - the first integer. * @param[in] q - the second point to multiply. * @param[in] m - the second integer, */ void eb_mul_sim_basic(eb_t r, const eb_t p, const bn_t k, const eb_t q, const bn_t m); /** * Multiplies and adds two binary elliptic curve points simultaneously using * shamir's trick. * * @param[out] r - the result. * @param[in] p - the first point to multiply. * @param[in] k - the first integer. * @param[in] q - the second point to multiply. * @param[in] m - the second integer, */ void eb_mul_sim_trick(eb_t r, const eb_t p, const bn_t k, const eb_t q, const bn_t m); /** * Multiplies and adds two binary elliptic curve points simultaneously using * interleaving of NAFs. * * @param[out] r - the result. * @param[in] p - the first point to multiply. * @param[in] k - the first integer. * @param[in] q - the second point to multiply. * @param[in] m - the second integer, */ void eb_mul_sim_inter(eb_t r, const eb_t p, const bn_t k, const eb_t q, const bn_t m); /** * Multiplies and adds two binary elliptic curve points simultaneously using * Solinas' Joint Sparse Form. * * @param[out] r - the result. * @param[in] p - the first point to multiply. * @param[in] k - the first integer. * @param[in] q - the second point to multiply. * @param[in] m - the second integer, */ void eb_mul_sim_joint(eb_t r, const eb_t p, const bn_t k, const eb_t q, const bn_t m); /** * Multiplies and adds the generator and a binary elliptic curve point * simultaneously. Computes R = [k]G + [m]Q. * * @param[out] r - the result. * @param[in] k - the first integer. * @param[in] q - the second point to multiply. * @param[in] m - the second integer. */ void eb_mul_sim_gen(eb_t r, const bn_t k, const eb_t q, const bn_t m); /** * Converts a point to affine coordinates. * * @param[out] r - the result. * @param[in] p - the point to convert. */ void eb_norm(eb_t r, const eb_t p); /** * Converts multiple points to affine coordinates. * * @param[out] r - the result. * @param[in] t - the points to convert. * @param[in] n - the number of points. */ void eb_norm_sim(eb_t *r, const eb_t *t, int n); /** * Maps a byte array to a point in a binary elliptic curve. * * @param[out] p - the result. * @param[in] msg - the byte array to map. * @param[in] len - the array length in bytes. */ void eb_map(eb_t p, const uint8_t *msg, int len); /** * Compresses a point. * * @param[out] r - the result. * @param[in] p - the point to compress. */ void eb_pck(eb_t r, const eb_t p); /** * Decompresses a point. * * @param[out] r - the result. * @param[in] p - the point to decompress. * @return if the decompression was successful */ int eb_upk(eb_t r, const eb_t p); #endif /* !RLC_EB_H */