blinding.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* Added to ref10 for Tor. We place this in the public domain. Alternatively,
  2. * you may have it under the Creative Commons 0 "CC0" license. */
  3. //#include "fe.h"
  4. #include "ge.h"
  5. #include "sc.h"
  6. #include "crypto_hash_sha512.h"
  7. #include "ed25519_ref10.h"
  8. #include <string.h>
  9. #include "crypto.h"
  10. static void
  11. ed25519_ref10_gettweak(unsigned char *out, const unsigned char *param)
  12. {
  13. const char str[] = "Derive temporary signing key";
  14. crypto_hash_sha512_2(out, (const unsigned char*)str, strlen(str), param, 32);
  15. out[0] &= 248; /* Is this necessary necessary ? */
  16. out[31] &= 63;
  17. out[31] |= 64;
  18. }
  19. int ed25519_ref10_blind_secret_key(unsigned char *out,
  20. const unsigned char *inp,
  21. const unsigned char *param)
  22. {
  23. const char str[] = "Derive temporary signing key hash input";
  24. unsigned char tweak[64];
  25. unsigned char zero[32];
  26. ed25519_ref10_gettweak(tweak, param);
  27. memset(zero, 0, 32);
  28. sc_muladd(out, inp, tweak, zero);
  29. crypto_hash_sha512_2(tweak, (const unsigned char *)str, strlen(str),
  30. inp+32, 32);
  31. memcpy(out+32, tweak, 32);
  32. memwipe(tweak, 0, sizeof(tweak));
  33. return 0;
  34. }
  35. int ed25519_ref10_blind_public_key(unsigned char *out,
  36. const unsigned char *inp,
  37. const unsigned char *param)
  38. {
  39. unsigned char tweak[64];
  40. unsigned char zero[32];
  41. unsigned char pkcopy[32];
  42. ge_p3 A;
  43. ge_p2 Aprime;
  44. ed25519_ref10_gettweak(tweak, param);
  45. memset(zero, 0, sizeof(zero));
  46. /* Not the greatest implementation of all of this. I wish I had
  47. * better-suited primitives to work with here... (but I don't wish that so
  48. * strongly that I'm about to code my own ge_scalarmult_vartime). */
  49. /* We negate the public key first, so that we can pass it to
  50. * frombytes_negate_vartime, which negates it again. If there were a
  51. * "ge_frombytes", we'd use that, but there isn't. */
  52. memcpy(pkcopy, inp, 32);
  53. pkcopy[31] ^= (1<<7);
  54. ge_frombytes_negate_vartime(&A, pkcopy);
  55. /* There isn't a regular ge_scalarmult -- we have to do tweak*A + zero*B. */
  56. ge_double_scalarmult_vartime(&Aprime, tweak, &A, zero);
  57. ge_tobytes(out, &Aprime);
  58. memwipe(tweak, 0, sizeof(tweak));
  59. memwipe(&A, 0, sizeof(A));
  60. memwipe(&Aprime, 0, sizeof(Aprime));
  61. memwipe(pkcopy, 0, sizeof(pkcopy));
  62. return 0;
  63. }
  64. /* This is the group order encoded in a format that
  65. * ge_double_scalarmult_vartime() understands. The group order m is:
  66. * m = 2^252 + 27742317777372353535851937790883648493 =
  67. * 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
  68. */
  69. static const uint8_t modm_m[32] = {0xed,0xd3,0xf5,0x5c,0x1a,0x63,0x12,0x58,
  70. 0xd6,0x9c,0xf7,0xa2,0xde,0xf9,0xde,0x14,
  71. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  72. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10};
  73. /* Do the scalar multiplication of <b>pubkey</b> with the group order
  74. * <b>modm_m</b>. Place the result in <b>out</b> which must be at least 32
  75. * bytes long. */
  76. int
  77. ed25519_ref10_scalarmult_with_group_order(unsigned char *out,
  78. const unsigned char *pubkey)
  79. {
  80. unsigned char pkcopy[32];
  81. unsigned char zero[32] = {0};
  82. ge_p3 Point;
  83. ge_p2 Result;
  84. /* All this is done to fit 'pubkey' in 'Point' so that it can be used by
  85. * ed25519 ref code. Same thing as in blinding function */
  86. memcpy(pkcopy, pubkey, 32);
  87. pkcopy[31] ^= (1<<7);
  88. if (ge_frombytes_negate_vartime(&Point, pkcopy) != 0) {
  89. return -1; /* error: bail out */
  90. }
  91. /* There isn't a regular scalarmult -- we have to do r = l*P + 0*B */
  92. ge_double_scalarmult_vartime(&Result, modm_m, &Point, zero);
  93. ge_tobytes(out, &Result);
  94. return 0;
  95. }