blinding.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. memcpy(out, param, 32);
  14. out[0] &= 248; /* Is this necessary necessary ? */
  15. out[31] &= 63;
  16. out[31] |= 64;
  17. }
  18. int ed25519_ref10_blind_secret_key(unsigned char *out,
  19. const unsigned char *inp,
  20. const unsigned char *param)
  21. {
  22. const char str[] = "Derive temporary signing key hash input";
  23. unsigned char tweak[64];
  24. unsigned char zero[32];
  25. ed25519_ref10_gettweak(tweak, param);
  26. memset(zero, 0, 32);
  27. sc_muladd(out, inp, tweak, zero);
  28. crypto_hash_sha512_2(tweak, (const unsigned char *)str, strlen(str),
  29. inp+32, 32);
  30. memcpy(out+32, tweak, 32);
  31. memwipe(tweak, 0, sizeof(tweak));
  32. return 0;
  33. }
  34. int ed25519_ref10_blind_public_key(unsigned char *out,
  35. const unsigned char *inp,
  36. const unsigned char *param)
  37. {
  38. unsigned char tweak[64];
  39. unsigned char zero[32];
  40. unsigned char pkcopy[32];
  41. ge_p3 A;
  42. ge_p2 Aprime;
  43. int retval = -1;
  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. if (ge_frombytes_negate_vartime(&A, pkcopy) != 0) {
  55. goto done;
  56. }
  57. /* There isn't a regular ge_scalarmult -- we have to do tweak*A + zero*B. */
  58. ge_double_scalarmult_vartime(&Aprime, tweak, &A, zero);
  59. ge_tobytes(out, &Aprime);
  60. retval = 0;
  61. done:
  62. memwipe(tweak, 0, sizeof(tweak));
  63. memwipe(&A, 0, sizeof(A));
  64. memwipe(&Aprime, 0, sizeof(Aprime));
  65. memwipe(pkcopy, 0, sizeof(pkcopy));
  66. return retval;
  67. }
  68. /* This is the group order encoded in a format that
  69. * ge_double_scalarmult_vartime() understands. The group order m is:
  70. * m = 2^252 + 27742317777372353535851937790883648493 =
  71. * 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
  72. */
  73. static const uint8_t modm_m[32] = {0xed,0xd3,0xf5,0x5c,0x1a,0x63,0x12,0x58,
  74. 0xd6,0x9c,0xf7,0xa2,0xde,0xf9,0xde,0x14,
  75. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  76. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10};
  77. /* Do the scalar multiplication of <b>pubkey</b> with the group order
  78. * <b>modm_m</b>. Place the result in <b>out</b> which must be at least 32
  79. * bytes long. */
  80. int
  81. ed25519_ref10_scalarmult_with_group_order(unsigned char *out,
  82. const unsigned char *pubkey)
  83. {
  84. unsigned char pkcopy[32];
  85. unsigned char zero[32] = {0};
  86. ge_p3 Point;
  87. ge_p2 Result;
  88. /* All this is done to fit 'pubkey' in 'Point' so that it can be used by
  89. * ed25519 ref code. Same thing as in blinding function */
  90. memcpy(pkcopy, pubkey, 32);
  91. pkcopy[31] ^= (1<<7);
  92. if (ge_frombytes_negate_vartime(&Point, pkcopy) != 0) {
  93. return -1; /* error: bail out */
  94. }
  95. /* There isn't a regular scalarmult -- we have to do r = l*P + 0*B */
  96. ge_double_scalarmult_vartime(&Result, modm_m, &Point, zero);
  97. ge_tobytes(out, &Result);
  98. return 0;
  99. }