You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

curve25519.c 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "config.h"
  17. #include "cryptobox.h"
  18. #include "curve25519.h"
  19. #include "platform_config.h"
  20. extern unsigned long cpu_config;
  21. typedef struct curve25519_impl_s {
  22. unsigned long cpu_flags;
  23. const char *desc;
  24. void (*scalarmult) (guint8 *mypublic,
  25. const guint8 *secret,
  26. const guint8 *basepoint);
  27. void (*scalarmult_base) (guint8 *mypublic,
  28. const guint8 *secret);
  29. } curve25519_impl_t;
  30. #define CURVE25519_DECLARE(ext) \
  31. void scalarmult_##ext(guint8 *mypublic, const guint8 *secret, const guint8 *basepoint); \
  32. void scalarmult_base_##ext(guint8 *mypublic, const guint8 *secret)
  33. #define CURVE25519_IMPL(cpuflags, desc, ext) \
  34. {(cpuflags), desc, scalarmult_##ext, scalarmult_base_##ext}
  35. #if defined(__LP64__)
  36. #if defined(HAVE_AVX)
  37. CURVE25519_DECLARE(avx);
  38. #define CURVE25519_AVX CURVE25519_IMPL(CPUID_AVX, "avx", avx)
  39. #endif
  40. #endif
  41. CURVE25519_DECLARE(ref);
  42. #define CURVE25519_REF CURVE25519_IMPL(0, "ref", ref)
  43. #if defined(CMAKE_ARCH_x86_64) || defined(CMAKE_ARCH_i386)
  44. CURVE25519_DECLARE(donna);
  45. #define CURVE25519_GENERIC CURVE25519_IMPL(0, "donna", donna)
  46. #else
  47. #define CURVE25519_GENERIC CURVE25519_REF
  48. #endif
  49. static const curve25519_impl_t curve25519_list[] = {
  50. CURVE25519_GENERIC,
  51. #if defined(CURVE25519_AVX)
  52. CURVE25519_AVX,
  53. #endif
  54. };
  55. const guchar secA[] = {0x5A, 0xC9, 0x9F, 0x33, 0x63, 0x2E, 0x5A, 0x76, 0x8D,
  56. 0xE7, 0xE8, 0x1B, 0xF8, 0x54, 0xC2, 0x7C, 0x46, 0xE3,
  57. 0xFB, 0xF2, 0xAB, 0xBA, 0xCD, 0x29, 0xEC, 0x4A, 0xFF,
  58. 0x51, 0x73, 0x69, 0xC6, 0x60};
  59. const guchar secB[] = {0x47, 0xDC, 0x3D, 0x21, 0x41, 0x74, 0x82, 0x0E, 0x11,
  60. 0x54, 0xB4, 0x9B, 0xC6, 0xCD, 0xB2, 0xAB, 0xD4, 0x5E,
  61. 0xE9, 0x58, 0x17, 0x05, 0x5D, 0x25, 0x5A, 0xA3, 0x58,
  62. 0x31, 0xB7, 0x0D, 0x32, 0x60};
  63. static const curve25519_impl_t *curve25519_opt = &curve25519_list[0];
  64. static gboolean
  65. curve25519_test_impl (const curve25519_impl_t *impl)
  66. {
  67. guchar sec_local[32], sec_ref[32],
  68. pubA[32], pubB[32];
  69. curve25519_impl_t ref_impl = CURVE25519_REF;
  70. ref_impl.scalarmult (pubA, secA, curve25519_basepoint);
  71. ref_impl.scalarmult (pubB, secB, curve25519_basepoint);
  72. impl->scalarmult (sec_local, secA, pubB);
  73. ref_impl.scalarmult (sec_ref, secA, pubB);
  74. if (memcmp (sec_local, sec_ref, sizeof (sec_ref)) != 0) {
  75. return FALSE;
  76. }
  77. impl->scalarmult (sec_local, secB, pubA);
  78. ref_impl.scalarmult (sec_ref, secB, pubA);
  79. if (memcmp (sec_local, sec_ref, sizeof (sec_ref)) != 0) {
  80. return FALSE;
  81. }
  82. impl->scalarmult (sec_local, secB, pubA);
  83. impl->scalarmult (sec_ref, secA, pubB);
  84. if (memcmp (sec_local, sec_ref, sizeof (sec_ref)) != 0) {
  85. return FALSE;
  86. }
  87. return TRUE;
  88. }
  89. const char*
  90. curve25519_load (void)
  91. {
  92. guint i;
  93. if (cpu_config != 0) {
  94. for (i = 0; i < G_N_ELEMENTS(curve25519_list); i++) {
  95. if (curve25519_list[i].cpu_flags & cpu_config) {
  96. curve25519_opt = &curve25519_list[i];
  97. break;
  98. }
  99. }
  100. }
  101. g_assert (curve25519_test_impl (curve25519_opt));
  102. return curve25519_opt->desc;
  103. }
  104. int
  105. curve25519 (guchar *mypublic,
  106. const guchar *secret,
  107. const guchar *basepoint)
  108. {
  109. curve25519_opt->scalarmult (mypublic, secret, basepoint);
  110. return 0;
  111. }
  112. int
  113. curve25519_base (guchar *mypublic, const guchar *secret)
  114. {
  115. curve25519_opt->scalarmult_base (mypublic, secret);
  116. return 0;
  117. }