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; }
/* 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; }
/** * @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; }
/* * 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; }
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); }