Bitcoin Forum
May 25, 2024, 10:58:45 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Como obtener un número aleatorio  (Read 1569 times)
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 11, 2013, 10:49:42 AM
 #1

Hola Bitcoiners, como veo esto muy parado, voy a darle vidilla con una pregunta.

Estoy haciendo una aplicación para bitcoin y necesito generar un número aleatorio cada X segundos, pero claro debe ser un método transparente y que no haya posibilidad alguna de tongo, y que de ninguna forma se pueda conocer de antemano, es decir la secuencia es:

  • Ronda de apuestas
  • Se cierra la ronda de apuestas
  • Se genera un número aleatorio
  • Verificación de las apuestas

Mi idea es la siguiente, tener dos direcciones públicas de bitcoin la dirección A y B. En el momento de generar la apuesta, la dirección A envía a la dirección B un valor de 0.001 btc, ahora tomo el identificador de la transacción y lo uso como semilla para generar un número.

El problema es que como tenga que pagar la comisión a los mineros, me arruino, porque son muchas al día. Bueno eso usando la api de blockchain. Tenia pensado hacer yo usando el bitcoind, y no meter comisión pq lo que realmente me interesa es el id de la transacción, no me importa el tiempo que tarde en llegar la transacción.

Mi pregunta es, ¿se os ocurre otro método?

Es imperativo, que la generación del número aleatorio de haga en el momento en las apuestas estén cerradas, y que ni yo mismo pudiera de ninguna forma ver el resultado con aterioridad. Es que hay algunas webs como está por ejemplo kamikaze que te lo hacen así:

Quote
sha256(datastring):58708576054347ff18e82b43c01c9714baae06f181c9bdfa6413b3fa6b981346
datastring:will apear after you end the game

A mi eso no me vale, porque el creador de la página podría conocer de antemano el resultado.

Un Saludo y Gracias,


Bitcoin, the weapon of freedom massive.
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
June 11, 2013, 11:18:23 AM
 #2

Estoy haciendo una aplicación para bitcoin y necesito generar un número aleatorio cada X segundos, pero claro debe ser un método transparente y que no haya posibilidad alguna de tongo, y que de ninguna forma se pueda conocer de antemano

Se suele hacer a partir de un algo (un número, o una palabra…) secreto que sólo conoce el servidor y otro algo que sólo conoce el usuario. Así, ninguno de los dos tiene control sobre el resultado final. En FlipSide lo que hago es mostrar al usuario el hash del primer valor y le permito escoger el segundo; cuando ya tengo los dos, genero las cartas aleatoriamente y al final publico los datos de cómo se han generado para que pueda comprobarse que no ha habido trampa.

En tu caso, durante la ronda de apuestas, cada jugador podría proponer su propio secreto y luego tú combinas lo de todos los jugadores para crear el número aleatorio (si no me equivoco no sería necesario que tú también tuvieras tu propio secreto en este caso).
Shevek
Sr. Member
****
Offline Offline

Activity: 252
Merit: 250



View Profile
June 11, 2013, 11:24:10 AM
 #3

http://www.random.org
http://fourmilab.ch/hotbits

Proposals for improving bitcoin are like asses: everybody has one
1SheveKuPHpzpLqSvPSavik9wnC51voBa
LotoADN
Full Member
***
Offline Offline

Activity: 201
Merit: 100


BCH is the dream of Satoshi Nakamoto


View Profile
June 11, 2013, 11:30:33 AM
 #4

Aqui tienes un generador de numeros aleatorios TrueRandom

Una manera muy trasparente de obtener aleatoriedad pura es que el generador de la secuencia aleatoria sea externo e independiente de tu servicio, así, por ejemplo, en LotoADN obtenemos la parte aleatoria del resultado del sorteo de Bonoloto y La Primitiva, de esta forma no podemos saber de antemano que numeros saldrán al no generar nosotros ninguna secuencia aleatoria y por otro lado, los que generan la secuencia (en este caso SELAE) no conocen cuales son las apuestas jugadas y por tanto no pueden interferir en el resultado del escrutinio. Además, durante el proceso del sorteo, el servicio se cierra y no se pueden manipular las apuestas recibidas ya que todo ha sido encapsulado en un proceso automatico en el que no interviene la mano humana.

Un saludo
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 11, 2013, 01:32:07 PM
 #5

Estoy haciendo una aplicación para bitcoin y necesito generar un número aleatorio cada X segundos, pero claro debe ser un método transparente y que no haya posibilidad alguna de tongo, y que de ninguna forma se pueda conocer de antemano

Se suele hacer a partir de un algo (un número, o una palabra…) secreto que sólo conoce el servidor y otro algo que sólo conoce el usuario. Así, ninguno de los dos tiene control sobre el resultado final. En FlipSide lo que hago es mostrar al usuario el hash del primer valor y le permito escoger el segundo; cuando ya tengo los dos, genero las cartas aleatoriamente y al final publico los datos de cómo se han generado para que pueda comprobarse que no ha habido trampa.

En tu caso, durante la ronda de apuestas, cada jugador podría proponer su propio secreto y luego tú combinas lo de todos los jugadores para crear el número aleatorio (si no me equivoco no sería necesario que tú también tuvieras tu propio secreto en este caso).

Hola, gracias, pero no serviría pq hay más de un usuario

Bitcoin, the weapon of freedom massive.
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 11, 2013, 01:33:35 PM
 #6

La solución de http://www.random.org me parece buena, aunque me gustaría que quedara todo en la cadena de bloques y que pudiera ser verificado.

Bitcoin, the weapon of freedom massive.
LuisCar
Legendary
*
Offline Offline

Activity: 1820
Merit: 1017



View Profile
June 11, 2013, 02:37:02 PM
 #7

Si el número no lo necesitas de inmediato, puedes tomarlo del hash del último bloque minado.

dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
June 11, 2013, 05:23:07 PM
 #8

Hola, gracias, pero no serviría pq hay más de un usuario

Precisamente!

Usuario 1 escoge la palabra "cakita".
Usuario 2 escoge la palabra "4coins".
Usuario 3 escoge la palabra "yasolofaltan2dias!!".

Y después de que todas las apuestas estén hechas, el servidor hace por ejemplo un sha384 de "cakita4coinsyasolofaltan2dias!!" y toma los últimos 32 bits como el número aleatorio buscado. Al acabar el juego, publicas las palabras que ha escogido cada uno, el hash del conjunto y el número resultante.

¿Con random.org puedes probar que no has generado el número por tu cuenta?
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 12, 2013, 09:54:14 AM
 #9

Hola, gracias, pero no serviría pq hay más de un usuario

Precisamente!

Usuario 1 escoge la palabra "cakita".
Usuario 2 escoge la palabra "4coins".
Usuario 3 escoge la palabra "yasolofaltan2dias!!".

Y después de que todas las apuestas estén hechas, el servidor hace por ejemplo un sha384 de "cakita4coinsyasolofaltan2dias!!" y toma los últimos 32 bits como el número aleatorio buscado. Al acabar el juego, publicas las palabras que ha escogido cada uno, el hash del conjunto y el número resultante.

¿Con random.org puedes probar que no has generado el número por tu cuenta?

Es cierto con random.org, es dificil probar que no se ha metido la mano.
Lo que comentas de los usuarios, no lo veo bien, pq se generaría un número cada 30 sg así que obligar a todos los usuarios a meter un datos, como que me mandan a freir esparragos.

Creo que lo mejor es la primera idea, enviar una cantidad fija de la dirección A a la B, conocidas por todos, y en la propia descripcción de la transacción incluir el id del juego etc, tomar el hash de la transacción y usarlo como semilla. La pega es las comisiones de los minero que sería bastante.


Bitcoin, the weapon of freedom massive.
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 12, 2013, 09:54:59 AM
 #10

Si el número no lo necesitas de inmediato, puedes tomarlo del hash del último bloque minado.

Es que como es tan poco tiempo, sería generar uno cada 30 sg, tendría que repetir bloque

Bitcoin, the weapon of freedom massive.
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
June 12, 2013, 12:30:19 PM
 #11

Lo que comentas de los usuarios, no lo veo bien, pq se generaría un número cada 30 sg así que obligar a todos los usuarios a meter un datos, como que me mandan a freir esparragos.

Aaaamigo, es que eso no lo dijiste al principio Smiley.


Creo que lo mejor es la primera idea, enviar una cantidad fija de la dirección A a la B, conocidas por todos, y en la propia descripcción de la transacción incluir el id del juego etc, tomar el hash de la transacción y usarlo como semilla. La pega es las comisiones de los minero que sería bastante.

Eso es spam, por supuesto que te van a freír a comisiones.

Lo que puedes hacer es pasarle a un generador de números aleatorios cualquiera (por ejemplo en FlipSide yo uso uno llamado ISAAC) una semilla escogida de antemano. Así, la secuencia generada es reproducible y verificable por cualquiera. Puedes por ejemplo usar una semilla diferente cada día y publicar su hash. Al día siguiente publicas la semilla y los números derivados de la misma, y todos podrán mirar que los números generados coinciden con la lista.

Si necesitas probar que la secuencia de números aleatorios no te favorece (por ejemplo, podrían acusarte de escoger semillas cuya secuencia resultante consiste en números más bajos que el promedio esperado, lo que podría beneficiarte), entonces puedes condimentar la semilla con el hash del último bloque del día anterior, o algo así.
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 12, 2013, 01:48:40 PM
 #12

Lo que comentas de los usuarios, no lo veo bien, pq se generaría un número cada 30 sg así que obligar a todos los usuarios a meter un datos, como que me mandan a freir esparragos.

Aaaamigo, es que eso no lo dijiste al principio Smiley.


Creo que lo mejor es la primera idea, enviar una cantidad fija de la dirección A a la B, conocidas por todos, y en la propia descripcción de la transacción incluir el id del juego etc, tomar el hash de la transacción y usarlo como semilla. La pega es las comisiones de los minero que sería bastante.

Eso es spam, por supuesto que te van a freír a comisiones.

Lo que puedes hacer es pasarle a un generador de números aleatorios cualquiera (por ejemplo en FlipSide yo uso uno llamado ISAAC) una semilla escogida de antemano. Así, la secuencia generada es reproducible y verificable por cualquiera. Puedes por ejemplo usar una semilla diferente cada día y publicar su hash. Al día siguiente publicas la semilla y los números derivados de la misma, y todos podrán mirar que los números generados coinciden con la lista.

Si necesitas probar que la secuencia de números aleatorios no te favorece (por ejemplo, podrían acusarte de escoger semillas cuya secuencia resultante consiste en números más bajos que el promedio esperado, lo que podría beneficiarte), entonces puedes condimentar la semilla con el hash del último bloque del día anterior, o algo así.

si, pero aunque tome la semilla del último bloque del día anterior, la secuencia de números va a ser siempre la misma, con lo que podría saber todos los números del día.

Lo de enviar de una dirección A a otra B, lo veo como en satoshidice, no hay posiblidad de fraude.

De todas formas no me parece mala tu idea de tomar último bloque del día anterior, pero debería meterle algo que haga único el sorteo, como el total de jugadores + el total de apuestas. Pero si nos ponemos tiquismiquis también existiría la posiblidad de fraude.

Bitcoin, the weapon of freedom massive.
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
June 12, 2013, 05:32:31 PM
 #13

si, pero aunque tome la semilla del último bloque del día anterior, la secuencia de números va a ser siempre la misma, con lo que podría saber todos los números del día.

Cada semilla da una secuencia diferente, nunca te vas a encontrar eso de que la secuencia sea la misma. Si ocurre, el generador de números aleatorios es para tirar a la basura.


De todas formas no me parece mala tu idea de tomar último bloque del día anterior, pero debería meterle algo que haga único el sorteo, como el total de jugadores + el total de apuestas.

Ahí ya puede ser lo que tú quieras, pregenerado y sin necesidad de probar nada, ya que el hecho de que lo combinas con un block hash que es impredecible, ya implica que no has podido hacer trampa. Y quien dice block hash dice números de la bonoloto o lo que sea. Así que la semilla de mañana puede ser "hellokitty" concatenado con el hash del último bloque de hoy y la semilla de pasadomañana puede ser "horariodecajasolode0815a1100" combinado con el hash del último bloque de mañana.
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 12, 2013, 09:59:51 PM
 #14

si, pero aunque tome la semilla del último bloque del día anterior, la secuencia de números va a ser siempre la misma, con lo que podría saber todos los números del día.

Cada semilla da una secuencia diferente, nunca te vas a encontrar eso de que la secuencia sea la misma. Si ocurre, el generador de números aleatorios es para tirar a la basura.


A lo que me refiero es que si por ejemplo el último bloque es a las 23:59:00, luego todo ese bloque como semilla. Con esa semilla yo ya puedo conocer todos los números del día siguiente.


Bitcoin, the weapon of freedom massive.
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
June 13, 2013, 04:35:41 AM
 #15

A lo que me refiero es que si por ejemplo el último bloque es a las 23:59:00, luego todo ese bloque como semilla. Con esa semilla yo ya puedo conocer todos los números del día siguiente.

¿Eso te da ventaja?
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 13, 2013, 07:20:07 AM
 #16

A lo que me refiero es que si por ejemplo el último bloque es a las 23:59:00, luego todo ese bloque como semilla. Con esa semilla yo ya puedo conocer todos los números del día siguiente.

¿Eso te da ventaja?

Si, porque conozco todo lo que va ha pasar.

Bitcoin, the weapon of freedom massive.
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
June 13, 2013, 07:28:20 AM
 #17

Entonces el esquema de enviarte una transacción a ti mismo tampoco te sirve, pues el txid se puede manipular.
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 13, 2013, 10:52:03 AM
 #18

Entonces el esquema de enviarte una transacción a ti mismo tampoco te sirve, pues el txid se puede manipular.

ah, pues vaya putada.

Entonces creo que una solución puede ser:

  • Tomar el hash del último bloque generado
  • Al realizar una apuesta cada jugador mete un número o cadena aleatorio, que se toma en cuenta para el calculo

pero claro, yo podría despues de recoger todas las apuestas, poner una más y hacer que salga el resultado que me de la real gana.

Es que son apuestas p2p, usuario contra usuario

Bitcoin, the weapon of freedom massive.
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
June 13, 2013, 12:22:49 PM
 #19

Entonces creo que una solución puede ser:

  • Tomar el hash del último bloque generado
  • Al realizar una apuesta cada jugador mete un número o cadena aleatorio, que se toma en cuenta para el calculo

pero claro, yo podría despues de recoger todas las apuestas, poner una más y hacer que salga el resultado que me de la real gana.

Es que son apuestas p2p, usuario contra usuario

En este escenario el block hash no te aporta nada. Luego, si lo estoy entendiendo bien, no es p2p como tal pues está centralizado en tu web.

Habría que hacerlo en varias rondas, primero todos los usuarios enviando un hash del valor aleatorio (generado en lado de cliente con JS) y, cuando ya se conocen todos los hashes, envían el valor original para que luego en el servidor se validen y combinen todos, y se genera el número de marras.

Ejemplo:

  • Usuario 1 envía el hash 7d990ec5dc5fb372001a6745a03ac1dcd778f0f4fcdb6d91dd101c3024e33fa3.
  • Usuario 2 envía el hash 6a808995f1b43b5e0ca8fedb04d3c4b6decc11e720ed0008ecc8113d8722675a.
  • Usuario 3, potencialmente tú, envía el hash 86cb2b211a4c42e4694bc42b7d0b8b448fb108c6aa34bcc349ebaac7d81ec2af.
  • En este punto, con todos los hashes conocidos, pasamos a la siguiente ronda:
  • Usuario 1 envía sf8989dsf.
  • Usuario 2 envía drg8d9fg9.
  • Usuario 3 envía dgih8d9gd. No puedes falsificarlo.
  • El servidor comprueba que el hash de cada valor coincide con el enviado previamente.
  • El servidor combina los valores (por ejemplo, con una simple concatenación, "sf8989dsfdrg8d9fg9dgih8d9gd") y genera un número aleatorio a partir del resultado (por ejemplo, con tomando los primeros bits de un hash de la concatenación, "8c18bd55b8aba67be1087bf84319d0ac4def7934ef21faa484a99920de938268" → "8c18" → 35864).
  • Al final el servidor lo publica todo.
Para que no te manden a freír espárragos, puedes ya proponer un valor aleatorio cualquiera en la página, y que los usuarios sean libres de cambiarlo (así lo hago yo).

Si algún usuario se las arregla para editar el javascript en memoria y hacer que en la segunda ronda no envíe el valor en claro, conseguirá hacer un DoS sobre esa partida en particular (evitando que la partida avance, pues está esperando por él) por lo que debes implementar un timeout.
lukyforvar (OP)
Hero Member
*****
Offline Offline

Activity: 804
Merit: 1002



View Profile WWW
June 13, 2013, 01:34:16 PM
 #20

Entonces creo que una solución puede ser:

  • Tomar el hash del último bloque generado
  • Al realizar una apuesta cada jugador mete un número o cadena aleatorio, que se toma en cuenta para el calculo

pero claro, yo podría despues de recoger todas las apuestas, poner una más y hacer que salga el resultado que me de la real gana.

Es que son apuestas p2p, usuario contra usuario

En este escenario el block hash no te aporta nada. Luego, si lo estoy entendiendo bien, no es p2p como tal pues está centralizado en tu web.

Habría que hacerlo en varias rondas, primero todos los usuarios enviando un hash del valor aleatorio (generado en lado de cliente con JS) y, cuando ya se conocen todos los hashes, envían el valor original para que luego en el servidor se validen y combinen todos, y se genera el número de marras.

Ejemplo:

  • Usuario 1 envía el hash 7d990ec5dc5fb372001a6745a03ac1dcd778f0f4fcdb6d91dd101c3024e33fa3.
  • Usuario 2 envía el hash 6a808995f1b43b5e0ca8fedb04d3c4b6decc11e720ed0008ecc8113d8722675a.
  • Usuario 3, potencialmente tú, envía el hash 86cb2b211a4c42e4694bc42b7d0b8b448fb108c6aa34bcc349ebaac7d81ec2af.
  • En este punto, con todos los hashes conocidos, pasamos a la siguiente ronda:
  • Usuario 1 envía sf8989dsf.
  • Usuario 2 envía drg8d9fg9.
  • Usuario 3 envía dgih8d9gd. No puedes falsificarlo.
  • El servidor comprueba que el hash de cada valor coincide con el enviado previamente.
  • El servidor combina los valores (por ejemplo, con una simple concatenación, "sf8989dsfdrg8d9fg9dgih8d9gd") y genera un número aleatorio a partir del resultado (por ejemplo, con tomando los primeros bits de un hash de la concatenación, "8c18bd55b8aba67be1087bf84319d0ac4def7934ef21faa484a99920de938268" → "8c18" → 35864).
  • Al final el servidor lo publica todo.
Para que no te manden a freír espárragos, puedes ya proponer un valor aleatorio cualquiera en la página, y que los usuarios sean libres de cambiarlo (así lo hago yo).

Si algún usuario se las arregla para editar el javascript en memoria y hacer que en la segunda ronda no envíe el valor en claro, conseguirá hacer un DoS sobre esa partida en particular (evitando que la partida avance, pues está esperando por él) por lo que debes implementar un timeout.

jeje te lo has currado eh, gracias !! así si valdría

Bitcoin, the weapon of freedom massive.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!