Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - soplo

#1
Scripting / script para grabar cdrom
28 Noviembre 2010, 15:55 PM
Hola
Como sabeis XP tiene la capacidad de grabar un archivo en un cd virgen sin necesidad de nero ni cosas semejantes.

Pues yo quiero automatizar eso. Quiero un script que me permita grabar un archivo a un cd de forma automática. En definitiva lo que yo quieo es que la salida de una aplicacion se guarde en un cdrom al modo de que fuera un disquete. Dado que ese programa deja un fichero yo quiero mediante un batch dejar ese fichero en un cdrom.

Y no encuentro información de quien hace eso y como. Todo lo que veo por ahí es que use nero.

¿alguna idea?
#2
Solo para decir que ando muy liado, pero en cuanto pueda vuelvo a la faena je je je.

Eso del criptoanalisis suena muy interesanete xDDD. Además tengo por ahi el código Miller-Rabin que en cuanto pueda dedicarle tiempo quedará como es debido osea funcionando ja ja ja.

Un saludo
#3
Para facilitar la comprensión he modificado el código anterior (solo para este hilo) a fin de ver si encontramos donde está el error. He omitido las funciones GMP y las he escrito en C clásico con el único interes de ver si hay algún error lógico.

A mi me parece que hay algo del algoritmo que no he puesto bien y por eso no me funciona adecuadamente, pero es que no lo veo.

Tal como está no funciona porque solo he cambiado textos, De hecho sé que faltan puntos y comas y tampoco están ni stdlib.h ni math.h pero da igual. Solo se trata de ver donde está el error para que no calcule bien.

Ahi va

int miller_rabin ( long  Num, int Comprobaciones )
{
  int r, s, EsPrimo=ES_PRIMO;
  long NumDec, ValorAleat, ValorAux, d, ValorTemp;
  if (ComprobarDivisibilidad(Num) == 0) { // comprobar si es divisible entre los primeros
    EsPrimo=NO_ES_PRIMO;   // 10.000 números primos
  }

Omito la función ComprobarDivisibilidad para no hacer mas tocho y me centro en Miller Rabin.

Miller Rabin requiere que se encuentre un par de números R y S tal que satisfagan que (N-1)=R * 2^S. Además R debe ser impar.

Num es el número a comprobar.
NumDec es Num-1

  NumDec=Num-1; //NumDec=Num-1
  d=NumDec

  s = 0;
  while ( mpz_even_p(d) ) {  //mientras d sea par
    mpz_fdiv_q_2exp(d, d, 1); // d=d/2
    s++;
  }

// Obtener la semilla para números aleatorios
srand(time(NULL))
ValorTemp=Num-4 //este valor se utiliza para el límite superior de número aleatorio a obtener

Aquí comienza el bucle de comprobación. Como dije MillerRabin tiene un factor de error y para asegurarnos que la respuesta es correcta en vez de hacer el test una vez lo hacemos varias. En mi caso 10 porque llamé a la función MillerRabin con el parámetro Comprobaciones=10.

Lo de EsPrimo es un valor boleano. Si antes resultó que es divisible entre algún número primo que no haga el bucle y se vaya al final.

while ( Comprobaciones-- > 0 && EsPrimo) {
    //Obtener un valor aleatorio en ValAleatorio entre 2 y Num-2
   
    ValorAleat=rand() * (ValorTemp)
    ValorAleat+=2 //obtener un valor aleatorio entre 2 y n-2

// Calcular ValorAux=ValorAleat^d mod Num
    ValorAux=pow(ValorAux,d) % Num

    if ( ValorAux == 1 ) { //si valoraux=1 es probable primo
         EsPrimo=ES_PRIMO; // es primo pero hay que comprobar mas
    } else {
         EsPrimo=NO_ES_PRIMO; //de momento no es primo.
    }
    if ( !EsPrimo && ValorAux == NumDec ) { //si valoraux= Num-1 probable primo
         EsPrimo=ES_PRIMO; //de momento es primo pero hay que comprobar mas
    } else {
         EsPrimo=NO_ES_PRIMO; //de momento no es primo.
    }

    if ( !EsPrimo ) { //si antes fue visto como no primo
       for(r=0; r < s-1; r++) {     
          ValorAux=pow(ValorAux,2) % Num
          if ( ValorAux == 1 ) {  // si ValorAux=1 es compuesto
             EsPrimo=NO_ES_PRIMO;
             break;
          }
       }
       if ( ValorAux<>NumDec ) { //si ValorAux<>Num-1 no es primo
             EsPrimo=NO_ES_PRIMO;
       }
       
       if ( !EsPrimo ) {
          break;
       }
    }   
  } //fin del while


¿donde demonios está el error?
#4
a mi también me parece que al final he acabado mareando la perdiz y poniendo algo mal. Por eso no me da bien. Tengo en mente hacer un manual de operaciones GPM porque es bastante antipático tal como viene en el manual de gnu mp 5.1.

En cualquier caso si tienes alguna duda con alguna línea no dudes en decirlo a ver si encontramos donde está el error (que seguro que es de bulto porque ya no se cuantas veces lo he tocado)

je je je
#5
Hola.

Estoy teniendo muchos problemas con la dichosa rutinita esta y aún no funciona. Para saberlo le meto un número que sé que es primo (porque aparece en alguna lista de números primos en internet) y me dice que no es primo así que no está bien.

Os pongo lo que tengo hecho a ver si encontramos la causa:

Puede salir un tocho porque voy a poner muchas anotaciones para que no os perdais con GMP pero bueno ...

Aquí empiezo. Incluyo gmp para poder trabajar con números grandes, defino dos funciones y creo una variable 104729 que es un número primo conocido para pasar el test. El resultado debe ser que ese número es primo.

Miller Rabin tiene un factor de error de 1/4 así que siempre se debe repetir el test varias veces para asegurarse que siempre que ese número pasa el test se devuelve que es primo. Si una sola vez saliera que es compuesto ya sabríamos que el númeor es compuesto.
# include <gmp.h>

# define ES_PRIMO 1
# define NO_ES_PRIMO 0

int miller_rabin_test ( mpz_t n, int k );
int ComprobarDivisibilidad( mpz_t n );

int main(void)
{
   int i;
   char *c="104729";
   mpz_t n;
   mpz_init(n); //inicio la variable n
   mpz_set_str(n,c,10); //meto el número a probar en n
   if ( miller_rabin(n, 10) == ES_PRIMO ) { // 10 es el número de comprobaciones que haré
       printf("%s es primol\n",c);
     } else {
       printf("%s no es primol\n",c);
     }
   
}


Ahora el test de Miller Rabin en sí mismo. Para facilitar la rapidez lo primero que hago es ver si es divisible por los primeros diez mil números primos conocidos. Si es divisible por alguno es que el número es compuesto y no hay que perder mas tiempo.

int miller_rabin ( mpz_t Num, int Comprobaciones )
{
  int r, s, EsPrimo=ES_PRIMO;
  mpz_t NumDec, ValorAleat, ValorAux, d, ValorTemp;
  if (ComprobarDivisibilidad(Num) == 0) { // comprobar si es divisible entre los primeros
    EsPrimo=NO_ES_PRIMO;   // 10.000 números primos
  }


Omito la función ComprobarDivisibilidad para no hacer mas tocho y me centro en Miller Rabin.

Miller Rabin requiere que se encuentre un par de números R y S tal que satisfagan que (N-1)=R * 2^S. Además R debe ser impar.

Num es el número a comprobar.
NumDec es Num-1
  mpz_init(d);
  mpz_init(NumDec);
  mpz_sub_ui(NumDec,Num,1); //NumDec=Num-1
  mpz_set(d,NumDec); // d=Num-1

  s = 0;
  while ( mpz_even_p(d) ) {  //mientras d sea par
    mpz_fdiv_q_2exp(d, d, 1); // d=d/2
    s++;
  }

Hasta aquí todo bien. Si llego hasta aquí es que el número a comprobar no es divisible entre los primeros 10.000 primos y he obtenido un valor R y S que requiere MillerRabin

Inicializo valores aleatorios (la semilla)
gmp_randstate_t semilla;
gmp_randinit_default(semilla);
gmp_randseed_ui (semilla, time(NULL));


Inicializo algunos valores que necesito
mpz_init(ValorAleat);
mpz_init(ValorAux);
mpz_init(ValorTemp);
mpz_sub_ui(ValorTemp,Num,4); //ValorTemp=num-4


Aquí comienza el bucle de comprobación. Como dije MillerRabin tiene un factor de error y para asegurarnos que la respuesta es correcta en vez de hacer el test una vez lo hacemos varias. En mi caso 10 porque llamé a la función MillerRabin con el parámetro Comprobaciones=10.

Lo de EsPrimo es un valor boleano. Si antes resultó que es divisible entre algún número primo que no haga el bucle y se vaya al final.
while ( Comprobaciones-- > 0 && EsPrimo) {
    //Obtener un valor aleatorio en ValAleatorio entre 2 y Num-2
    mpz_urandomm(ValorAleat,semilla,ValorTemp); //Obtener un valor aleatorio entre 0 y num-4
    mpz_add_ui(ValorAleat,ValorAleat,2); // ValorAleat=ValorAleat+2

// Calcular ValorAux=ValorAleat^d mod Num
    mpz_powm(ValorAux,ValorAleat,d,Num);

    if ( mpz_cmp_ui(ValorAux, 1) == 0 ) { //si valoraux=1 es probable primo
         EsPrimo=ES_PRIMO; // es primo pero hay que comprobar mas
    } else {
         EsPrimo=NO_ES_PRIMO; //de momento no es primo.
    }
    if ( !EsPrimo && mpz_cmp(ValorAux, NumDec) == 0 ) { //si valoraux= Num-1 probable primo
         EsPrimo=ES_PRIMO; //de momento es primo pero hay que comprobar mas
    } else {
         EsPrimo=NO_ES_PRIMO; //de momento no es primo.
    }

    if ( !EsPrimo ) { //si antes fue visto como no primo
       for(r=0; r < s-1; r++) {     
          mpz_powm_ui (ValorAux, ValorAux, 2, Num);  //ValorAux=ValorAux^2 mod Num         
          if ( mpz_cmp_ui(ValorAux,1) == 0) {  // si ValorAux=1 es compuesto
             EsPrimo=NO_ES_PRIMO;
             break;
          }
       }
       if ( mpz_cmp(ValorAux,NumDec) != 0 ) { //si ValorAux<>Num-1 no es primo
             EsPrimo=NO_ES_PRIMO;
       }
       
       if ( !EsPrimo ) {
          break;
       }
    }   
  } //fin del while

Ahora al final solo queda devolver el resultado EsPrimo que será verdadero o falso y limpiar memoria

  mpz_clear(ValorAux);
  mpz_clear(ValorTemp);
  mpz_clear(d);
  mpz_clear(NumDec);
  mpz_clear(ValorAleat);

  return (EsPrimo);
}


Pues no me funciona y no veo la razón. Se que estoy muy cerca pero hay algo que se me escapa.
Ese código se puede optimizar mucho. Lo he puesto así porque se ven mas claros los pasos que doy para seguir a MillerRabin.
#6
Joer no se porque me ha dado por confundir cifrar que firmar je je je.

El código de Miller Rabin no funciona bien de momento. He metido un número que se que es primo y me dice que no lo es. Tengo que hacer algunas pruebas aún pero pienso que mañana estará ja ja ja

En cuanto a los certificados:

Existe la posibilidad de crear yo mi propio CA. Eso es razonable si no necesito interoperar con esos certificados fuera de mi dominio porque obviamente yo confío en mi mismo. El inconveniente de eso es que los demás no confian en mi.

La segunda opción es contratar a una empresa CA externa tal como verisign. El problema de eso es que ellos cobran y si necesito muchos certificados puede ser un problema presupuestario.

Hay varios tipos de certificados: los x509 creo que son aquellos en los que yo tengo mi propia CA pero hay otros.

Por otra parte esté la cuestión del formato de los certificados. El mas utilizado es el PEM y DER que se suelen usar para las claves privadas. Todo esto lo tengo muy confuso. De hecho creo que estos formatos se corresponden con marcas registradas y así el pkcs#12 es el que usa Microsoft, PEM en el mundo unix y DER. Entiendo que esto debe ser un problema porque habrá veces que hay que extraer la información de un DER para convertirlo a PEM o lo que sea.

Aquí un enlace sobre los PEM, DER y pkcs
http://publikaccion.blogspot.com/2007/05/tipos-de-formatos-de-certificados.html

Aquí hay una buena ayuda para openssl (aunque en ingles) que ayuda a ver las distintas opciones y posibilidades.
http://www.madboa.com/geek/openssl/

Aquí hay un resumen de los distintos formatos PKCS
http://es.wikipedia.org/wiki/PKCS

Esto si que es un lio. Dificilo no pero lioso si.

;D
#7
Muy interesante je je je.

Respecto al test de Miller-Rabin lo tengo ya terminado, pero me estoy tomando un tiempo para asegurarme que está bien y no hay errores porque lo he hecho con gmp para números grandes y eso se sale del C estandar, es engorroso y lo ideal sería que la gente se lo pudiera pastear sin mas como una función. Por eso prefiero asegurarme no vaya a ser que en vez de ayudar lo joda todo je je je.

Respecto a los certificados me asalta una duda. Pongo la cosa tal como lo entiendo:

sistema asimétrico
Pongamos que A conecta la primera vez con B para establecer un canal seguro de comunicación. Si solo uso un sistema asimétrico el procedimiento es enviarle mi clave pública y que él me envíe la suya.

Cuando quiero A quiere enviar algún dato a B lo que hace es firmarlo con su clave pública y así solo lo podrá ver B. Igualmente si B quiere enviarme algo a A lo firmará con la clave pública de A y solo lo podrá ver A.

Man in the middle
El problema de esto tal como está expuesto es que un tercero C (de canalla) esté en el medio. Si A envía su clave pública a B la intercepta y en cambio envía la suya. B recibe una clave pública que cree que es de A pero no. Es de C.Cada vez que B firma algo con la clave pública de A en realidad lo  está haciendo con la de C y aunque cree que se lo envia a A en realidad se lo envía a C. Es decir, C se entera de todo.

certificados
La solución para evitar esto es que una tercera parte garantice que la clave pública de A es realmente de A. Para ello lo que hace es firmar la clave pública de A con su propia clave pública y así quien recibe una clave pública de A firmada por la entidad en la que se confía se tiene la seguridad de que esa clave pública es de quien dice ser. Si en esa situación el Canalla intentara lo mismo que antes no funcionaría porque la clave pública que envía a B no está firmada por la entidad de certificados. Esa es la razón por la que la entidad de certificados (CA) debe ser de toda confianza y si alguien consigue la clave privada de ese CA podrá firmar como si fuera ella y por tanto los certificados ya no serán seguros.

¿Es esto? ¿lo tengo bien entendido?

Tengo mas preguntas pero esperaré a ver si esto que he puesto está bien.

;D
#8
bueno bueno que yo no digo nada para meterte presión ni nada. Solo que estoy en ello porque me divierte y cuando puedas si quieres pues ya hablarás sobre ello y si no quieres no. Yo de momento leo lo que pones y agradezco tu dedicación nada mas.

Si para entonces está hecho igual te sirve (o igual no) para explicar lo que quieras pero nada mas. Nada de presión ni cosas de esas. Se te agradece tu tiempo y tus ganas y suerte con la estadística que es un peñazo.

:laugh:
#9
Efectivamente. Eso es lo que estoy haciendo: ver si es divisible entre números primos pequeños y conocidos. Si pasa eso entonces entra en el loop. Para eso utilizo la lista de los 10.000 primeros números primos.

CitarNo hace falta que pruebes divisibilidad por todos los números entre [2;n-1], podés limitar la prueba a [2;sqrt(n)]
Así lo estoy haciendo je je je.

De todas formas quisiera saber cual es el test de primalidad que te parece mas eficiente para números grandes.

Un saludo

#10
Lo que es yo lo llevo bastante bien.  Ahora estoy trabajando en el test de primalidad de Miller-Rabin y en breve espero poder postear una función en C que lo hace para números largos.

Será una buena ayuda porque para RSA, DSA, etc se debe partir de dos números primos. Con ese test de primalidad será posible obtener números primos de cualquier tamaño.

De todas formas para quien quiera hacer cositas y tener números primos tengo la lista de los 10.000 primeros números primos y así no necesitan calcularlos. Quien tenga interes que me lo diga y en paz.

;D