-
+ 73247011FCC9996859CAB02ADE955CD8D5FA04B85593E182645EBE0F497686ABFC771ECDF1E43B0E39506C85B25F365D80A81031FB82F13919E2FF5824EDA5EF
smg_comms/rsa/include/smg_rsa.h
(0 . 0)(1 . 242)
8606 /* smg_rsa.h
8607 * S.MG, 2017
8608 */
8609
8610 #ifndef SMG_RSA_H
8611 #define SMG_RSA_H
8612
8613 #include "mpi.h"
8614 #include "knobs.h"
8615
8616 /* A way to determine endianness at runtime.
8617 * Required for diddling a float's mantissa for instance.
8618 */
8619 static const int onect = 1;
8620 #define is_bigendian() ( (*(char*)&onect) == 0 )
8621
8622 /*
8623 * These are constants as per Eulora's protocol specification, NOT knobs!
8624 * Eulora uses RSA keys of 3920 bits (490 octets);
8625 * The above key length means 2 primes of 1960 bits (245 octets) each.
8626 * NB: if you choose here an odd key length in octets you might end up with a smaller actual key, read the code.
8627 */
8628 static const int KEY_LENGTH_OCTETS = 490;
8629
8630 typedef struct {
8631 MPI n; /* modulus */
8632 MPI e; /* public exponent */
8633 } RSA_public_key;
8634
8635 typedef struct {
8636 MPI n; /* public modulus */
8637 MPI e; /* public exponent */
8638 MPI d; /* private exponent: e*d=1 mod phi */
8639 MPI p; /* prime p */
8640 MPI q; /* prime q */
8641 MPI u; /* inverse of p mod q */
8642 } RSA_secret_key;
8643
8644
8645 /*********truerandom.c*********/
8646
8647 /*
8648 * Opens and configures (as per FG requirements) the specified entropy source (e.g. "/dev/ttyUSB0")
8649 * @param source_name the name of the file to open (e.g. "/dev/ttyUSB0")
8650 * @return the descriptor of the open file when successful; negative value otherwise
8651 */
8652 int open_entropy_source(char* source_name);
8653
8654
8655 /*
8656 * Returns noctets random octets (i.e. 8*noctets bits in total) as obtained from EuCrypt's preferred source.
8657 * Preferred source is defined in knobs.h as ENTROPY_SOURCE and should be a TRNG (e.g. Fuckgoats).
8658 * @param nboctets the length of desired random sequence, in octets
8659 * @param out pointer to allocated memory space for the requested random noctets; NB: this method does NOT allocate space!
8660 * @return the actual number of octets that were obtained from the currently configured entropy source (this is equal to noctets on successful read of required noctets)
8661 */
8662 int get_random_octets(int noctets, unsigned char *out);
8663
8664 /* Returns noctets random octets as obtained from the specified "from" source;
8665 * NB: the "from" source is considered to be the handle of an already opened stream;
8666 * This method will simply attempt to read from the source as needed!
8667 *
8668 * @param noctets the length of desired random sequence, in octets
8669 * @param out pointer to allocated memory space for the requested random octets;
8670 * NB: this method does NOT allocate space!
8671 * @param from handle of an already opened entropy source - this method will just READ from it as needed
8672 * @return the actual number of octets that were obtained
8673 */
8674 int get_random_octets_from(int noctets, unsigned char *out, int from);
8675
8676 /* Returns (in parameter *n) a *potentially biased* random float between 0 and 1
8677 * Uses bits from ENTROPY_SOURCE but it rounds when converting to float
8678 * NB: This function rounds impredictably.
8679 Use it ONLY if LSB normalization is insignificant to you!
8680 * This function uses rng_uint64 below.
8681 *
8682 * @param n - a float value (LSB rounded) between 0 and 1, obtained using
8683 * a 64-bit random integer (64 bits from ENTROPY_SOURCE)
8684 * @return - a positive value on success and a negative value in case of error
8685 * main possible cause for error: failure to open ENTROPY_SOURCE.
8686 * NB: a non-responsive/malconfigured source can result in blocking
8687 */
8688 int rng_dirty_float(float *n);
8689
8690
8691 /* Returns (in parameter *n) a randomly generated float between 1 and 2 using:
8692 * - the IEEE 754/1985 format for single float representation
8693 * - ENTROPY_SOURCE to obtain bits that are *directly* used as mantissa
8694 * NB: this value is between 1 and 2 due to the normalised format that includes
8695 * an implicit 1 ( i.e. value is (-1)^sign * 2^(e-127) * (1.mantissa) )
8696 *
8697 * From IEEE 754/1985, a description of the single float format:
8698 * msb means most significant bit
8699 * lsb means least significant bit
8700 * 1 8 23 ... widths
8701 * +-+-------+-----------------------+
8702 * |s| e | f |
8703 * +-+-------+-----------------------+
8704 * msb lsb msb lsb ... order
8705
8706 * A 32-bit single format number X is divided as shown in the figure above. The
8707 * value v of X is inferred from its constituent fields thus:
8708 * 1. If e = 255 and f != 0 , then v is NaN regardless of s
8709 * 2. If e = 255 and f = 0 , then v = (-1)^s INFINITY
8710 * 3. If 0 < e < 255 , then v = (-1)^s * 2^(e-127) * ( 1.f )
8711 * 4. If e = 0 and f != 0 , then v = (-1)^s * 2^(-126) * ( 0.f ) (denormalized
8712 * numbers)
8713 * 5. If e = 0 and f = 0 , then v = ( -1 )^s * 0 (zero)
8714 *
8715 * @param n - the address of an IEEE 754/1985 float: its mantissa will be set to
8716 * random bits obtained from ENTROPY_SOURCE; its sign will be set
8717 * to 0; its exponent will be set to 127 (the bias value so
8718 * that the actual exponent is 0).
8719 * @return - a positive value on success and a negative value in case of error
8720 * main possible cause for error: failure to open ENTROPY_SOURCE.
8721 * NB: a non-responsive/malconfigured source can result in blocking
8722 */
8723 int rng_float_754_1985(float *n);
8724
8725 /* Returns (in parameter *n) a random unsigned integer value on 32 bits.
8726 * Uses random bits from ENTROPY_SOURCE that are directly interpreted as int
8727 *
8728 * @param n - it will contain the random integer obtained by interpreting 32
8729 * bits from ENTROPY_SOURCE as an unsigned int value on 32 bits.
8730 * @return - a positive value on success and a negative value in case of error
8731 */
8732 int rng_uint32( uint32_t *n );
8733
8734 /* Returns (in parameter *n) a random unsigned integer value on 64 bits.
8735 * Uses random bits from ENTROPY_SOURCE that are directly interpreted as int
8736 *
8737 * @param n - it will contain the random integer obtained by interpreting 64
8738 * bits from ENTROPY_SOURCE as an unsigned int value on 64 bits.
8739 * @return - a positive value on success and a negative value in case of error
8740 */
8741 int rng_uint64( uint64_t *n );
8742
8743 /*********primegen.c*********/
8744
8745 /*
8746 * This is an implementation of the Miller-Rabin probabilistic primality test:
8747 * checking the specified number of randomly-chosen candidate witnesses
8748 * (i.e. with an outer bound of (1/4)^nwitnesses).
8749 * NB: a 1 result from this test means that the given n is indeed composite (non-prime)
8750 but a 0 result does not fully guarantee that n is prime!
8751 If this doesn't make sense to you, read more on probabilistic primality tests.
8752 * @param n the candidate prime number;
8753 the function will investigate whether this number is composite or *likely* to be prime.
8754 How likely? It depends on the number of witnesses checked, see next parameter.
8755 * @param nwitnesses this is the number of randomly chosen candidate witnesses to the compositeness of n
8756 that will be checked; the outer bound of the algorithm depends on this.
8757 * @param entropy_source the source of entropy (ready to read from) that will be used
8758 to choose candidate witnesses to the compositeness of n.
8759 * @return 1 if at least one witness to the compositeness of n has been found
8760 (i.e. n is certainly composite);
8761 0 if no witness to the compositeness of n was found (i.e. it is likely that n is prime)
8762 * NB: the probability that n is *not* prime although this function returned 0 is
8763 less than (1/4)^nwitnesses, but it is NOT zero.
8764 */
8765 int is_composite( MPI n, int nwitnesses, int entropy_source);
8766
8767 /**
8768 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
8769 * NB: top 2 bits and bottom bit are ALWAYS 1! (i.e. a mask 110....01 is applied to the random bits)
8770 * a prime of 8*noctets long will have only (8*noctets-3) bits that are randomly chosen!
8771 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
8772 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
8773 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
8774 * Preconditions:
8775 * noctets > 0 (at least one octet!)
8776 * output has known allocated memory for at least nlimbs(noctets)
8777 * successful access to the entropy source
8778 * @param noctets the length of the desired prime number, in octets
8779 * @param output an MPI with sufficient memory allocated for a number that is noctets long
8780 */
8781 void gen_random_prime( unsigned int noctets, MPI output);
8782
8783 /*********rsa.c*********/
8784 /*
8785 * Generates a pair of public+private RSA keys using directly the entropy source
8786 * specified in include/knobs.h
8787 *
8788 * ALL RSA keys are 8*KEY_LENGTH_OCTETS bits out of
8789 * 2 8*KEY_LENGTH_OCTETS/2 bits primes, as per TMSR spec.
8790 *
8791 * @param sk a fully-allocated structure to hold the generated keypair (secret
8792 key structure holds all the elements anyway, public key is a subset of this)
8793 *
8794 * NB: this procedure does NOT allocate memory for components in sk!
8795 * caller should ALLOCATE enough memory for all the MPIs in sk
8796 * Precondition:
8797 * MPIs in sk have known allocated memory for the nlimbs fitting their TMSR size
8798 */
8799 void gen_keypair( RSA_secret_key *sk );
8800
8801 /****************
8802 * Public key operation. Encrypt input with pk and store result into output.
8803 *
8804 * output = input^e mod n , where e,n are elements of pkey.
8805 * NB: caller should allocate *sufficient* memory for output to hold the result.
8806 * NB: NO checks are made on input!
8807 *
8808 * @param output MPI with enough allocated memory to hold result of encryption
8809 * @param input MPI containing content to encrypt; it *has to be* different from
8810 output!
8811 * @param pk the public key that will be used to encrypt input
8812 *
8813 * Precondition:
8814 * output != input
8815 * Output and input have to be two distinct MPIs because of the sorry state of
8816 the underlying mpi lib that can't handle properly the case when those are the
8817 same.
8818 */
8819 void public_rsa( MPI output, MPI input, RSA_public_key *pk );
8820
8821
8822 /****************
8823 * Secret key operation. Decrypt input with sk and store result in output.
8824 *
8825 * output = input^d mod n , where d, n are elements of skey.
8826 *
8827 * This implementation uses the Chinese Remainder Theorem (CRT):
8828 *
8829 * out1 = input ^ (d mod (p-1)) mod p
8830 * out2 = input ^ (d mod (q-1)) mod q
8831 * h = u * (out2 - out1) mod q
8832 * output = out1 + h * p
8833 *
8834 * where out1, out2 and h are intermediate values, d,n,p,q,u are elements of
8835 skey. By using CRT, encryption is *faster*. Decide for yourself if this fits
8836 your needs though!
8837 * NB: it is the caller's responsibility to allocate memory for output!
8838 * NB: NO checks are made on input!
8839 *
8840 * @param output MPI with enough allocated memory to hold result of decryption
8841 * @param input MPI containing content to decrypt
8842 * @param sk the secret key that will be used to decrypt input
8843 */
8844 void secret_rsa( MPI output, MPI input, RSA_secret_key *sk );
8845
8846 #endif /*SMG_RSA*/
8847