]> www.wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
Merge branch 'master' of https://github.com/gost-engine/engine
authorDmitry Belyavskiy <beldmit@gmail.com>
Tue, 2 Oct 2018 07:28:54 +0000 (10:28 +0300)
committerDmitry Belyavskiy <beldmit@gmail.com>
Tue, 2 Oct 2018 07:28:54 +0000 (10:28 +0300)
CMakeLists.txt
gost_params.c
test_curves.c [new file with mode: 0644]

index 15fe22d5024c4a6ee35657891fdcf42331c287b5..774a1a7c2ae225b5ff4e878908f84c38f3306848 100644 (file)
@@ -113,6 +113,11 @@ set(GOST_ENGINE_SOURCE_FILES
         gost_omac_acpkm.c
         )
 
+add_executable(test_curves test_curves.c)
+target_link_libraries(test_curves gost_engine gost_core ${OPENSSL_CRYPTO_LIBRARY})
+add_test(NAME curves
+       COMMAND test_curves)
+
 add_executable(test_context test_context.c)
 target_link_libraries(test_context gost_engine gost_core ${OPENSSL_CRYPTO_LIBRARY})
 add_test(NAME context
index 0a7557d239838bc19a15a868f203253a8314e146..799672bebf89fae5a8cfe07730e215637256490d 100644 (file)
@@ -130,5 +130,41 @@ R3410_ec_params R3410_2012_512_paramset[] = {
      "DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD",
      "1"}
     ,
+    {NID_id_tc26_gost_3410_2012_256_paramSetA,
+     /* a */
+     "C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335",
+     /* b */
+     "295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513",
+     /* p */
+     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
+     /* m */
+     "01000000000000000000000000000000003F63377F21ED98D70456BD55B0D8319C",
+     /* x */
+     "91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28",
+     /* y */
+     "32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C",
+     "4"}
+    ,
+    {NID_id_tc26_gost_3410_2012_512_paramSetC,
+     /* a */
+     "DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E1430645"
+     "46E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3",
+     /* b */
+     "B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE0"
+     "38CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1",
+     /* p */
+     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7",
+     /* m */
+     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+     "26336E91941AAC0130CEA7FD451D40B323B6A79E9DA6849A5188F3BD1FC08FB4",
+     /* x */
+     "E2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043A"
+     "A27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148",
+     /* y */
+     "F5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9B"
+     "E18E2D33E3021ED2EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F",
+     "4"}
+    ,
     {NID_undef, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
 };
diff --git a/test_curves.c b/test_curves.c
new file mode 100644 (file)
index 0000000..7f36c75
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2018 vt@altlinux.org. All Rights Reserved.
+ *
+ * Contents licensed under the terms of the OpenSSL license
+ * See https://www.openssl.org/source/license.html for details
+ */
+
+#include "e_gost_err.h"
+#include "gost_lcl.h"
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+#include <openssl/obj_mac.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+#include <string.h>
+
+#define T(e) ({ if (!(e)) { \
+               ERR_print_errors_fp(stderr); \
+               OpenSSLDie(__FILE__, __LINE__, #e); \
+           } \
+        })
+
+#define cRED   "\033[1;31m"
+#define cDRED  "\033[0;31m"
+#define cGREEN "\033[1;32m"
+#define cDGREEN        "\033[0;32m"
+#define cBLUE  "\033[1;34m"
+#define cDBLUE "\033[0;34m"
+#define cNORM  "\033[m"
+#define TEST_ASSERT(e) {if ((test = (e))) \
+                printf(cRED "  Test FAILED\n" cNORM); \
+            else \
+                printf(cGREEN "  Test passed\n" cNORM);}
+
+struct test_curve {
+    int nid;
+    const char *name;
+    int listed;
+};
+
+static struct test_curve test_curves[] = {
+#if 2001
+    { NID_id_GostR3410_2001_TestParamSet, },
+    { NID_id_GostR3410_2001_CryptoPro_A_ParamSet },
+    { NID_id_GostR3410_2001_CryptoPro_B_ParamSet },
+    { NID_id_GostR3410_2001_CryptoPro_C_ParamSet },
+    { NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
+    { NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
+#endif
+    {
+       NID_id_tc26_gost_3410_2012_512_paramSetA,
+       "id-tc26-gost-3410-2012-512-paramSetA",
+    },
+    {
+       NID_id_tc26_gost_3410_2012_512_paramSetB,
+       "id-tc26-gost-3410-2012-512-paramSetB",
+    },
+    {
+       NID_id_tc26_gost_3410_2012_512_paramSetC,
+       "id-tc26-gost-3410-2012-512-paramSetC",
+    },
+    {
+       NID_id_tc26_gost_3410_2012_256_paramSetA,
+       "id-tc26-gost-3410-2012-256-paramSetA",
+    },
+    0,
+};
+
+static struct test_curve *get_test_curve(int nid)
+{
+    int i;
+
+    for (i = 0; test_curves[i].nid; i++)
+       if (test_curves[i].nid == nid)
+           return &test_curves[i];
+    return NULL;
+}
+
+static void print_bn(const char *name, const BIGNUM *n)
+{
+    printf("%3s = ", name);
+    BN_print_fp(stdout, n);
+    printf("\n");
+}
+
+// https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
+static int parameter_test(struct test_curve *tc)
+{
+    const int nid = tc->nid;
+    int test;
+
+    printf(cBLUE "Test curve NID %d" cNORM, nid);
+    if (tc->name)
+       printf(cBLUE ": %s" cNORM, tc->name);
+    else if (OBJ_nid2sn(nid))
+       printf(cBLUE ": %s" cNORM, OBJ_nid2sn(nid));
+    printf("\n");
+
+    if (!OBJ_nid2obj(nid)) {
+       printf(cRED "NID %d not found\n" cNORM, nid);
+       return 1;
+    }
+
+    /* nid resolves in both directions */
+    const char *sn, *ln;
+    T(sn = OBJ_nid2sn(nid));
+    T(ln = OBJ_nid2ln(nid));
+    if (tc->name)
+       T(!strcmp(tc->name, OBJ_nid2sn(nid)));
+    T(nid == OBJ_sn2nid(sn));
+    T(nid == OBJ_ln2nid(ln));
+
+    EC_KEY *ec;
+    T(ec = EC_KEY_new());
+    if (!fill_GOST_EC_params(ec, nid)) {
+       printf(cRED "fill_GOST_EC_params FAIL\n" cNORM);
+       ERR_print_errors_fp(stderr);
+       return 1;
+    }
+
+    const EC_GROUP *group;
+    T(group = EC_KEY_get0_group(ec));
+
+    BN_CTX *ctx;
+    T(ctx = BN_CTX_new());
+    BIGNUM *p, *a, *b;
+    T(p = BN_new());
+    T(a = BN_new());
+    T(b = BN_new());
+    EC_GROUP_get_curve_GFp(group, p, a, b, ctx);
+    print_bn("p", p);
+    print_bn("a", a);
+    print_bn("b", b);
+    T(!BN_is_zero(p));
+    T(BN_is_odd(p)); /* Should be odd for F_p */
+    T(!BN_is_zero(a));
+    T(!BN_is_zero(b));
+
+    /* Check generator */
+    const EC_POINT *generator;
+    T(generator = EC_GROUP_get0_generator(group));
+    BIGNUM *x, *y;
+    T(x = BN_new());
+    T(y = BN_new());
+    T(EC_POINT_get_affine_coordinates_GFp(group, generator, x, y, ctx));
+    print_bn("x", x);
+    print_bn("y", y);
+    T(!BN_is_zero(y));
+
+    /* Generator is not identity element 0 */
+    T(EC_POINT_is_at_infinity(group, generator) == 0);
+
+    /* x and y is in range [1 .. p-1] */
+    T(!BN_is_negative(x));
+    T(!BN_is_negative(y));
+    T(BN_cmp(x, p) < 0);
+    T(BN_cmp(y, p) < 0);
+
+    /* Generator should be on curve */
+    T(EC_POINT_is_on_curve(group, generator, ctx) == 1);
+
+    /* y^2 == (x^3 + ax + b) mod p
+     * Should be same as EC_POINT_is_on_curve(generator),
+     * but, let's calculate it manually. */
+    BIGNUM *yy  = BN_new();
+    BIGNUM *r   = BN_new();
+    BIGNUM *xxx = BN_new();
+    BIGNUM *ax  = BN_new();
+    T(yy && r && xxx && ax);
+    BN_set_word(r, 2);
+    BN_mod_exp(yy, y, r, p, ctx);
+    BN_set_word(r, 3);
+    BN_mod_exp(xxx, x, r, p, ctx);
+    BN_mod_mul(ax, a, x, p, ctx);
+    BN_mod_add(xxx, xxx, ax, p, ctx);
+    BN_mod_add(xxx, xxx, b, p, ctx);
+    T(BN_cmp(yy, xxx) == 0);
+
+    /* Check order */
+    const BIGNUM *order;
+    T(order = EC_GROUP_get0_order(group));
+    T(!BN_is_zero(order));
+    print_bn("m", order);
+    T(!BN_is_zero(order));
+    EC_POINT *point;
+    T((point = EC_POINT_new(group)));
+    T(EC_POINT_mul(group, point, NULL, generator, order, ctx));
+    /* generator * order is the point at infinity? */
+    T(EC_POINT_is_at_infinity(group, point) == 1);
+
+    /* Check if order is cyclic */
+    BIGNUM *k1 = BN_new();
+    BIGNUM *k2 = BN_new();
+    EC_POINT *p1 = EC_POINT_new(group);
+    EC_POINT *p2 = EC_POINT_new(group);
+    BN_set_word(k1, 3);
+    BN_set_word(k2, 3);
+    BN_add(k2, k2, order);
+    T(EC_POINT_mul(group, p1, NULL, generator, k1, ctx));
+    T(EC_POINT_mul(group, p2, NULL, generator, k2, ctx));
+
+    /* Cofactor is 1 or 4 */
+    const BIGNUM *c;
+    T(c = EC_GROUP_get0_cofactor(group));
+    if (BN_is_odd(order))
+       T(BN_is_word(c, 1));
+    else
+       T(BN_is_word(c, 4));
+
+    TEST_ASSERT(0);
+    return test;
+}
+
+int main(int argc, char **argv)
+{
+    int ret = 0;
+
+    struct test_curve *tc;
+    for (tc = test_curves; tc->nid; tc++) {
+       ret |= parameter_test(tc);
+    }
+
+    if (ret)
+       printf(cDRED "= Some tests FAILED!\n" cNORM);
+    else
+       printf(cDGREEN "= All tests passed!\n" cNORM);
+    return ret;
+}