1
0

Sign.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "crypto/Sign.h"
  16. #include "crypto/sign/crypto_sign_ed25519.h"
  17. #include "crypto/sign/ge.h"
  18. #include "crypto/sign/sc.h"
  19. Linker_require("crypto/sign/fe_0.c")
  20. Linker_require("crypto/sign/fe_1.c")
  21. Linker_require("crypto/sign/fe_add.c")
  22. Linker_require("crypto/sign/fe_cmov.c")
  23. Linker_require("crypto/sign/fe_copy.c")
  24. Linker_require("crypto/sign/fe_frombytes.c")
  25. Linker_require("crypto/sign/fe_invert.c")
  26. Linker_require("crypto/sign/fe_isnegative.c")
  27. Linker_require("crypto/sign/fe_isnonzero.c")
  28. Linker_require("crypto/sign/fe_mul.c")
  29. Linker_require("crypto/sign/fe_neg.c")
  30. Linker_require("crypto/sign/fe_pow22523.c")
  31. Linker_require("crypto/sign/fe_sq.c")
  32. Linker_require("crypto/sign/fe_sq2.c")
  33. Linker_require("crypto/sign/fe_sub.c")
  34. Linker_require("crypto/sign/fe_tobytes.c")
  35. Linker_require("crypto/sign/ge_add.c")
  36. Linker_require("crypto/sign/ge_double_scalarmult.c")
  37. Linker_require("crypto/sign/ge_frombytes.c")
  38. Linker_require("crypto/sign/ge_madd.c")
  39. Linker_require("crypto/sign/ge_msub.c")
  40. Linker_require("crypto/sign/ge_p1p1_to_p2.c")
  41. Linker_require("crypto/sign/ge_p1p1_to_p3.c")
  42. Linker_require("crypto/sign/ge_p2_0.c")
  43. Linker_require("crypto/sign/ge_p2_dbl.c")
  44. Linker_require("crypto/sign/ge_p3_0.c")
  45. Linker_require("crypto/sign/ge_p3_dbl.c")
  46. Linker_require("crypto/sign/ge_p3_to_cached.c")
  47. Linker_require("crypto/sign/ge_p3_to_p2.c")
  48. Linker_require("crypto/sign/ge_p3_tobytes.c")
  49. Linker_require("crypto/sign/ge_precomp_0.c")
  50. Linker_require("crypto/sign/ge_scalarmult_base.c")
  51. Linker_require("crypto/sign/ge_sub.c")
  52. Linker_require("crypto/sign/ge_tobytes.c")
  53. Linker_require("crypto/sign/sc_muladd.c")
  54. Linker_require("crypto/sign/sc_reduce.c")
  55. Linker_require("crypto/sign/open.c")
  56. #include <sodium/crypto_hash_sha512.h>
  57. // This is fairly streight forward, we're taking a curve25519 private key and
  58. // interpreting it as an ed25519 key. This works in conjunction with the public
  59. // key converter Sign_publicSigningKeyToCurve25519() which is able to re-derive
  60. // the encryption key from a public signing key.
  61. void Sign_signingKeyPairFromCurve25519(uint8_t keypairOut[64], uint8_t secretCryptoKey[32])
  62. {
  63. Bits_memcpy(keypairOut, secretCryptoKey, 32);
  64. // The lower 3 bits are always cleared in both curve25519 and ed25519 keys before use
  65. // see: https://crypto.stackexchange.com/a/12614
  66. keypairOut[0] &= 248;
  67. // You will notice that ed25519 uses &= 63 (setting bit number 354 to zero) while
  68. // curve25519 scalarmult uses &= 127, allowing bit number 254 to be potentially 1,
  69. // this might look as though the keys are different but since the next line flags bit
  70. // number 254 always to 1, there is no difference here between the way curve25519
  71. // implementations and ed25519 implementations work.
  72. keypairOut[31] &= 63;
  73. // Bit number 254 is always set in both curve25519 and ed25519 keys before use
  74. // see: https://crypto.stackexchange.com/a/11818
  75. keypairOut[31] |= 64;
  76. // This is just doing the same thing as vanilla ed25519 crypto_sign_keypair()
  77. // computation with the exception that we don't hash the private key before
  78. // computation.
  79. ge_p3 A;
  80. ge_scalarmult_base(&A, keypairOut);
  81. ge_p3_tobytes(&keypairOut[32], &A);
  82. }
  83. void Sign_publicKeyFromKeyPair(uint8_t publicSigningKey[32], uint8_t keyPair[64])
  84. {
  85. Bits_memcpy(publicSigningKey, &keyPair[32], 32);
  86. }
  87. // This function is here because cjdns traditionally did not include signing, it only
  88. // has a key for encryption so when signing was implemented, in order not to break
  89. // everyone who has a cjdroute.conf file already, we needed to be able to convert
  90. // the encryption key to a signing key.
  91. // That in itself is fairly easy, and considered to be safe, but unfortunately nacl
  92. // and libsodium ed25519 implementations hash the private key before each use, making
  93. // it impossible to use our private key derived from a curve25519 encryption private key.
  94. //
  95. // The reason why nacl hashes the private key is to expand 32 bytes of entropy into 64
  96. // bytes, half of which is used as the actual signing key and half of which is used as
  97. // a secret random value which when combined with the hash of the message creates a
  98. // value r that is unpredictable and different for each message signed. It's important
  99. // to note that if r is the same for two different messages then there is a way for an
  100. // attacker to mathmatically derive the private key.
  101. //
  102. // What we do here instead is take the hash of the actual private key used to sign with
  103. // plus some random "belt and suspenders" bytes. Generally speaking, we should consider
  104. // that there is no more dissernable relationship between the public key and the sha512
  105. // of the private key than there is between the public key and the second half of the
  106. // same sha512 which produces the private key, but this is walking off of the beaten path
  107. // and throwing in a little bit of random each message should not make the situation any
  108. // worse.
  109. void Sign_signMsg(uint8_t keyPair[64], struct Message* msg, struct Random* rand)
  110. {
  111. // az is set to the secret key followed by another secret value
  112. // which since we don't have a secret seed in this algorithm is just the
  113. // hash of the secret key and 32 bytes of random
  114. uint8_t az[64];
  115. uint8_t r[64];
  116. ge_p3 R;
  117. uint8_t hram[64];
  118. // First we need to derive a unique random value, we'll do this by hashing the secret
  119. // key plus 32 bytes of random, whereas crypto_sign() achieves this by taking half of
  120. // the hash of the secret key that is input to it.
  121. Bits_memcpy(az, keyPair, 32);
  122. Random_bytes(rand, &az[32], 32);
  123. crypto_hash_sha512(az,az,64);
  124. // Ok, now az contains 64 bytes of unique random value, the upper 32 bytes needs to
  125. // be set to the actual secret key that we're going to use for signing.
  126. Bits_memcpy(az, keyPair, 32);
  127. // The reason for these numbers being masked off is explained above, but this is no
  128. // different from crypto_sign()
  129. az[0] &= 248;
  130. az[31] &= 63;
  131. az[31] |= 64;
  132. // hash message + secret number, this is the same as crypto_sign()
  133. // If there isn't enough space in the message, we abort the process
  134. Er_assert(Message_epush(msg, &az[32], 32));
  135. crypto_hash_sha512(r, msg->msgbytes, Message_getLength(msg));
  136. // Replace secret number with public key, this is the same as crypto_sign()
  137. Bits_memcpy(msg->msgbytes, &keyPair[32], 32);
  138. // Now we scalar multiply the hash of the message + unique secret and push that
  139. // to the message, nothing different from crypto_sign()
  140. sc_reduce(r);
  141. ge_scalarmult_base(&R,r);
  142. // If there isn't enough space in the message, we abort the process
  143. Er_assert(Message_eshift(msg, 32));
  144. ge_p3_tobytes(msg->msgbytes,&R);
  145. // This final step is the same as crypto_sign()
  146. // Overwrite the public key which the verifier will replace in order to recompute
  147. // the hash.
  148. crypto_hash_sha512(hram, msg->msgbytes, Message_getLength(msg));
  149. sc_reduce(hram);
  150. sc_muladd(&msg->msgbytes[32], hram, az, r);
  151. }
  152. // For verify, we're just using the normal sign_open() function, nothing special here.
  153. int Sign_verifyMsg(uint8_t publicSigningKey[32], struct Message* msg)
  154. {
  155. if (Message_getLength(msg) < 64) { return -1; }
  156. struct Allocator* alloc = Allocator_child(Message_getAlloc(msg));
  157. uint8_t* buff = Allocator_malloc(alloc, Message_getLength(msg));
  158. unsigned long long ml = Message_getLength(msg);
  159. int ret = crypto_sign_ed25519_open(buff, &ml, msg->msgbytes, Message_getLength(msg), publicSigningKey);
  160. Allocator_free(alloc);
  161. if (ret) {
  162. return -1;
  163. }
  164. Er_assert(Message_epop(msg, NULL, 64));
  165. return 0;
  166. }
  167. // This is a copy of libsodium's implementation:
  168. // https://github.com/jedisct1/libsodium/blob/eae4add8de435a7fad08eab4f6e7cbfa9209a692/
  169. // src/libsodium/crypto_sign/ed25519/ref10/keypair.c#L45
  170. // Note that in newer versions Libsodium added a checks
  171. // * ge25519_has_small_order - refusing signatures made with weak public keys
  172. // * ge25519_is_on_main_subgroup - refusing signatures from keys on different subgroups
  173. // These additions are specific to Libsodium, they not in the original NACL ed25519
  174. // implementation, nor in tweetnacl.
  175. int Sign_publicSigningKeyToCurve25519(uint8_t curve25519keyOut[32], uint8_t publicSigningKey[32])
  176. {
  177. ge_p3 A;
  178. fe x;
  179. fe one_minus_y;
  180. if (ge_frombytes_negate_vartime(&A, publicSigningKey) != 0) {
  181. return -1;
  182. }
  183. fe_1(one_minus_y);
  184. fe_sub(one_minus_y, one_minus_y, A.Y);
  185. fe_invert(one_minus_y, one_minus_y);
  186. fe_1(x);
  187. fe_add(x, x, A.Y);
  188. fe_mul(x, x, one_minus_y);
  189. fe_tobytes(curve25519keyOut, x);
  190. return 0;
  191. }