ECC Brainpool Curvas estándar y generación de curvas con Bouncy Castle ¿Qué semilla usar?

1

Quiero implementar un Acuerdo de clave ECC con una curva de Brainpool brainpoolP512r1 o brainpoolP512t1.

No tengo claro qué valor de semilla usar (y cómo). En este documento enlace se mencionan dos valores semilla.

Y RFC enlace

5.1 Generación de números primos

  

6636920D871574E69A458FEA3F4933D7E0D95748 para ECC 512

5.2 Generación de curvas pseudoaleatorias

  

02AC60ACC93ED874422A52ECB238FEEE5AB6AD para ECC 512

  • Entonces, ¿qué semilla debo usar en el constructor ECDomainParameters?
  • ¿El valor de semilla para la curva torcida es el mismo? Solo encuentro valores semilla para brainpool P512r1 y no para brainpoolP512t1
  • ¿Está la implementación correcta?

        // ECC 512 = AES 256 = RSA 15360
        var ecP = TeleTrusTNamedCurves.GetByName("brainpoolp512t1");
    
        // because ecP.GetSeed() is null !?
        // see spec "ECC Brainpool Standard Curves and Curve Generation" site 7
    
        // 5.1 Generation of prime numbers
        var seed_p_512PrimeNumbers = StringToByteArray("6636920D871574E69A458FEA3F4933D7E0D95748");
        // 5.2 Generation of pseudo-random curves
        var seed_p_512PseudoRandomCurves = StringToByteArray("02AC60ACC93ED874422A52ECB238FEEE5AB6AD");
    
        var ecSpec = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, seed_p_512PseudoRandomCurves);
    
        // Alice
    
        var enc = new UTF8Encoding();
        var secretPlain = "This is a secret.";
        var secretPlainBytes = enc.GetBytes(secretPlain);
    
    
        IAsymmetricCipherKeyPairGenerator aliceGenerator = GeneratorUtilities.GetKeyPairGenerator("ECDH");
        aliceGenerator.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));
        AsymmetricCipherKeyPair aliceKeyPair = aliceGenerator.GenerateKeyPair();
        IBasicAgreement aliceBasicAgreement = AgreementUtilities.GetBasicAgreement("ECDH");
        aliceBasicAgreement.Init(aliceKeyPair.Private);
    
    
        // Bob
    
        IAsymmetricCipherKeyPairGenerator bobGenerator = GeneratorUtilities.GetKeyPairGenerator("ECDH");
        bobGenerator.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));
        AsymmetricCipherKeyPair bobKeyPair = bobGenerator.GenerateKeyPair();
        IBasicAgreement bobBasicAgreement = AgreementUtilities.GetBasicAgreement("ECDH");
        bobBasicAgreement.Init(bobKeyPair.Private);
    
    
        // generate shared key
    
        var k1 = bobBasicAgreement.CalculateAgreement(aliceKeyPair.Public).ToByteArray();
        var k2 = aliceBasicAgreement.CalculateAgreement(bobKeyPair.Public).ToByteArray();
    
        for (int i = 0; i < k1.Length; i++)
        {
            if (k1[i] != k2[i])
            {
                throw new Exception("Secrets are not equal.");
            }
        }
    

¡Muchas gracias!

Daniel

    
pregunta dh_cgn 13.09.2013 - 10:59
fuente

1 respuesta

3

No tienes que especificar una semilla en absoluto.

Una curva elíptica se especifica mediante un puñado de parámetros:

  • la definición del campo en el que estás jugando (aquí, el campo consiste en los enteros módulo a un primo dado p );
  • la ecuación de la curva, aquí Y 2 = X 3 + aX + b para dos constantes a y b ;
  • un generador convencional G , que es un punto de curva (es decir, un par de coordenadas (X, Y) que coincide con la ecuación de la curva);
  • el orden n del generador y su cofactor h .

El orden n es el entero más pequeño que no es cero, por lo que nG = 0 ; h es tal que el número total de puntos en la curva es igual a nh . Normalmente, elegimos la curva tal que n es primo y h = 1 , es decir, el generador genera toda la curva, y con un orden principal adecuado para Diffie-Hellman o DSA .

La semilla no es necesaria en absoluto para calcular las cosas con la curva. La semilla se utilizó para generar la propia curva. Se trata de los " números de Nothing-Up-my-sleeve ". Es matemáticamente posible (o al menos puede ser) generar parámetros especiales con una estructura oculta ( p , a y b en las notaciones arriba) de modo que la curva se vea bien, pero de hecho es débil contra el criptoanálisis. La generación de curvas normal y honesta se ve así: generamos p , a y b completamente aleatorios, y luego verificamos los requisitos en sección 2 de RFC 5639 ; Si no están todos reunidos, inténtalo de nuevo. Los parámetros de formas especiales que inducen debilidades son extremadamente raros, por lo que la generación aleatoria está bien.

Para demostrar que se siguió este proceso normal y, por lo tanto, que los parámetros de la curva no fueron diseñados para ser especialmente débiles, es habitual especificar completamente el PRNG utilizado para producir todos los valores aleatorios , completa con su (s) semilla (s) de partida. Por lo tanto, terceros (por ejemplo, usted) pueden volver a ejecutar el PRNG y el proceso de generación de curvas, y ver que obtienen, de hecho, los mismos parámetros de curvas. Para las curvas de Brainpool, este PRNG se especifica en el apéndice A . Aquí, tienen dos semillas porque primero generan p , y solo entonces a y b , como dos pasos, cada uno con su propia semilla.

Sin embargo, no es necesario hacerlo cada vez . Cuando realice una re-generación de la curva, hágalo una vez , solo para asegurarse de que los parámetros que se encuentran en el RFC son legítimos. De hecho, no necesita hacerlo usted mismo, solo necesita convencerse de que alguien, en algún lugar, lo ha hecho. En cualquier caso, los parámetros de la curva que está a punto de usar ya están en Bouncy Castle.

Para simplemente usar la curva, la semilla no es necesaria y se puede establecer en null . Hay un espacio en la clase ECDomainParameters para especificar un seed porque algunos estándares (pero no todos) para codificar los parámetros de la curva tienen alguna disposición para admitir la inclusión de dicha semilla. Sin embargo, esto no se aplica realmente a su caso:

  • Tu código hablará con tu código; por lo tanto, ambas partes ya saben qué curva se utiliza, y no tienen necesidad de codificar los parámetros de la curva en ninguna parte.
  • Incluso si codifica los parámetros, no necesitará volver a ejecutar el proceso de generación de curvas, ya que cada parte usará sus propios parámetros codificados, no los enviados por el par.
  • En cualquier caso, no hay un estándar para la generación de parámetros PRNG. Brainpool tiene su propio, pero no hay un PRNG acordado que sea adecuado para todos (al contrario de los parámetros de DSA, donde el estándar en sí mismo lo incluye, consulte el apéndice A). De hecho, esto se puede ver en el hecho de que el proceso Brainpool utiliza dos semillas, no una.

Entonces, ahora mismo, la inclusión de seed en los parámetros codificados, y en la clase ECDomainParameters , es peso muerto puro. Solo configúralo en null y sigue adelante.

Al no ser un practicante de la API C # de Bouncy Castle, no puedo comentar sobre su uso, pero desde un punto de vista superficial, las cosas parecen estar bien. Su variable secretPlainBytes parece falsa; Supongo que es el mensaje que luego cifrará con la clave acordada (resultante del intercambio de clave DH), utilizando el código que no muestra.

    
respondido por el Tom Leek 13.09.2013 - 13:26
fuente

Lea otras preguntas en las etiquetas