elliptic_point elliptic_point::operator+(const elliptic_point &P) const{
  int lambda = 0;
  elliptic_point toReturn(0,0);
  
  if(this->isPOI)
    return P;
  else if(P.isPOI)
    return (*this);
  
  if((*this) == P){
    if(P.y == 0){
      toReturn.isPOI = true;
      return toReturn;
    }
    int twoypinv = modular_inverse(modular_positive(2 * P.y, mod), mod);
    lambda = modular_positive((3 * P.x * P.x + a) * twoypinv, mod);
  }else{
    if(this->x == P.x){
      toReturn.isPOI = true;
      return toReturn;
    }
    int xsinv = modular_inverse(modular_positive(this->x - P.x, mod), mod);
    lambda = modular_positive((this->y - P.y) * xsinv, mod);
  }

  toReturn.x = modular_positive(((lambda * lambda) - (P.x) - (this->x)), mod);
  toReturn.y = modular_positive(((lambda * (P.x - toReturn.x)) - P.y), mod);
  
  return toReturn;
}
Exemple #2
0
/* Z = (X * Y) mod M

   Not an mbedTLS function
*/
int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M)
{
    int ret;
    size_t num_words = hardware_words_needed(M);
    mbedtls_mpi Rinv;
    mbedtls_mpi_uint Mprime;

    /* Calculate and load the first stage montgomery multiplication */
    mbedtls_mpi_init(&Rinv);
    MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, num_words));
    Mprime = modular_inverse(M);

    esp_mpi_acquire_hardware();

    /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */
    mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words);
    mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
    mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, &Rinv, num_words);
    REG_WRITE(RSA_M_DASH_REG, (uint32_t)Mprime);

    /* "mode" register loaded with number of 512-bit blocks, minus 1 */
    REG_WRITE(RSA_MULT_MODE_REG, (num_words / 16) - 1);

    /* Execute first stage montgomery multiplication */
    execute_op(RSA_MULT_START_REG);

    /* execute second stage */
    MBEDTLS_MPI_CHK( modular_multiply_finish(Z, X, Y, num_words) );

    esp_mpi_release_hardware();

 cleanup:
    mbedtls_mpi_free(&Rinv);
    return ret;
}
Exemple #3
0
/**
 * @brief Pre-calculate some of the expensive steps in reduction. 
 *
 * This function should only be called once (normally when a session starts).
 * When the session is over, bi_free_mod() should be called. bi_mod_power()
 * relies on this function being called.
 * @param ctx [in]  The bigint session context.
 * @param bim [in]  The bigint modulus that will be used.
 * @param mod_offset [in] There are three moduluii that can be stored - the
 * standard modulus, and its two primes p and q. This offset refers to which
 * modulus we are referring to.
 * @see bi_free_mod(), bi_mod_power().
 */
void ICACHE_FLASH_ATTR bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
{
    int k = bim->size;
    comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
#ifdef CONFIG_BIGINT_MONTGOMERY
    bigint *R, *R2;
#endif

    ctx->bi_mod[mod_offset] = bim;
    bi_permanent(ctx->bi_mod[mod_offset]);
    ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
    bi_permanent(ctx->bi_normalised_mod[mod_offset]);

#if defined(CONFIG_BIGINT_MONTGOMERY)
    /* set montgomery variables */
    R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1);     /* R */
    R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1);  /* R^2 */
    ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2);             /* R^2 mod m */
    ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R);               /* R mod m */

    bi_permanent(ctx->bi_RR_mod_m[mod_offset]);
    bi_permanent(ctx->bi_R_mod_m[mod_offset]);

    ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]);

#elif defined (CONFIG_BIGINT_BARRETT)
    ctx->bi_mu[mod_offset] = 
        bi_divide(ctx, comp_left_shift(
            bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0);
    bi_permanent(ctx->bi_mu[mod_offset]);
#endif
}
void GaussianElimination(Matrix &M0){
    for(int i = 0,r = 0;r<R && i<C;++i){
        bool found = false;
        
        for(int j = r;j<R;++j){
            if(M0.X[j][i]>0){
                found = true;
                
                if(j==r) break;
                
                for(int k = i;k<C;++k) swap(M0.X[r][k],M0.X[j][k]);
                break;
            }
        }
        
        if(found){
            int aux = modular_inverse(M0.X[r][i],MOD);
            
            for(int j = i;j<C;++j) M0.X[r][j] = (M0.X[r][j]*aux)%MOD;
            
            for(int j = r+1;j<R;++j){
                aux = MOD-M0.X[j][i];
                for(int k = i;k<C;++k)
                    M0.X[j][k] = (M0.X[j][k]+aux*M0.X[r][k])%MOD;
            }
            
            ++r;
        }else return;
    }
    
    for(int i = R-1;i>0;--i)
        for(int j = 0;j<i;++j)
            M0.X[j][C-1] = (M0.X[j][C-1]+(MOD-M0.X[j][i])*M0.X[i][C-1])%MOD;
}
int main(int argc,char *argv[])
{
	
	int sample = 15;
	int prime = 31;
	
	printf("%d\n",modular_inverse(sample, prime));
	return 0;
}
int main( void )
{
    printf( "%d\n", modular_inverse( 3, 11 ) );
    return 0;
}
Exemple #7
0
/*
 * Sliding-window exponentiation: Z = X^Y mod M  (HAC 14.85)
 *
 * _Rinv is optional pre-calculated version of Rinv (via calculate_rinv()).
 *
 * (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv)
 *
 */
int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi* Y, const mbedtls_mpi* M, mbedtls_mpi* _Rinv )
{
    int ret = 0;
    size_t z_words = hardware_words_needed(Z);
    size_t x_words = hardware_words_needed(X);
    size_t y_words = hardware_words_needed(Y);
    size_t m_words = hardware_words_needed(M);
    size_t num_words;

    mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */
    mbedtls_mpi *Rinv;    /* points to _Rinv (if not NULL) othwerwise &RR_new */
    mbedtls_mpi_uint Mprime;

    /* "all numbers must be the same length", so choose longest number
       as cardinal length of operation...
    */
    num_words = z_words;
    if (x_words > num_words) {
        num_words = x_words;
    }
    if (y_words > num_words) {
        num_words = y_words;
    }
    if (m_words > num_words) {
        num_words = m_words;
    }

    if (num_words * 32 > 4096) {
        return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    }

    /* Determine RR pointer, either _RR for cached value
       or local RR_new */
    if (_Rinv == NULL) {
        mbedtls_mpi_init(&Rinv_new);
        Rinv = &Rinv_new;
    } else {
        Rinv = _Rinv;
    }
    if (Rinv->p == NULL) {
        MBEDTLS_MPI_CHK(calculate_rinv(Rinv, M, num_words));
    }

    Mprime = modular_inverse(M);

    esp_mpi_acquire_hardware();

    /* "mode" register loaded with number of 512-bit blocks, minus 1 */
    REG_WRITE(RSA_MODEXP_MODE_REG, (num_words / 16) - 1);

    /* Load M, X, Rinv, M-prime (M-prime is mod 2^32) */
    mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
    mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words);
    mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words);
    mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words);
    REG_WRITE(RSA_M_DASH_REG, Mprime);

    execute_op(RSA_START_MODEXP_REG);

    ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, num_words);

    esp_mpi_release_hardware();

 cleanup:
    if (_Rinv == NULL) {
        mbedtls_mpi_free(&Rinv_new);
    }

    return ret;
}
Exemple #8
0
void rsa_generate(unsigned int b_size) {

    mpz_t p, q, n, d, e, phi;
    mpz_t phi_p, phi_q, p_mod;
    int p_size = b_size/2, q_size = b_size - b_size/2;

    mpz_init(p);
    mpz_init(q);
    mpz_init(n);
    mpz_init(d);
    mpz_init(e);
    mpz_init(phi);
    mpz_init(phi_p);
    mpz_init(phi_q);
    mpz_init(p_mod);

    do {
        /* prvocisla p,q */
        do {

            do {
                /* p */
                gen_prime(p_size,p);

                /* q */
                gen_prime(q_size,q);

            } while(mpz_cmp(p,q) == 0);/* p a q sa nerovnaju */

            /* phi */
            mpz_sub_ui(phi_p,p,1);
            mpz_sub_ui(phi_q,q,1);
            mpz_mul(phi,phi_q,phi_p);

            /* e */
            if(mpz_cmp_ui(phi,65537) > 0) { /* phi > 65537 */
                mpz_set_ui(e,65537);
            } else if(mpz_cmp_ui(phi,17) > 0) { /* phi > 17 */
                mpz_set_ui(e,17);
            } else {
                mpz_set_ui(e,3);
            }


            mpz_mod(p_mod,p,e);
        } while(mpz_cmp_ui(p_mod,1) == 0);/* (p mod e) !=1 */

        /* modulus n */
        mpz_mul(n,p,q);

        /* d */
        modular_inverse(e,phi,d);
    } while(mpz_cmp_ui(d,0) == 0); /* dokial nenajdes spravne, pre ktore existuj inverzia */

#ifdef DEBUG
    gmp_printf("p: %Zd\nq: %Zd\nn: %Zd\nphi: %Zd\ne: %Zd\nd: %Zd\n",p,q,n,phi,e,d);
#endif

    gmp_printf("0x%Zx 0x%Zx 0x%Zx 0x%Zx 0x%Zx\n",p,q,n,e,d);

    mpz_clear(p);
    mpz_clear(q);
    mpz_clear(n);
    mpz_clear(d);
    mpz_clear(e);
    mpz_clear(phi);
    mpz_clear(phi_p);
    mpz_clear(phi_q);
    mpz_clear(p_mod);
}