ntru.c 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097
  1. /*
  2. * Implementation of OpenSSH 9.x's hybrid key exchange protocol
  3. * [email protected] .
  4. *
  5. * This consists of the 'Streamlined NTRU Prime' quantum-resistant
  6. * cryptosystem, run in parallel with ordinary Curve25519 to generate
  7. * a shared secret combining the output of both systems.
  8. *
  9. * (Hence, even if you don't trust this newfangled NTRU Prime thing at
  10. * all, it's at least no _less_ secure than the kex you were using
  11. * already.)
  12. *
  13. * References for the NTRU Prime cryptosystem, up to and including
  14. * binary encodings of public and private keys and the exact preimages
  15. * of the hashes used in key exchange:
  16. *
  17. * https://ntruprime.cr.yp.to/
  18. * https://ntruprime.cr.yp.to/nist/ntruprime-20201007.pdf
  19. *
  20. * The SSH protocol layer is not documented anywhere I could find (as
  21. * of 2022-04-15, not even in OpenSSH's PROTOCOL.* files). I had to
  22. * read OpenSSH's source code to find out how it worked, and the
  23. * answer is as follows:
  24. *
  25. * This hybrid kex method is treated for SSH purposes as a form of
  26. * elliptic-curve Diffie-Hellman, and shares the same SSH message
  27. * sequence: client sends SSH2_MSG_KEX_ECDH_INIT containing its public
  28. * half, server responds with SSH2_MSG_KEX_ECDH_REPLY containing _its_
  29. * public half plus the host key and signature on the shared secret.
  30. *
  31. * (This is a bit of a fudge, because unlike actual ECDH, this kex
  32. * method is asymmetric: one side sends a public key, and the other
  33. * side encrypts something with it and sends the ciphertext back. So
  34. * while the normal ECDH implementations can compute the two sides
  35. * independently in parallel, this system reusing the same messages
  36. * has to be serial. But the order of the messages _is_ firmly
  37. * specified in SSH ECDH, so it works anyway.)
  38. *
  39. * For this kex method, SSH2_MSG_KEX_ECDH_INIT still contains a single
  40. * SSH 'string', which consists of the concatenation of a Streamlined
  41. * NTRU Prime public key with the Curve25519 public value. (Both of
  42. * these have fixed length in bytes, so there's no ambiguity in the
  43. * concatenation.)
  44. *
  45. * SSH2_MSG_KEX_ECDH_REPLY is mostly the same as usual. The only
  46. * string in the packet that varies is the second one, which would
  47. * normally contain the server's public elliptic curve point. Instead,
  48. * it now contains the concatenation of
  49. *
  50. * - a Streamlined NTRU Prime ciphertext
  51. * - the 'confirmation hash' specified in ntruprime-20201007.pdf,
  52. * hashing the plaintext of that ciphertext together with the
  53. * public key
  54. * - the Curve25519 public point as usual.
  55. *
  56. * Again, all three of those elements have fixed lengths.
  57. *
  58. * The client decrypts the ciphertext, checks the confirmation hash,
  59. * and if successful, generates the 'session hash' specified in
  60. * ntruprime-20201007.pdf, which is 32 bytes long and is the ultimate
  61. * output of the Streamlined NTRU Prime key exchange.
  62. *
  63. * The output of the hybrid kex method as a whole is an SSH 'string'
  64. * of length 64 containing the SHA-512 hash of the concatenatio of
  65. *
  66. * - the Streamlined NTRU Prime session hash (32 bytes)
  67. * - the Curve25519 shared secret (32 bytes).
  68. *
  69. * That string is included directly into the SSH exchange hash and key
  70. * derivation hashes, in place of the mpint that comes out of most
  71. * other kex methods.
  72. */
  73. #include <stdio.h>
  74. #include <stdlib.h>
  75. #include <assert.h>
  76. #include "putty.h"
  77. #include "ssh.h"
  78. #include "mpint.h"
  79. #include "ntru.h"
  80. /* ----------------------------------------------------------------------
  81. * Preliminaries: we're going to need to do modular arithmetic on
  82. * small values (considerably smaller than 2^16), and we need to do it
  83. * without using integer division which might not be time-safe.
  84. *
  85. * The strategy for this is the same as I used in
  86. * mp_mod_known_integer: see there for the proofs. The basic idea is
  87. * that we precompute the reciprocal of our modulus as a fixed-point
  88. * number, and use that to get an approximate quotient which we
  89. * subtract off. For these integer sizes, precomputing a fixed-point
  90. * reciprocal of the form (2^48 / modulus) leaves us at most off by 1
  91. * in the quotient, so there's a single (time-safe) trial subtraction
  92. * at the end.
  93. *
  94. * (It's possible that some speed could be gained by not reducing
  95. * fully at every step. But then you'd have to carefully identify all
  96. * the places in the algorithm where things are compared to zero. This
  97. * was the easiest way to get it all working in the first place.)
  98. */
  99. /* Precompute the reciprocal */
  100. static uint64_t reciprocal_for_reduction(uint16_t q)
  101. {
  102. return ((uint64_t)1 << 48) / q;
  103. }
  104. /* Reduce x mod q, assuming qrecip == reciprocal_for_reduction(q) */
  105. static uint16_t reduce(uint32_t x, uint16_t q, uint64_t qrecip)
  106. {
  107. uint64_t unshifted_quot = x * qrecip;
  108. uint64_t quot = unshifted_quot >> 48;
  109. uint16_t reduced = x - quot * q;
  110. reduced -= q * (1 & ((q-1 - reduced) >> 15));
  111. return reduced;
  112. }
  113. /* Reduce x mod q as above, but also return the quotient */
  114. static uint16_t reduce_with_quot(uint32_t x, uint32_t *quot_out,
  115. uint16_t q, uint64_t qrecip)
  116. {
  117. uint64_t unshifted_quot = x * qrecip;
  118. uint64_t quot = unshifted_quot >> 48;
  119. uint16_t reduced = x - quot * q;
  120. uint64_t extraquot = (1 & ((q-1 - reduced) >> 15));
  121. reduced -= extraquot * q;
  122. *quot_out = quot + extraquot;
  123. return reduced;
  124. }
  125. /* Invert x mod q, assuming it's nonzero. (For time-safety, no check
  126. * is made for zero; it just returns 0.) */
  127. static uint16_t invert(uint16_t x, uint16_t q, uint64_t qrecip)
  128. {
  129. /* Fermat inversion: compute x^(q-2), since x^(q-1) == 1. */
  130. uint32_t sq = x, bit = 1, acc = 1, exp = q-2;
  131. while (1) {
  132. if (exp & bit) {
  133. acc = reduce(acc * sq, q, qrecip);
  134. exp &= ~bit;
  135. if (!exp)
  136. return acc;
  137. }
  138. sq = reduce(sq * sq, q, qrecip);
  139. bit <<= 1;
  140. }
  141. }
  142. /* Check whether x == 0, time-safely, and return 1 if it is or 0 otherwise. */
  143. static unsigned iszero(uint16_t x)
  144. {
  145. return 1 & ~((x + 0xFFFF) >> 16);
  146. }
  147. /*
  148. * Handy macros to cut down on all those extra function parameters. In
  149. * the common case where a function is working mod the same modulus
  150. * throughout (and has called it q), you can just write 'SETUP;' at
  151. * the top and then call REDUCE(...) and INVERT(...) without having to
  152. * write out q and qrecip every time.
  153. */
  154. #define SETUP uint64_t qrecip = reciprocal_for_reduction(q)
  155. #define REDUCE(x) reduce(x, q, qrecip)
  156. #define INVERT(x) invert(x, q, qrecip)
  157. /* ----------------------------------------------------------------------
  158. * Quotient-ring functions.
  159. *
  160. * NTRU Prime works with two similar but different quotient rings:
  161. *
  162. * Z_q[x] / <x^p-x-1> where p,q are the prime parameters of the system
  163. * Z_3[x] / <x^p-x-1> with the same p, but coefficients mod 3.
  164. *
  165. * The former is a field (every nonzero element is invertible),
  166. * because the system parameters are chosen such that x^p-x-1 is
  167. * invertible over Z_q. The latter is not a field (or not necessarily,
  168. * and in particular, not for the value of p we use here).
  169. *
  170. * In these core functions, you pass in the modulus you want as the
  171. * parameter q, which is either the 'real' q specified in the system
  172. * parameters, or 3 if you're doing one of the mod-3 parts of the
  173. * algorithm.
  174. */
  175. /*
  176. * Multiply two elements of a quotient ring.
  177. *
  178. * 'a' and 'b' are arrays of exactly p coefficients, with constant
  179. * term first. 'out' is an array the same size to write the inverse
  180. * into.
  181. */
  182. void ntru_ring_multiply(uint16_t *out, const uint16_t *a, const uint16_t *b,
  183. unsigned p, unsigned q)
  184. {
  185. SETUP;
  186. /*
  187. * Strategy: just compute the full product with 2p coefficients,
  188. * and then reduce it mod x^p-x-1 by working downwards from the
  189. * top coefficient replacing x^{p+k} with (x+1)x^k for k = ...,1,0.
  190. *
  191. * Possibly some speed could be gained here by doing the recursive
  192. * Karatsuba optimisation for the initial multiplication? But I
  193. * haven't tried it.
  194. */
  195. uint32_t *unreduced = snewn(2*p, uint32_t);
  196. { // WINSCP
  197. unsigned i;
  198. for (i = 0; i < 2*p; i++)
  199. unreduced[i] = 0;
  200. } // WINSCP
  201. { // WINSCP
  202. unsigned i, j;
  203. for (i = 0; i < p; i++)
  204. for (j = 0; j < p; j++)
  205. unreduced[i+j] = REDUCE(unreduced[i+j] + a[i] * b[j]);
  206. } // WINSCP
  207. { // WINSCP
  208. unsigned i;
  209. for (i = 2*p - 1; i >= p; i--) {
  210. unreduced[i-p] += unreduced[i];
  211. unreduced[i-p+1] += unreduced[i];
  212. unreduced[i] = 0;
  213. }
  214. } // WINSCP
  215. { // WINSCP
  216. unsigned i;
  217. for (i = 0; i < p; i++)
  218. out[i] = REDUCE(unreduced[i]);
  219. } // WINSCP
  220. smemclr(unreduced, 2*p * sizeof(*unreduced));
  221. sfree(unreduced);
  222. }
  223. /*
  224. * Invert an element of the quotient ring.
  225. *
  226. * 'in' is an array of exactly p coefficients, with constant term
  227. * first. 'out' is an array the same size to write the inverse into.
  228. *
  229. * Method: essentially Stein's gcd algorithm, taking the gcd of the
  230. * input (regarded as an element of Z_q[x] proper) and x^p-x-1. Given
  231. * two polynomials over a field which are not both divisible by x, you
  232. * can find their gcd by iterating the following procedure:
  233. *
  234. * - if one is divisible by x, divide off x
  235. * - otherwise, subtract from the higher-degree one whatever scalar
  236. * multiple of the lower-degree one will make it divisible by x,
  237. * and _then_ divide off x
  238. *
  239. * Neither of these types of step changes the gcd of the two
  240. * polynomials.
  241. *
  242. * Each step reduces the sum of the two polynomials' degree by at
  243. * least one, as long as at least one of the degrees is positive.
  244. * (Maybe more than one if all the stars align in the second case, if
  245. * the subtraction cancels the leading term as well as the constant
  246. * term.) So in at most deg A + deg B steps, we must have reached the
  247. * situation where both polys are constants; in one more step after
  248. * that, one of them will be zero; and in one step after _that_, the
  249. * zero one will reliably be the one we're dividing by x. Or rather,
  250. * that's what happens in the case where A,B are coprime; if not, then
  251. * one hits zero while the other is still nonzero.
  252. *
  253. * In a normal gcd algorithm, you'd track a linear combination of the
  254. * two original polynomials that yields each working value, and end up
  255. * with a linear combination of the inputs that yields the gcd. In
  256. * this algorithm, the 'divide off x' step makes that awkward - but we
  257. * can solve that by instead multiplying by the inverse of x in the
  258. * ring that we want our answer to be valid in! And since the modulus
  259. * polynomial of the ring is x^p-x-1, the inverse of x is easy to
  260. * calculate, because it's always just x^{p-1} - 1, which is also very
  261. * easy to multiply by.
  262. */
  263. unsigned ntru_ring_invert(uint16_t *out, const uint16_t *in,
  264. unsigned p, unsigned q)
  265. {
  266. SETUP;
  267. /* Size of the polynomial arrays we'll work with */
  268. const size_t SIZE = p+1;
  269. /* Number of steps of the algorithm is the max possible value of
  270. * deg A + deg B + 2, where deg A <= p-1 and deg B = p */
  271. const size_t STEPS = 2*p + 1;
  272. /* Our two working polynomials */
  273. uint16_t *A = snewn(SIZE, uint16_t);
  274. uint16_t *B = snewn(SIZE, uint16_t);
  275. /* Coefficient of the input value in each one */
  276. uint16_t *Ac = snewn(SIZE, uint16_t);
  277. uint16_t *Bc = snewn(SIZE, uint16_t);
  278. /* Initialise A to the input, and Ac correspondingly to 1 */
  279. memcpy(A, in, p*sizeof(uint16_t));
  280. A[p] = 0;
  281. Ac[0] = 1;
  282. { // WINSCP
  283. size_t i;
  284. for (i = 1; i < SIZE; i++)
  285. Ac[i] = 0;
  286. } // WINSCP
  287. /* Initialise B to the quotient polynomial of the ring, x^p-x-1
  288. * And Bc = 0 */
  289. B[0] = B[1] = q-1;
  290. { // WINSCP
  291. size_t i;
  292. for (i = 2; i < p; i++)
  293. B[i] = 0;
  294. } // WINSCP
  295. B[p] = 1;
  296. { // WINSCP
  297. size_t i;
  298. for (i = 0; i < SIZE; i++)
  299. Bc[i] = 0;
  300. } // WINSCP
  301. /* Run the gcd-finding algorithm. */
  302. { // WINSCP
  303. size_t i;
  304. for (i = 0; i < STEPS; i++) {
  305. /*
  306. * First swap round so that A is the one we'll be dividing by x.
  307. *
  308. * In the case where one of the two polys has a zero constant
  309. * term, it's that one. In the other case, it's the one of
  310. * smaller degree. We must compute both, and choose between
  311. * them in a side-channel-safe way.
  312. */
  313. unsigned x_divides_A = iszero(A[0]);
  314. unsigned x_divides_B = iszero(B[0]);
  315. unsigned B_is_bigger = 0;
  316. {
  317. unsigned not_seen_top_term_of_A = 1, not_seen_top_term_of_B = 1;
  318. { // WINSCP
  319. size_t j;
  320. for (j = SIZE; j-- > 0 ;) {
  321. not_seen_top_term_of_A &= iszero(A[j]);
  322. not_seen_top_term_of_B &= iszero(B[j]);
  323. B_is_bigger |= (~not_seen_top_term_of_B &
  324. not_seen_top_term_of_A);
  325. }
  326. } // WINSCP
  327. }
  328. { // WINSCP
  329. unsigned need_swap = x_divides_B | (~x_divides_A & B_is_bigger);
  330. uint16_t swap_mask = (uint64_t)-(int64_t)need_swap; // WINSCP
  331. { // WINSCP
  332. size_t j;
  333. for (j = 0; j < SIZE; j++) {
  334. uint16_t diff = (A[j] ^ B[j]) & swap_mask;
  335. A[j] ^= diff;
  336. B[j] ^= diff;
  337. }
  338. } // WINSCP
  339. { // WINSCP
  340. size_t j;
  341. for (j = 0; j < SIZE; j++) {
  342. uint16_t diff = (Ac[j] ^ Bc[j]) & swap_mask;
  343. Ac[j] ^= diff;
  344. Bc[j] ^= diff;
  345. }
  346. } // WINSCP
  347. /*
  348. * Replace A with a linear combination of both A and B that
  349. * has constant term zero, which we do by calculating
  350. *
  351. * (constant term of B) * A - (constant term of A) * B
  352. *
  353. * In one of the two cases, A's constant term is already zero,
  354. * so the coefficient of B will be zero too; hence, this will
  355. * do nothing useful (it will merely scale A by some scalar
  356. * value), but it will take the same length of time as doing
  357. * something, which is just what we want.
  358. */
  359. { // WINSCP
  360. uint16_t Amult = B[0], Bmult = q - A[0];
  361. { // WINSCP
  362. size_t j; // WINSCP
  363. for (j = 0; j < SIZE; j++)
  364. A[j] = REDUCE(Amult * A[j] + Bmult * B[j]);
  365. } // WINSCP
  366. /* And do the same transformation to Ac */
  367. { // WINSCP
  368. size_t j;
  369. for (j = 0; j < SIZE; j++)
  370. Ac[j] = REDUCE(Amult * Ac[j] + Bmult * Bc[j]);
  371. } // WINSCP
  372. /*
  373. * Now divide A by x, and compensate by multiplying Ac by
  374. * x^{p-1}-1 mod x^p-x-1.
  375. *
  376. * That multiplication is particularly easy, precisely because
  377. * x^{p-1}-1 is the multiplicative inverse of x! Each x^n term
  378. * for n>0 just moves down to the x^{n-1} term, and only the
  379. * constant term has to be dealt with in an interesting way.
  380. */
  381. { // WINSCP
  382. size_t j;
  383. for (j = 1; j < SIZE; j++)
  384. A[j-1] = A[j];
  385. } // WINSCP
  386. A[SIZE-1] = 0;
  387. { // WINSCP
  388. uint16_t Ac0 = Ac[0];
  389. { // WINSCP
  390. size_t j;
  391. for (j = 1; j < p; j++)
  392. Ac[j-1] = Ac[j];
  393. } // WINSCP
  394. Ac[p-1] = Ac0;
  395. Ac[0] = REDUCE(Ac[0] + q - Ac0);
  396. } // WINSCP
  397. } // WINSCP
  398. }
  399. } // WINSCP
  400. /*
  401. * Now we expect that A is 0, and B is a constant. If so, then
  402. * they are coprime, and we're going to return success. If not,
  403. * they have a common factor.
  404. */
  405. { // WINSCP
  406. unsigned success = iszero(A[0]) & (1 ^ iszero(B[0]));
  407. { // WINSCP
  408. size_t j;
  409. for (j = 1; j < SIZE; j++)
  410. success &= iszero(A[j]) & iszero(B[j]);
  411. } // WINSCP
  412. /*
  413. * So we're going to return Bc, but first, scale it by the
  414. * multiplicative inverse of the constant we ended up with in
  415. * B[0].
  416. */
  417. { // WINSCP
  418. uint16_t scale = INVERT(B[0]);
  419. { // WINSCP
  420. size_t i;
  421. for (i = 0; i < p; i++)
  422. out[i] = REDUCE(scale * Bc[i]);
  423. } // WINSCP
  424. smemclr(A, SIZE * sizeof(*A));
  425. sfree(A);
  426. smemclr(B, SIZE * sizeof(*B));
  427. sfree(B);
  428. smemclr(Ac, SIZE * sizeof(*Ac));
  429. sfree(Ac);
  430. smemclr(Bc, SIZE * sizeof(*Bc));
  431. sfree(Bc);
  432. return success;
  433. } // WINSCP
  434. } // WINSCP
  435. } // WINSCP
  436. }
  437. /*
  438. * Given an array of values mod q, convert each one to its
  439. * minimum-absolute-value representative, and then reduce mod 3.
  440. *
  441. * Output values are 0, 1 and 0xFFFF, representing -1.
  442. *
  443. * (Normally our arrays of uint16_t are in 'minimal non-negative
  444. * residue' form, so the output of this function is unusual. But it's
  445. * useful to have it in this form so that it can be reused by
  446. * ntru_round3. You can put it back to the usual representation using
  447. * ntru_normalise, below.)
  448. */
  449. void ntru_mod3(uint16_t *out, const uint16_t *in, unsigned p, unsigned q)
  450. {
  451. uint64_t qrecip = reciprocal_for_reduction(q);
  452. uint64_t recip3 = reciprocal_for_reduction(3);
  453. unsigned bias = q/2;
  454. uint16_t adjust = 3 - reduce(bias-1, 3, recip3);
  455. { // WINSCP
  456. unsigned i;
  457. for (i = 0; i < p; i++) {
  458. uint16_t val = reduce(in[i] + bias, q, qrecip);
  459. uint16_t residue = reduce(val + adjust, 3, recip3);
  460. out[i] = residue - 1;
  461. }
  462. } // WINSCP
  463. }
  464. /*
  465. * Given an array of values mod q, round each one to the nearest
  466. * multiple of 3 to its minimum-absolute-value representative.
  467. *
  468. * Output values are signed integers coerced to uint16_t, so again,
  469. * use ntru_normalise afterwards to put them back to normal.
  470. */
  471. void ntru_round3(uint16_t *out, const uint16_t *in, unsigned p, unsigned q)
  472. {
  473. SETUP;
  474. unsigned bias = q/2;
  475. ntru_mod3(out, in, p, q);
  476. { // WINSCP
  477. unsigned i;
  478. for (i = 0; i < p; i++)
  479. out[i] = REDUCE(in[i] + bias) - bias - out[i];
  480. } // WINSCP
  481. }
  482. /*
  483. * Given an array of signed integers coerced to uint16_t in the range
  484. * [-q/2,+q/2], normalise them back to mod q values.
  485. */
  486. static void ntru_normalise(uint16_t *out, const uint16_t *in,
  487. unsigned p, unsigned q)
  488. {
  489. unsigned i; // WINSCP
  490. for (i = 0; i < p; i++)
  491. out[i] = in[i] + q * (in[i] >> 15);
  492. }
  493. /*
  494. * Given an array of values mod q, add a constant to each one.
  495. */
  496. void ntru_bias(uint16_t *out, const uint16_t *in, unsigned bias,
  497. unsigned p, unsigned q)
  498. {
  499. SETUP;
  500. unsigned i; // WINSCP
  501. for (i = 0; i < p; i++)
  502. out[i] = REDUCE(in[i] + bias);
  503. }
  504. /*
  505. * Given an array of values mod q, multiply each one by a constant.
  506. */
  507. void ntru_scale(uint16_t *out, const uint16_t *in, uint16_t scale,
  508. unsigned p, unsigned q)
  509. {
  510. SETUP;
  511. unsigned i; // WINSCP
  512. for (i = 0; i < p; i++)
  513. out[i] = REDUCE(in[i] * scale);
  514. }
  515. /*
  516. * Given an array of values mod 3, convert them to values mod q in a
  517. * way that maps -1,0,+1 to -1,0,+1.
  518. */
  519. static void ntru_expand(
  520. uint16_t *out, const uint16_t *in, unsigned p, unsigned q)
  521. {
  522. size_t i; // WINSCP
  523. for (i = 0; i < p; i++) {
  524. uint16_t v = in[i];
  525. /* Map 2 to q-1, and leave 0 and 1 unchanged */
  526. v += (v >> 1) * (q-3);
  527. out[i] = v;
  528. }
  529. }
  530. /* ----------------------------------------------------------------------
  531. * Implement the binary encoding from ntruprime-20201007.pdf, which is
  532. * used to encode public keys and ciphertexts (though not plaintexts,
  533. * which are done in a much simpler way).
  534. *
  535. * The general idea is that your encoder takes as input a list of
  536. * small non-negative integers (r_i), and a sequence of limits (m_i)
  537. * such that 0 <= r_i < m_i, and emits a sequence of bytes that encode
  538. * all of these as tightly as reasonably possible.
  539. *
  540. * That's more general than is really needed, because in both the
  541. * actual uses of this encoding, the input m_i are all the same! But
  542. * the array of (r_i,m_i) pairs evolves during encoding, so they don't
  543. * _stay_ all the same, so you still have to have all the generality.
  544. *
  545. * The encoding process makes a number of passes along the list of
  546. * inputs. In each step, pairs of adjacent numbers are combined into
  547. * one larger one by turning (r_i,m_i) and (r_{i+1},m_{i+1}) into the
  548. * pair (r_i + m_i r_{i+1}, m_i m_{i+1}), i.e. so that the original
  549. * numbers could be recovered by taking the quotient and remaiinder of
  550. * the new r value by m_i. Then, if the new m_i is at least 2^14, we
  551. * emit the low 8 bits of r_i to the output stream and reduce r_i and
  552. * its limit correspondingly. So at the end of the pass, we've got
  553. * half as many numbers still to encode, they're all still not too
  554. * big, and we've emitted some amount of data into the output. Then do
  555. * another pass, keep going until there's only one number left, and
  556. * emit it little-endian.
  557. *
  558. * That's all very well, but how do you decode it again? DJB exhibits
  559. * a pair of recursive functions that are supposed to be mutually
  560. * inverse, but I didn't have any confidence that I'd be able to debug
  561. * them sensibly if they turned out not to be (or rather, if I
  562. * implemented one of them wrong). So I came up with my own strategy
  563. * instead.
  564. *
  565. * In my strategy, we start by processing just the (m_i) into an
  566. * 'encoding schedule' consisting of a sequence of simple
  567. * instructions. The instructions operate on a FIFO queue of numbers,
  568. * initialised to the original (r_i). The three instruction types are:
  569. *
  570. * - 'COMBINE': consume two numbers a,b from the head of the queue,
  571. * combine them by calculating a + m*b for some specified m, and
  572. * push the result on the tail of the queue.
  573. *
  574. * - 'BYTE': divide the tail element of the queue by 2^8 and emit the
  575. * low bits into the output stream.
  576. *
  577. * - 'COPY': pop a number from the head of the queue and push it
  578. * straight back on the tail. (Used for handling the leftover
  579. * element at the end of a pass if the input to the pass was a list
  580. * of odd length.)
  581. *
  582. * So we effectively implement DJB's encoding process in simulation,
  583. * and instead of actually processing a set of (r_i), we 'compile' the
  584. * process into a sequence of instructions that can be handed just the
  585. * (r_i) later and encode them in the right way. At the end of the
  586. * instructions, the queue is expected to have been reduced to length
  587. * 1 and contain the single integer 0.
  588. *
  589. * The nice thing about this system is that each of those three
  590. * instructions is easy to reverse. So you can also use the same
  591. * instructions for decoding: start with a queue containing 0, and
  592. * process the instructions in reverse order and reverse sense. So
  593. * BYTE means to _consume_ a byte from the encoded data (starting from
  594. * the rightmost end) and use it to make a queue element bigger; and
  595. * COMBINE run in reverse pops a single element from one end of the
  596. * queue, divides it by m, and pushes the quotient and remainder on
  597. * the other end.
  598. *
  599. * (So it's easy to debug, because the queue passes through the exact
  600. * same sequence of states during decoding that it did during
  601. * encoding, just in reverse order.)
  602. *
  603. * Also, the encoding schedule comes with information about the
  604. * expected size of the encoded data, because you can find that out
  605. * easily by just counting the BYTE commands.
  606. */
  607. enum {
  608. /*
  609. * Command values appearing in the 'ops' array. ENC_COPY and
  610. * ENC_BYTE are single values; values of the form
  611. * (ENC_COMBINE_BASE + m) represent a COMBINE command with
  612. * parameter m.
  613. */
  614. ENC_COPY, ENC_BYTE, ENC_COMBINE_BASE
  615. };
  616. struct NTRUEncodeSchedule {
  617. /*
  618. * Object representing a compiled set of encoding instructions.
  619. *
  620. * 'nvals' is the number of r_i we expect to encode. 'nops' is the
  621. * number of encoding commands in the 'ops' list; 'opsize' is the
  622. * physical size of the array, used during construction.
  623. *
  624. * 'endpos' is used to avoid a last-minute faff during decoding.
  625. * We implement our FIFO of integers as a ring buffer of size
  626. * 'nvals'. Encoding cycles round it some number of times, and the
  627. * final 0 element ends up at some random location in the array.
  628. * If we know _where_ the 0 ends up during encoding, we can put
  629. * the initial 0 there at the start of decoding, and then when we
  630. * finish reversing all the instructions, we'll end up with the
  631. * output numbers already arranged at their correct positions, so
  632. * that there's no need to rotate the array at the last minute.
  633. */
  634. size_t nvals, endpos, nops, opsize;
  635. uint32_t *ops;
  636. };
  637. static inline void sched_append(NTRUEncodeSchedule *sched, uint16_t op)
  638. {
  639. /* Helper function to append an operation to the schedule, and
  640. * update endpos. */
  641. sgrowarray(sched->ops, sched->opsize, sched->nops);
  642. sched->ops[sched->nops++] = op;
  643. if (op != ENC_BYTE)
  644. sched->endpos = (sched->endpos + 1) % sched->nvals;
  645. }
  646. /*
  647. * Take in the list of limit values (m_i) and compute the encoding
  648. * schedule.
  649. */
  650. NTRUEncodeSchedule *ntru_encode_schedule(const uint16_t *ms_in, size_t n)
  651. {
  652. NTRUEncodeSchedule *sched = snew(NTRUEncodeSchedule);
  653. sched->nvals = n;
  654. sched->endpos = n-1;
  655. sched->nops = sched->opsize = 0;
  656. sched->ops = NULL;
  657. assert(n != 0);
  658. /*
  659. * 'ms' is the list of (m_i) on input to the current pass.
  660. * 'ms_new' is the list output from the current pass. After each
  661. * pass we swap the arrays round.
  662. */
  663. { // WINSCP
  664. uint32_t *ms = snewn(n, uint32_t);
  665. uint32_t *msnew = snewn(n, uint32_t);
  666. { // WINSCP
  667. size_t i;
  668. for (i = 0; i < n; i++)
  669. ms[i] = ms_in[i];
  670. } // WINSCP
  671. while (n > 1) {
  672. size_t nnew = 0;
  673. { // WINSCP
  674. size_t i;
  675. for (i = 0; i < n; i += 2) {
  676. if (i+1 == n) {
  677. /*
  678. * Odd element at the end of the input list: just copy
  679. * it unchanged to the output.
  680. */
  681. sched_append(sched, ENC_COPY);
  682. msnew[nnew++] = ms[i];
  683. break;
  684. }
  685. /*
  686. * Normal case: consume two elements from the input list
  687. * and combine them.
  688. */
  689. { // WINSCP
  690. uint32_t m1 = ms[i], m2 = ms[i+1], m = m1*m2;
  691. sched_append(sched, ENC_COMBINE_BASE + m1);
  692. /*
  693. * And then, as long as the combined limit is big enough,
  694. * emit an output byte from the bottom of it.
  695. */
  696. while (m >= (1<<14)) {
  697. sched_append(sched, ENC_BYTE);
  698. m = (m + 0xFF) >> 8;
  699. }
  700. /*
  701. * Whatever is left after that, we emit into the output
  702. * list and append to the fifo.
  703. */
  704. msnew[nnew++] = m;
  705. } // WINSCP
  706. }
  707. } // WINSCP
  708. /*
  709. * End of pass. The output list of (m_i) now becomes the input
  710. * list.
  711. */
  712. { // WINSCP
  713. uint32_t *tmp = ms;
  714. ms = msnew;
  715. n = nnew;
  716. msnew = tmp;
  717. } // WINSCP
  718. }
  719. /*
  720. * When that loop terminates, it's because there's exactly one
  721. * number left to encode. (Or, technically, _at most_ one - but we
  722. * don't support encoding a completely empty list in this
  723. * implementation, because what would be the point?) That number
  724. * is just emitted little-endian until its limit is 1 (meaning its
  725. * only possible actual value is 0).
  726. */
  727. assert(n == 1);
  728. { // WINSCP
  729. uint32_t m = ms[0];
  730. while (m > 1) {
  731. sched_append(sched, ENC_BYTE);
  732. m = (m + 0xFF) >> 8;
  733. }
  734. sfree(ms);
  735. sfree(msnew);
  736. return sched;
  737. } // WINSCP
  738. } // WINSCP
  739. }
  740. void ntru_encode_schedule_free(NTRUEncodeSchedule *sched)
  741. {
  742. sfree(sched->ops);
  743. sfree(sched);
  744. }
  745. /*
  746. * Calculate the output length of the encoded data in bytes.
  747. */
  748. size_t ntru_encode_schedule_length(NTRUEncodeSchedule *sched)
  749. {
  750. size_t len = 0;
  751. { // WINSCP
  752. size_t i;
  753. for (i = 0; i < sched->nops; i++)
  754. if (sched->ops[i] == ENC_BYTE)
  755. len++;
  756. return len;
  757. } // WINSCP
  758. }
  759. /*
  760. * Retrieve the number of items encoded. (Used by testcrypt.)
  761. */
  762. size_t ntru_encode_schedule_nvals(NTRUEncodeSchedule *sched)
  763. {
  764. return sched->nvals;
  765. }
  766. /*
  767. * Actually encode a sequence of (r_i), emitting the output bytes to
  768. * an arbitrary BinarySink.
  769. */
  770. void ntru_encode(NTRUEncodeSchedule *sched, const uint16_t *rs_in,
  771. BinarySink *bs)
  772. {
  773. size_t n = sched->nvals;
  774. uint32_t *rs = snewn(n, uint32_t);
  775. { // WINSCP
  776. size_t i;
  777. for (i = 0; i < n; i++)
  778. rs[i] = rs_in[i];
  779. } // WINSCP
  780. /*
  781. * The head and tail pointers of the queue are both 'full'. That
  782. * is, rs[head] is the first element actually in the queue, and
  783. * rs[tail] is the last element.
  784. *
  785. * So you append to the queue by first advancing 'tail' and then
  786. * writing to rs[tail], whereas you consume from the queue by
  787. * first reading rs[head] and _then_ advancing 'head'.
  788. *
  789. * The more normal thing would be to make 'tail' point to the
  790. * first empty slot instead of the last full one. But then you'd
  791. * have to faff about with modular arithmetic to find the last
  792. * full slot for the BYTE command, so in this case, it's easier to
  793. * do it the less usual way.
  794. */
  795. { // WINSCP
  796. size_t head = 0, tail = n-1;
  797. { // WINSCP
  798. size_t i;
  799. for (i = 0; i < sched->nops; i++) {
  800. uint16_t op = sched->ops[i];
  801. switch (op) {
  802. case ENC_BYTE:
  803. put_byte(bs, rs[tail] & 0xFF);
  804. rs[tail] >>= 8;
  805. break;
  806. case ENC_COPY: {
  807. uint32_t r = rs[head];
  808. head = (head + 1) % n;
  809. tail = (tail + 1) % n;
  810. rs[tail] = r;
  811. break;
  812. }
  813. default: {
  814. uint32_t r1 = rs[head];
  815. head = (head + 1) % n;
  816. { // WINSCP
  817. uint32_t r2 = rs[head];
  818. head = (head + 1) % n;
  819. tail = (tail + 1) % n;
  820. rs[tail] = r1 + (op - ENC_COMBINE_BASE) * r2;
  821. break;
  822. } // WINSCP
  823. }
  824. }
  825. }
  826. } // WINSCP
  827. /*
  828. * Expect that we've ended up with a single zero in the queue, at
  829. * exactly the position that the setup-time analysis predicted it.
  830. */
  831. assert(head == sched->endpos);
  832. assert(tail == sched->endpos);
  833. assert(rs[head] == 0);
  834. smemclr(rs, n * sizeof(*rs));
  835. sfree(rs);
  836. } // WINSCP
  837. }
  838. /*
  839. * Decode a ptrlen of binary data into a sequence of (r_i). The data
  840. * is expected to be of exactly the right length (on pain of assertion
  841. * failure).
  842. */
  843. void ntru_decode(NTRUEncodeSchedule *sched, uint16_t *rs_out, ptrlen data)
  844. {
  845. size_t n = sched->nvals;
  846. const uint8_t *base = (const uint8_t *)data.ptr;
  847. const uint8_t *pos = base + data.len;
  848. /*
  849. * Initialise the queue to a single zero, at the 'endpos' position
  850. * that will mean the final output is correctly aligned.
  851. *
  852. * 'head' and 'tail' have the same meanings as in encoding. So
  853. * 'tail' is the location that BYTE modifies and COPY and COMBINE
  854. * consume from, and 'head' is the location that COPY and COMBINE
  855. * push on to. As in encoding, they both point at the extremal
  856. * full slots in the array.
  857. */
  858. uint32_t *rs = snewn(n, uint32_t);
  859. size_t head = sched->endpos, tail = head;
  860. rs[tail] = 0;
  861. { // WINSCP
  862. size_t i;
  863. for (i = sched->nops; i-- > 0 ;) {
  864. uint16_t op = sched->ops[i];
  865. switch (op) {
  866. case ENC_BYTE: {
  867. assert(pos > base);
  868. { // WINSCP
  869. uint8_t byte = *--pos;
  870. rs[tail] = (rs[tail] << 8) | byte;
  871. break;
  872. } // WINSCP
  873. }
  874. case ENC_COPY: {
  875. uint32_t r = rs[tail];
  876. tail = (tail + n - 1) % n;
  877. head = (head + n - 1) % n;
  878. rs[head] = r;
  879. break;
  880. }
  881. default: {
  882. uint32_t r = rs[tail];
  883. tail = (tail + n - 1) % n;
  884. { // WINSCP
  885. uint32_t m = op - ENC_COMBINE_BASE;
  886. uint64_t mrecip = reciprocal_for_reduction(m);
  887. uint32_t r1, r2;
  888. r1 = reduce_with_quot(r, &r2, m, mrecip);
  889. head = (head + n - 1) % n;
  890. rs[head] = r2;
  891. head = (head + n - 1) % n;
  892. rs[head] = r1;
  893. break;
  894. } // WINSCP
  895. }
  896. }
  897. }
  898. } // WINSCP
  899. assert(pos == base);
  900. assert(head == 0);
  901. assert(tail == n-1);
  902. { // WINSCP
  903. size_t i;
  904. for (i = 0; i < n; i++)
  905. rs_out[i] = rs[i];
  906. } // WINSCP
  907. smemclr(rs, n * sizeof(*rs));
  908. sfree(rs);
  909. }
  910. /* ----------------------------------------------------------------------
  911. * The actual public-key cryptosystem.
  912. */
  913. struct NTRUKeyPair {
  914. unsigned p, q, w;
  915. uint16_t *h; /* public key */
  916. uint16_t *f3, *ginv; /* private key */
  917. uint16_t *rho; /* for implicit rejection */
  918. };
  919. /* Helper function to free an array of uint16_t containing a ring
  920. * element, clearing it on the way since some of them are sensitive. */
  921. static void ring_free(uint16_t *val, unsigned p)
  922. {
  923. smemclr(val, p*sizeof(*val));
  924. sfree(val);
  925. }
  926. void ntru_keypair_free(NTRUKeyPair *keypair)
  927. {
  928. ring_free(keypair->h, keypair->p);
  929. ring_free(keypair->f3, keypair->p);
  930. ring_free(keypair->ginv, keypair->p);
  931. ring_free(keypair->rho, keypair->p);
  932. sfree(keypair);
  933. }
  934. /* Trivial accessors used by test programs. */
  935. unsigned ntru_keypair_p(NTRUKeyPair *keypair) { return keypair->p; }
  936. const uint16_t *ntru_pubkey(NTRUKeyPair *keypair) { return keypair->h; }
  937. /*
  938. * Generate a value of the class DJB describes as 'Short': it consists
  939. * of p terms that are all either 0 or +1 or -1, and exactly w of them
  940. * are not zero.
  941. *
  942. * Values of this kind are used for several purposes: part of the
  943. * private key, a plaintext, and the 'rho' fake-plaintext value used
  944. * for deliberately returning a duff but non-revealing session hash if
  945. * things go wrong.
  946. *
  947. * -1 is represented as 2 in the output array. So if you want these
  948. * numbers mod 3, then they come out already in the right form.
  949. * Otherwise, use ntru_expand.
  950. */
  951. void ntru_gen_short(uint16_t *v, unsigned p, unsigned w)
  952. {
  953. /*
  954. * Get enough random data to generate a polynomial all of whose p
  955. * terms are in {0,+1,-1}, and exactly w of them are nonzero.
  956. * We'll do this by making up a completely random sequence of
  957. * {+1,-1} and then setting a random subset of them to 0.
  958. *
  959. * So we'll need p random bits to choose the nonzero values, and
  960. * then (doing it the simplest way) log2(p!) bits to shuffle them,
  961. * plus say 128 bits to ensure any fluctuations in uniformity are
  962. * negligible.
  963. *
  964. * log2(p!) is a pain to calculate, so we'll bound it above by
  965. * p*log2(p), which we bound in turn by p*16.
  966. */
  967. size_t randbitpos = 17 * p + 128;
  968. mp_int *randdata = mp_resize(mp_random_bits(randbitpos), randbitpos + 32);
  969. /*
  970. * Initial value before zeroing out some terms: p randomly chosen
  971. * values in {1,2}.
  972. */
  973. { // WINSCP
  974. size_t i;
  975. for (i = 0; i < p; i++)
  976. v[i] = 1 + mp_get_bit(randdata, --randbitpos);
  977. } // WINSCP
  978. /*
  979. * Hereafter we're going to extract random bits by multiplication,
  980. * treating randdata as a large fixed-point number.
  981. */
  982. mp_reduce_mod_2to(randdata, randbitpos);
  983. /*
  984. * Zero out some terms, leaving a randomly selected w of them
  985. * nonzero.
  986. */
  987. { // WINSCP
  988. uint32_t nonzeros_left = w;
  989. mp_int *x = mp_new(64);
  990. { // WINSCP
  991. size_t i;
  992. for (i = p; i-- > 0 ;) {
  993. /*
  994. * Pick a random number out of the number of terms remaning.
  995. */
  996. mp_mul_integer_into(randdata, randdata, i+1);
  997. mp_rshift_fixed_into(x, randdata, randbitpos);
  998. mp_reduce_mod_2to(randdata, randbitpos);
  999. { // WINSCP
  1000. size_t j = mp_get_integer(x);
  1001. /*
  1002. * If that's less than nonzeros_left, then we're leaving this
  1003. * number nonzero. Otherwise we're zeroing it out.
  1004. */
  1005. uint32_t keep = (uint32_t)(j - nonzeros_left) >> 31;
  1006. v[i] &= (uint32_t)-(int32_t)keep; /* clear this field if keep == 0 */ // WINSCP
  1007. nonzeros_left -= keep; /* decrement counter if keep == 1 */
  1008. } // WINSCP
  1009. }
  1010. } // WINSCP
  1011. mp_free(x);
  1012. mp_free(randdata);
  1013. } // WINSCP
  1014. }
  1015. /*
  1016. * Make a single attempt at generating a key pair. This involves
  1017. * inventing random elements of both our quotient rings and hoping
  1018. * they're both invertible.
  1019. *
  1020. * They may not be, if you're unlucky. The element of Z_q/<x^p-x-1>
  1021. * will _almost_ certainly be invertible, because that is a field, so
  1022. * invertibility can only fail if you were so unlucky as to choose the
  1023. * all-0s element. But the element of Z_3/<x^p-x-1> may fail to be
  1024. * invertible because it has a common factor with x^p-x-1 (which, over
  1025. * Z_3, is not irreducible).
  1026. *
  1027. * So we can't guarantee to generate a key pair in constant time,
  1028. * because there's no predicting how many retries we'll need. However,
  1029. * this isn't a failure of side-channel safety, because we completely
  1030. * discard all the random numbers and state from each failed attempt.
  1031. * So if there were a side-channel leakage from a failure, the only
  1032. * thing it would give away would be a bunch of random numbers that
  1033. * turned out not to be used anyway.
  1034. *
  1035. * But a _successful_ call to this function should execute in a
  1036. * secret-independent manner, and this 'make a single attempt'
  1037. * function is exposed in the API so that 'testsc' can check that.
  1038. */
  1039. NTRUKeyPair *ntru_keygen_attempt(unsigned p, unsigned q, unsigned w)
  1040. {
  1041. /*
  1042. * First invent g, which is the one more likely to fail to invert.
  1043. * This is simply a uniformly random polynomial with p terms over
  1044. * Z_3. So we need p*log2(3) random bits for it, plus 128 for
  1045. * uniformity. It's easiest to bound log2(3) above by 2.
  1046. */
  1047. size_t randbitpos = 2 * p + 128;
  1048. mp_int *randdata = mp_resize(mp_random_bits(randbitpos), randbitpos + 32);
  1049. /*
  1050. * Select p random values from {0,1,2}.
  1051. */
  1052. uint16_t *g = snewn(p, uint16_t);
  1053. mp_int *x = mp_new(64);
  1054. { // WINSCP
  1055. size_t i;
  1056. for (i = 0; i < p; i++) {
  1057. mp_mul_integer_into(randdata, randdata, 3);
  1058. mp_rshift_fixed_into(x, randdata, randbitpos);
  1059. mp_reduce_mod_2to(randdata, randbitpos);
  1060. g[i] = mp_get_integer(x);
  1061. }
  1062. } // WINSCP
  1063. mp_free(x);
  1064. mp_free(randdata);
  1065. /*
  1066. * Try to invert g over Z_3, and fail if it isn't invertible.
  1067. */
  1068. { // WINSCP
  1069. uint16_t *ginv = snewn(p, uint16_t);
  1070. if (!ntru_ring_invert(ginv, g, p, 3)) {
  1071. ring_free(g, p);
  1072. ring_free(ginv, p);
  1073. return NULL;
  1074. }
  1075. /*
  1076. * Fine; we have g. Now make up an f, and convert it to a
  1077. * polynomial over q.
  1078. */
  1079. { // WINSCP
  1080. uint16_t *f = snewn(p, uint16_t);
  1081. ntru_gen_short(f, p, w);
  1082. ntru_expand(f, f, p, q);
  1083. /*
  1084. * Multiply f by 3.
  1085. */
  1086. { // WINSCP
  1087. uint16_t *f3 = snewn(p, uint16_t);
  1088. ntru_scale(f3, f, 3, p, q);
  1089. /*
  1090. * Try to invert 3*f over Z_q. This should be _almost_ guaranteed
  1091. * to succeed, since Z_q/<x^p-x-1> is a field, so the only
  1092. * non-invertible value is 0. Even so, there _is_ one, so check
  1093. * the return value!
  1094. */
  1095. { // WINSCP
  1096. uint16_t *f3inv = snewn(p, uint16_t);
  1097. if (!ntru_ring_invert(f3inv, f3, p, q)) {
  1098. ring_free(f, p);
  1099. ring_free(f3, p);
  1100. ring_free(f3inv, p);
  1101. ring_free(g, p);
  1102. ring_free(ginv, p);
  1103. return NULL;
  1104. }
  1105. /*
  1106. * Make the public key, by converting g to a polynomial over q and
  1107. * then multiplying by f3inv.
  1108. */
  1109. { // WINSCP
  1110. uint16_t *g_q = snewn(p, uint16_t);
  1111. ntru_expand(g_q, g, p, q);
  1112. { // WINSCP
  1113. uint16_t *h = snewn(p, uint16_t);
  1114. ntru_ring_multiply(h, g_q, f3inv, p, q);
  1115. /*
  1116. * Make up rho, used to substitute for the plaintext in the
  1117. * session hash in case of confirmation failure.
  1118. */
  1119. { // WINSCP
  1120. uint16_t *rho = snewn(p, uint16_t);
  1121. ntru_gen_short(rho, p, w);
  1122. /*
  1123. * And we're done! Free everything except the pieces we're
  1124. * returning.
  1125. */
  1126. { // WINSCP
  1127. NTRUKeyPair *keypair = snew(NTRUKeyPair);
  1128. keypair->p = p;
  1129. keypair->q = q;
  1130. keypair->w = w;
  1131. keypair->h = h;
  1132. keypair->f3 = f3;
  1133. keypair->ginv = ginv;
  1134. keypair->rho = rho;
  1135. ring_free(f, p);
  1136. ring_free(f3inv, p);
  1137. ring_free(g, p);
  1138. ring_free(g_q, p);
  1139. return keypair;
  1140. } // WINSCP
  1141. } // WINSCP
  1142. } // WINSCP
  1143. } // WINSCP
  1144. } // WINSCP
  1145. } // WINSCP
  1146. } // WINSCP
  1147. } // WINSCP
  1148. }
  1149. /*
  1150. * The top-level key generation function for real use (as opposed to
  1151. * testsc): keep trying to make a key until you succeed.
  1152. */
  1153. NTRUKeyPair *ntru_keygen(unsigned p, unsigned q, unsigned w)
  1154. {
  1155. while (1) {
  1156. NTRUKeyPair *keypair = ntru_keygen_attempt(p, q, w);
  1157. if (keypair)
  1158. return keypair;
  1159. }
  1160. }
  1161. /*
  1162. * Public-key encryption.
  1163. */
  1164. void ntru_encrypt(uint16_t *ciphertext, const uint16_t *plaintext,
  1165. uint16_t *pubkey, unsigned p, unsigned q)
  1166. {
  1167. uint16_t *r_q = snewn(p, uint16_t);
  1168. ntru_expand(r_q, plaintext, p, q);
  1169. { // WINSCP
  1170. uint16_t *unrounded = snewn(p, uint16_t);
  1171. ntru_ring_multiply(unrounded, r_q, pubkey, p, q);
  1172. ntru_round3(ciphertext, unrounded, p, q);
  1173. ntru_normalise(ciphertext, ciphertext, p, q);
  1174. ring_free(r_q, p);
  1175. ring_free(unrounded, p);
  1176. } // WINSCP
  1177. }
  1178. /*
  1179. * Public-key decryption.
  1180. */
  1181. void ntru_decrypt(uint16_t *plaintext, const uint16_t *ciphertext,
  1182. NTRUKeyPair *keypair)
  1183. {
  1184. unsigned p = keypair->p, q = keypair->q, w = keypair->w;
  1185. uint16_t *tmp = snewn(p, uint16_t);
  1186. ntru_ring_multiply(tmp, ciphertext, keypair->f3, p, q);
  1187. ntru_mod3(tmp, tmp, p, q);
  1188. ntru_normalise(tmp, tmp, p, 3);
  1189. ntru_ring_multiply(plaintext, tmp, keypair->ginv, p, 3);
  1190. ring_free(tmp, p);
  1191. /*
  1192. * With luck, this should have recovered exactly the original
  1193. * plaintext. But, as per the spec, we check whether it has
  1194. * exactly w nonzero coefficients, and if not, then something has
  1195. * gone wrong - and in that situation we time-safely substitute a
  1196. * different output.
  1197. *
  1198. * (I don't know exactly why we do this, but I assume it's because
  1199. * otherwise the mis-decoded output could be made to disgorge a
  1200. * secret about the private key in some way.)
  1201. */
  1202. { // WINSCP
  1203. unsigned weight = p;
  1204. { // WINSCP
  1205. size_t i;
  1206. for (i = 0; i < p; i++)
  1207. weight -= iszero(plaintext[i]);
  1208. } // WINSCP
  1209. { // WINSCP
  1210. unsigned ok = iszero(weight ^ w);
  1211. /*
  1212. * The default failure return value consists of w 1s followed by
  1213. * 0s.
  1214. */
  1215. unsigned mask = ok - 1;
  1216. { // WINSCP
  1217. size_t i;
  1218. for (i = 0; i < w; i++) {
  1219. uint16_t diff = (1 ^ plaintext[i]) & mask;
  1220. plaintext[i] ^= diff;
  1221. }
  1222. } // WINSCP
  1223. { // WINSCP
  1224. size_t i;
  1225. for (i = w; i < p; i++) {
  1226. uint16_t diff = (0 ^ plaintext[i]) & mask;
  1227. plaintext[i] ^= diff;
  1228. }
  1229. } // WINSCP
  1230. } // WINSCP
  1231. } // WINSCP
  1232. }
  1233. /* ----------------------------------------------------------------------
  1234. * Encode and decode public keys, ciphertexts and plaintexts.
  1235. *
  1236. * Public keys and ciphertexts use the complicated binary encoding
  1237. * system implemented above. In both cases, the inputs are regarded as
  1238. * symmetric about zero, and are first biased to map their most
  1239. * negative permitted value to 0, so that they become non-negative and
  1240. * hence suitable as inputs to the encoding system. In the case of a
  1241. * ciphertext, where the input coefficients have also been coerced to
  1242. * be multiples of 3, we divide by 3 as well, saving space by reducing
  1243. * the upper bounds (m_i) on all the encoded numbers.
  1244. */
  1245. /*
  1246. * Compute the encoding schedule for a public key.
  1247. */
  1248. static NTRUEncodeSchedule *ntru_encode_pubkey_schedule(unsigned p, unsigned q)
  1249. {
  1250. uint16_t *ms = snewn(p, uint16_t);
  1251. { // WINSCP
  1252. size_t i;
  1253. for (i = 0; i < p; i++)
  1254. ms[i] = q;
  1255. } // WINSCP
  1256. { // WINSCP
  1257. NTRUEncodeSchedule *sched = ntru_encode_schedule(ms, p);
  1258. sfree(ms);
  1259. return sched;
  1260. } // WINSCP
  1261. }
  1262. /*
  1263. * Encode a public key.
  1264. */
  1265. void ntru_encode_pubkey(const uint16_t *pubkey, unsigned p, unsigned q,
  1266. BinarySink *bs)
  1267. {
  1268. /* Compute the biased version for encoding */
  1269. uint16_t *biased_pubkey = snewn(p, uint16_t);
  1270. ntru_bias(biased_pubkey, pubkey, q / 2, p, q);
  1271. /* Encode it */
  1272. { // WINSCP
  1273. NTRUEncodeSchedule *sched = ntru_encode_pubkey_schedule(p, q);
  1274. ntru_encode(sched, biased_pubkey, bs);
  1275. ntru_encode_schedule_free(sched);
  1276. ring_free(biased_pubkey, p);
  1277. } // WINSCP
  1278. }
  1279. /*
  1280. * Decode a public key and write it into 'pubkey'. We also return a
  1281. * ptrlen pointing at the chunk of data we removed from the
  1282. * BinarySource.
  1283. */
  1284. ptrlen ntru_decode_pubkey(uint16_t *pubkey, unsigned p, unsigned q,
  1285. BinarySource *src)
  1286. {
  1287. NTRUEncodeSchedule *sched = ntru_encode_pubkey_schedule(p, q);
  1288. /* Retrieve the right number of bytes from the source */
  1289. size_t len = ntru_encode_schedule_length(sched);
  1290. ptrlen encoded = get_data(src, len);
  1291. if (get_err(src)) {
  1292. /* If there wasn't enough data, give up and return all-zeroes
  1293. * purely for determinism. But that value should never be
  1294. * used, because the caller will also check get_err(src). */
  1295. memset(pubkey, 0, p*sizeof(*pubkey));
  1296. } else {
  1297. /* Do the decoding */
  1298. ntru_decode(sched, pubkey, encoded);
  1299. /* Unbias the coefficients */
  1300. ntru_bias(pubkey, pubkey, q-q/2, p, q);
  1301. }
  1302. ntru_encode_schedule_free(sched);
  1303. return encoded;
  1304. }
  1305. /*
  1306. * For ciphertext biasing: work out the largest absolute value a
  1307. * ciphertext element can take, which is given by taking q/2 and
  1308. * rounding it to the nearest multiple of 3.
  1309. */
  1310. static inline unsigned ciphertext_bias(unsigned q)
  1311. {
  1312. return (q/2+1) / 3;
  1313. }
  1314. /*
  1315. * The number of possible values of a ciphertext coefficient (for use
  1316. * as the m_i in encoding) ranges from +ciphertext_bias(q) to
  1317. * -ciphertext_bias(q) inclusive.
  1318. */
  1319. static inline unsigned ciphertext_m(unsigned q)
  1320. {
  1321. return 1 + 2 * ciphertext_bias(q);
  1322. }
  1323. /*
  1324. * Compute the encoding schedule for a ciphertext.
  1325. */
  1326. static NTRUEncodeSchedule *ntru_encode_ciphertext_schedule(
  1327. unsigned p, unsigned q)
  1328. {
  1329. unsigned m = ciphertext_m(q);
  1330. uint16_t *ms = snewn(p, uint16_t);
  1331. { // WINSCP
  1332. size_t i;
  1333. for (i = 0; i < p; i++)
  1334. ms[i] = m;
  1335. } // WINSCP
  1336. { // WINSCP
  1337. NTRUEncodeSchedule *sched = ntru_encode_schedule(ms, p);
  1338. sfree(ms);
  1339. return sched;
  1340. } // WINSCP
  1341. }
  1342. /*
  1343. * Encode a ciphertext.
  1344. */
  1345. void ntru_encode_ciphertext(const uint16_t *ciphertext, unsigned p, unsigned q,
  1346. BinarySink *bs)
  1347. {
  1348. SETUP;
  1349. /*
  1350. * Bias the ciphertext, and scale down by 1/3, which we do by
  1351. * modular multiplication by the inverse of 3 mod q. (That only
  1352. * works if we know the inputs are all _exact_ multiples of 3
  1353. * - but we do!)
  1354. */
  1355. uint16_t *biased_ciphertext = snewn(p, uint16_t);
  1356. ntru_bias(biased_ciphertext, ciphertext, 3 * ciphertext_bias(q), p, q);
  1357. ntru_scale(biased_ciphertext, biased_ciphertext, INVERT(3), p, q);
  1358. /* Encode. */
  1359. { // WINSCP
  1360. NTRUEncodeSchedule *sched = ntru_encode_ciphertext_schedule(p, q);
  1361. ntru_encode(sched, biased_ciphertext, bs);
  1362. ntru_encode_schedule_free(sched);
  1363. ring_free(biased_ciphertext, p);
  1364. } // WINSCP
  1365. }
  1366. ptrlen ntru_decode_ciphertext(uint16_t *ct, NTRUKeyPair *keypair,
  1367. BinarySource *src)
  1368. {
  1369. unsigned p = keypair->p, q = keypair->q;
  1370. NTRUEncodeSchedule *sched = ntru_encode_ciphertext_schedule(p, q);
  1371. /* Retrieve the right number of bytes from the source */
  1372. size_t len = ntru_encode_schedule_length(sched);
  1373. ptrlen encoded = get_data(src, len);
  1374. if (get_err(src)) {
  1375. /* As above, return deterministic nonsense on failure */
  1376. memset(ct, 0, p*sizeof(*ct));
  1377. } else {
  1378. /* Do the decoding */
  1379. ntru_decode(sched, ct, encoded);
  1380. /* Undo the scaling and bias */
  1381. ntru_scale(ct, ct, 3, p, q);
  1382. ntru_bias(ct, ct, q - 3 * ciphertext_bias(q), p, q);
  1383. }
  1384. ntru_encode_schedule_free(sched);
  1385. return encoded; /* also useful to the caller, optionally */
  1386. }
  1387. /*
  1388. * Encode a plaintext.
  1389. *
  1390. * This is a much simpler encoding than the NTRUEncodeSchedule system:
  1391. * since elements of a plaintext are mod 3, we just encode each one in
  1392. * 2 bits, applying the usual bias so that {-1,0,+1} map to {0,1,2}
  1393. * respectively.
  1394. *
  1395. * There's no corresponding decode function, because plaintexts are
  1396. * never transmitted on the wire (the whole point is that they're too
  1397. * secret!). Plaintexts are only encoded in order to put them into
  1398. * hash preimages.
  1399. */
  1400. void ntru_encode_plaintext(const uint16_t *plaintext, unsigned p,
  1401. BinarySink *bs)
  1402. {
  1403. unsigned byte = 0, bitpos = 0;
  1404. { // WINSCP
  1405. size_t i;
  1406. for (i = 0; i < p; i++) {
  1407. unsigned encoding = (plaintext[i] + 1) * iszero(plaintext[i] >> 1);
  1408. byte |= encoding << bitpos;
  1409. bitpos += 2;
  1410. if (bitpos == 8 || i+1 == p) {
  1411. put_byte(bs, byte);
  1412. byte = 0;
  1413. bitpos = 0;
  1414. }
  1415. }
  1416. } // WINSCP
  1417. }
  1418. /* ----------------------------------------------------------------------
  1419. * Compute the hashes required by the key exchange layer of NTRU Prime.
  1420. *
  1421. * There are two of these. The 'confirmation hash' is sent by the
  1422. * server along with the ciphertext, and the client can recalculate it
  1423. * to check whether the ciphertext was decrypted correctly. Then, the
  1424. * 'session hash' is the actual output of key exchange, and if the
  1425. * confirmation hash doesn't match, it gets deliberately corrupted.
  1426. */
  1427. /*
  1428. * Make the confirmation hash, whose inputs are the plaintext and the
  1429. * public key.
  1430. *
  1431. * This is defined as H(2 || H(3 || r) || H(4 || K)), where r is the
  1432. * plaintext and K is the public key (as encoded by the above
  1433. * functions), and the constants 2,3,4 are single bytes. The choice of
  1434. * hash function (H itself) is SHA-512 truncated to 256 bits.
  1435. *
  1436. * (To be clear: that is _not_ the thing that FIPS 180-4 6.7 defines
  1437. * as "SHA-512/256", which varies the initialisation vector of the
  1438. * SHA-512 algorithm as well as truncating the output. _This_
  1439. * algorithm uses the standard SHA-512 IV, and _just_ truncates the
  1440. * output, in the manner suggested by FIPS 180-4 section 7.)
  1441. *
  1442. * 'out' should therefore expect to receive 32 bytes of data.
  1443. */
  1444. static void ntru_confirmation_hash(
  1445. uint8_t *out, const uint16_t *plaintext,
  1446. const uint16_t *pubkey, unsigned p, unsigned q)
  1447. {
  1448. /* The outer hash object */
  1449. ssh_hash *hconfirm = ssh_hash_new(&ssh_sha512);
  1450. put_byte(hconfirm, 2); /* initial byte 2 */
  1451. { // WINSCP
  1452. uint8_t hashdata[64];
  1453. /* Compute H(3 || r) and add it to the main hash */
  1454. ssh_hash *h3r = ssh_hash_new(&ssh_sha512);
  1455. put_byte(h3r, 3);
  1456. ntru_encode_plaintext(plaintext, p, BinarySink_UPCAST(h3r));
  1457. ssh_hash_final(h3r, hashdata);
  1458. put_data(hconfirm, hashdata, 32);
  1459. /* Compute H(4 || K) and add it to the main hash */
  1460. { // WINSCP
  1461. ssh_hash *h4K = ssh_hash_new(&ssh_sha512);
  1462. put_byte(h4K, 4);
  1463. ntru_encode_pubkey(pubkey, p, q, BinarySink_UPCAST(h4K));
  1464. ssh_hash_final(h4K, hashdata);
  1465. put_data(hconfirm, hashdata, 32);
  1466. /* Compute the full output of the main SHA-512 hash */
  1467. ssh_hash_final(hconfirm, hashdata);
  1468. /* And copy the first 32 bytes into the caller's output array */
  1469. memcpy(out, hashdata, 32);
  1470. smemclr(hashdata, sizeof(hashdata));
  1471. } // WINSCP
  1472. } // WINSCP
  1473. }
  1474. /*
  1475. * Make the session hash, whose inputs are the plaintext, the
  1476. * ciphertext, and the confirmation hash (hence, transitively, a
  1477. * dependence on the public key as well).
  1478. *
  1479. * As computed by the server, and by the client if the confirmation
  1480. * hash matched, this is defined as
  1481. *
  1482. * H(1 || H(3 || r) || ciphertext || confirmation hash)
  1483. *
  1484. * but if the confirmation hash _didn't_ match, then the plaintext r
  1485. * is replaced with the dummy plaintext-shaped value 'rho' we invented
  1486. * during key generation (presumably to avoid leaking any information
  1487. * about our secrets), and the initial byte 1 is replaced with 0 (to
  1488. * ensure that the resulting hash preimage can't match any legitimate
  1489. * preimage). So in that case, you instead get
  1490. *
  1491. * H(0 || H(3 || rho) || ciphertext || confirmation hash)
  1492. *
  1493. * The inputs to this function include 'ok', which is the value to use
  1494. * as the initial byte (1 on success, 0 on failure), and 'plaintext'
  1495. * which should already have been substituted with rho in case of
  1496. * failure.
  1497. *
  1498. * The ciphertext is provided in already-encoded form.
  1499. */
  1500. static void ntru_session_hash(
  1501. uint8_t *out, unsigned ok, const uint16_t *plaintext,
  1502. unsigned p, ptrlen ciphertext, ptrlen confirmation_hash)
  1503. {
  1504. /* The outer hash object */
  1505. ssh_hash *hsession = ssh_hash_new(&ssh_sha512);
  1506. put_byte(hsession, ok); /* initial byte 1 or 0 */
  1507. { // WINSCP
  1508. uint8_t hashdata[64];
  1509. /* Compute H(3 || r), or maybe H(3 || rho), and add it to the main hash */
  1510. ssh_hash *h3r = ssh_hash_new(&ssh_sha512);
  1511. put_byte(h3r, 3);
  1512. ntru_encode_plaintext(plaintext, p, BinarySink_UPCAST(h3r));
  1513. ssh_hash_final(h3r, hashdata);
  1514. put_data(hsession, hashdata, 32);
  1515. /* Put the ciphertext and confirmation hash in */
  1516. put_datapl(hsession, ciphertext);
  1517. put_datapl(hsession, confirmation_hash);
  1518. /* Compute the full output of the main SHA-512 hash */
  1519. ssh_hash_final(hsession, hashdata);
  1520. /* And copy the first 32 bytes into the caller's output array */
  1521. memcpy(out, hashdata, 32);
  1522. smemclr(hashdata, sizeof(hashdata));
  1523. } // WINSCP
  1524. }
  1525. /* ----------------------------------------------------------------------
  1526. * Top-level key exchange and SSH integration.
  1527. *
  1528. * Although this system borrows the ECDH packet structure, it's unlike
  1529. * true ECDH in that it is completely asymmetric between client and
  1530. * server. So we have two separate vtables of methods for the two
  1531. * sides of the system, and a third vtable containing only the class
  1532. * methods, in particular a constructor which chooses which one to
  1533. * instantiate.
  1534. */
  1535. /*
  1536. * The parameters p,q,w for the system. There are other choices of
  1537. * these, but OpenSSH only specifies this set. (If that ever changes,
  1538. * we'll need to turn these into elements of the state structures.)
  1539. */
  1540. #define p_LIVE 761
  1541. #define q_LIVE 4591
  1542. #define w_LIVE 286
  1543. static char *ssh_ntru_description(const ssh_kex *kex)
  1544. {
  1545. return dupprintf("NTRU Prime / Curve25519 hybrid key exchange");
  1546. }
  1547. /*
  1548. * State structure for the client, which takes the role of inventing a
  1549. * key pair and decrypting a secret plaintext sent to it by the server.
  1550. */
  1551. typedef struct ntru_client_key {
  1552. NTRUKeyPair *keypair;
  1553. ecdh_key *curve25519;
  1554. ecdh_key ek;
  1555. } ntru_client_key;
  1556. static void ssh_ntru_client_free(ecdh_key *dh);
  1557. static void ssh_ntru_client_getpublic(ecdh_key *dh, BinarySink *bs);
  1558. static bool ssh_ntru_client_getkey(ecdh_key *dh, ptrlen remoteKey,
  1559. BinarySink *bs);
  1560. static const ecdh_keyalg ssh_ntru_client_vt = {
  1561. /* This vtable has no 'new' method, because it's constructed via
  1562. * the selector vt below */
  1563. NULL, // WINSCP
  1564. /*.free =*/ ssh_ntru_client_free,
  1565. /*.getpublic =*/ ssh_ntru_client_getpublic,
  1566. /*.getkey =*/ ssh_ntru_client_getkey,
  1567. /*.description =*/ ssh_ntru_description,
  1568. };
  1569. static ecdh_key *ssh_ntru_client_new(void)
  1570. {
  1571. ntru_client_key *nk = snew(ntru_client_key);
  1572. nk->ek.vt = &ssh_ntru_client_vt;
  1573. nk->keypair = ntru_keygen(p_LIVE, q_LIVE, w_LIVE);
  1574. nk->curve25519 = ecdh_key_new(&ssh_ec_kex_curve25519, false);
  1575. return &nk->ek;
  1576. }
  1577. static void ssh_ntru_client_free(ecdh_key *dh)
  1578. {
  1579. ntru_client_key *nk = container_of(dh, ntru_client_key, ek);
  1580. ntru_keypair_free(nk->keypair);
  1581. ecdh_key_free(nk->curve25519);
  1582. sfree(nk);
  1583. }
  1584. static void ssh_ntru_client_getpublic(ecdh_key *dh, BinarySink *bs)
  1585. {
  1586. ntru_client_key *nk = container_of(dh, ntru_client_key, ek);
  1587. /*
  1588. * The client's public information is a single SSH string
  1589. * containing the NTRU public key and the Curve25519 public point
  1590. * concatenated. So write both of those into the output
  1591. * BinarySink.
  1592. */
  1593. ntru_encode_pubkey(nk->keypair->h, p_LIVE, q_LIVE, bs);
  1594. ecdh_key_getpublic(nk->curve25519, bs);
  1595. }
  1596. static bool ssh_ntru_client_getkey(ecdh_key *dh, ptrlen remoteKey,
  1597. BinarySink *bs)
  1598. {
  1599. ntru_client_key *nk = container_of(dh, ntru_client_key, ek);
  1600. /*
  1601. * We expect the server to have sent us a string containing a
  1602. * ciphertext, a confirmation hash, and a Curve25519 public point.
  1603. * Extract all three.
  1604. */
  1605. BinarySource src[1];
  1606. BinarySource_BARE_INIT_PL(src, remoteKey);
  1607. { // WINSCP
  1608. uint16_t *ciphertext = snewn(p_LIVE, uint16_t);
  1609. ptrlen ciphertext_encoded = ntru_decode_ciphertext(
  1610. ciphertext, nk->keypair, src);
  1611. ptrlen confirmation_hash = get_data(src, 32);
  1612. ptrlen curve25519_remoteKey = get_data(src, 32);
  1613. if (get_err(src) || get_avail(src)) {
  1614. /* Hard-fail if the input wasn't exactly the right length */
  1615. ring_free(ciphertext, p_LIVE);
  1616. return false;
  1617. }
  1618. /*
  1619. * Main hash object which will combine the NTRU and Curve25519
  1620. * outputs.
  1621. */
  1622. { // WINSCP
  1623. ssh_hash *h = ssh_hash_new(&ssh_sha512);
  1624. /* Reusable buffer for storing various hash outputs. */
  1625. uint8_t hashdata[64];
  1626. /*
  1627. * NTRU side.
  1628. */
  1629. {
  1630. /* Decrypt the ciphertext to recover the server's plaintext */
  1631. uint16_t *plaintext = snewn(p_LIVE, uint16_t);
  1632. ntru_decrypt(plaintext, ciphertext, nk->keypair);
  1633. /* Make the confirmation hash */
  1634. ntru_confirmation_hash(hashdata, plaintext, nk->keypair->h,
  1635. p_LIVE, q_LIVE);
  1636. /* Check it matches the one the server sent */
  1637. { // WINSCP
  1638. unsigned ok = smemeq(hashdata, confirmation_hash.ptr, 32);
  1639. /* If not, substitute in rho for the plaintext in the session hash */
  1640. unsigned mask = ok-1;
  1641. { // WINSCP
  1642. size_t i;
  1643. for (i = 0; i < p_LIVE; i++)
  1644. plaintext[i] ^= mask & (plaintext[i] ^ nk->keypair->rho[i]);
  1645. } // WINSCP
  1646. /* Compute the session hash, whether or not we did that */
  1647. ntru_session_hash(hashdata, ok, plaintext, p_LIVE, ciphertext_encoded,
  1648. confirmation_hash);
  1649. /* Free temporary values */
  1650. ring_free(plaintext, p_LIVE);
  1651. ring_free(ciphertext, p_LIVE);
  1652. /* And put the NTRU session hash into the main hash object. */
  1653. put_data(h, hashdata, 32);
  1654. } // WINSCP
  1655. }
  1656. /*
  1657. * Curve25519 side.
  1658. */
  1659. {
  1660. strbuf *otherkey = strbuf_new_nm();
  1661. /* Call out to Curve25519 to compute the shared secret from that
  1662. * kex method */
  1663. bool ok = ecdh_key_getkey(nk->curve25519, curve25519_remoteKey,
  1664. BinarySink_UPCAST(otherkey));
  1665. /* If that failed (which only happens if the other end does
  1666. * something wrong, like sending a low-order curve point
  1667. * outside the subgroup it's supposed to), we might as well
  1668. * just abort and return failure. That's what we'd have done
  1669. * in standalone Curve25519. */
  1670. if (!ok) {
  1671. ssh_hash_free(h);
  1672. smemclr(hashdata, sizeof(hashdata));
  1673. strbuf_free(otherkey);
  1674. return false;
  1675. }
  1676. /*
  1677. * ecdh_key_getkey will have returned us a chunk of data
  1678. * containing an encoded mpint, which is how the Curve25519
  1679. * output normally goes into the exchange hash. But in this
  1680. * context we want to treat it as a fixed big-endian 32 bytes,
  1681. * so extract it from its encoding and put it into the main
  1682. * hash object in the new format.
  1683. */
  1684. { // WINSCP
  1685. BinarySource src[1];
  1686. BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(otherkey));
  1687. { // WINSCP
  1688. mp_int *curvekey = get_mp_ssh2(src);
  1689. { // WINSCP
  1690. unsigned i;
  1691. for (i = 32; i-- > 0 ;)
  1692. put_byte(h, mp_get_byte(curvekey, i));
  1693. } // WINSCP
  1694. mp_free(curvekey);
  1695. strbuf_free(otherkey);
  1696. } // WINSCP
  1697. } // WINSCP
  1698. }
  1699. /*
  1700. * Finish up: compute the final output hash (full 64 bytes of
  1701. * SHA-512 this time), and return it encoded as a string.
  1702. */
  1703. ssh_hash_final(h, hashdata);
  1704. put_stringpl(bs, make_ptrlen(hashdata, sizeof(hashdata)));
  1705. smemclr(hashdata, sizeof(hashdata));
  1706. return true;
  1707. } // WINSCP
  1708. } // WINSCP
  1709. }
  1710. /*
  1711. * State structure for the server, which takes the role of inventing a
  1712. * secret plaintext and sending it to the client encrypted with the
  1713. * public key the client sent.
  1714. */
  1715. typedef struct ntru_server_key {
  1716. uint16_t *plaintext;
  1717. strbuf *ciphertext_encoded, *confirmation_hash;
  1718. ecdh_key *curve25519;
  1719. ecdh_key ek;
  1720. } ntru_server_key;
  1721. static void ssh_ntru_server_free(ecdh_key *dh);
  1722. static void ssh_ntru_server_getpublic(ecdh_key *dh, BinarySink *bs);
  1723. static bool ssh_ntru_server_getkey(ecdh_key *dh, ptrlen remoteKey,
  1724. BinarySink *bs);
  1725. static const ecdh_keyalg ssh_ntru_server_vt = {
  1726. /* This vtable has no 'new' method, because it's constructed via
  1727. * the selector vt below */
  1728. NULL, // WINSCP
  1729. /*.free =*/ ssh_ntru_server_free,
  1730. /*.getpublic =*/ ssh_ntru_server_getpublic,
  1731. /*.getkey =*/ ssh_ntru_server_getkey,
  1732. /*.description =*/ ssh_ntru_description,
  1733. };
  1734. static ecdh_key *ssh_ntru_server_new(void)
  1735. {
  1736. ntru_server_key *nk = snew(ntru_server_key);
  1737. nk->ek.vt = &ssh_ntru_server_vt;
  1738. nk->plaintext = snewn(p_LIVE, uint16_t);
  1739. nk->ciphertext_encoded = strbuf_new_nm();
  1740. nk->confirmation_hash = strbuf_new_nm();
  1741. ntru_gen_short(nk->plaintext, p_LIVE, w_LIVE);
  1742. nk->curve25519 = ecdh_key_new(&ssh_ec_kex_curve25519, false);
  1743. return &nk->ek;
  1744. }
  1745. static void ssh_ntru_server_free(ecdh_key *dh)
  1746. {
  1747. ntru_server_key *nk = container_of(dh, ntru_server_key, ek);
  1748. ring_free(nk->plaintext, p_LIVE);
  1749. strbuf_free(nk->ciphertext_encoded);
  1750. strbuf_free(nk->confirmation_hash);
  1751. ecdh_key_free(nk->curve25519);
  1752. sfree(nk);
  1753. }
  1754. static bool ssh_ntru_server_getkey(ecdh_key *dh, ptrlen remoteKey,
  1755. BinarySink *bs)
  1756. {
  1757. ntru_server_key *nk = container_of(dh, ntru_server_key, ek);
  1758. /*
  1759. * In the server, getkey is called first, with the public
  1760. * information received from the client. We expect the client to
  1761. * have sent us a string containing a public key and a Curve25519
  1762. * public point.
  1763. */
  1764. BinarySource src[1];
  1765. BinarySource_BARE_INIT_PL(src, remoteKey);
  1766. { // WINSCP
  1767. uint16_t *pubkey = snewn(p_LIVE, uint16_t);
  1768. ntru_decode_pubkey(pubkey, p_LIVE, q_LIVE, src);
  1769. { // WINSCP
  1770. ptrlen curve25519_remoteKey = get_data(src, 32);
  1771. if (get_err(src) || get_avail(src)) {
  1772. /* Hard-fail if the input wasn't exactly the right length */
  1773. ring_free(pubkey, p_LIVE);
  1774. return false;
  1775. }
  1776. /*
  1777. * Main hash object which will combine the NTRU and Curve25519
  1778. * outputs.
  1779. */
  1780. { // WINSCP
  1781. ssh_hash *h = ssh_hash_new(&ssh_sha512);
  1782. /* Reusable buffer for storing various hash outputs. */
  1783. uint8_t hashdata[64];
  1784. /*
  1785. * NTRU side.
  1786. */
  1787. {
  1788. /* Encrypt the plaintext we generated at construction time,
  1789. * and encode the ciphertext into a strbuf so we can reuse it
  1790. * for both the session hash and sending to the client. */
  1791. uint16_t *ciphertext = snewn(p_LIVE, uint16_t);
  1792. ntru_encrypt(ciphertext, nk->plaintext, pubkey, p_LIVE, q_LIVE);
  1793. ntru_encode_ciphertext(ciphertext, p_LIVE, q_LIVE,
  1794. BinarySink_UPCAST(nk->ciphertext_encoded));
  1795. ring_free(ciphertext, p_LIVE);
  1796. /* Compute the confirmation hash, and write it into another
  1797. * strbuf. */
  1798. ntru_confirmation_hash(hashdata, nk->plaintext, pubkey,
  1799. p_LIVE, q_LIVE);
  1800. put_data(nk->confirmation_hash, hashdata, 32);
  1801. /* Compute the session hash (which is easy on the server side,
  1802. * requiring no conditional substitution). */
  1803. ntru_session_hash(hashdata, 1, nk->plaintext, p_LIVE,
  1804. ptrlen_from_strbuf(nk->ciphertext_encoded),
  1805. ptrlen_from_strbuf(nk->confirmation_hash));
  1806. /* And put the NTRU session hash into the main hash object. */
  1807. put_data(h, hashdata, 32);
  1808. /* Now we can free the public key */
  1809. ring_free(pubkey, p_LIVE);
  1810. }
  1811. /*
  1812. * Curve25519 side.
  1813. */
  1814. {
  1815. strbuf *otherkey = strbuf_new_nm();
  1816. /* Call out to Curve25519 to compute the shared secret from that
  1817. * kex method */
  1818. bool ok = ecdh_key_getkey(nk->curve25519, curve25519_remoteKey,
  1819. BinarySink_UPCAST(otherkey));
  1820. /* As on the client side, abort if Curve25519 reported failure */
  1821. if (!ok) {
  1822. ssh_hash_free(h);
  1823. smemclr(hashdata, sizeof(hashdata));
  1824. strbuf_free(otherkey);
  1825. return false;
  1826. }
  1827. /* As on the client side, decode Curve25519's mpint so we can
  1828. * re-encode it appropriately for our hash preimage */
  1829. { // WINSCP
  1830. BinarySource src[1];
  1831. BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(otherkey));
  1832. { // WINSCP
  1833. mp_int *curvekey = get_mp_ssh2(src);
  1834. { // WINSCP
  1835. unsigned i;
  1836. for (i = 32; i-- > 0 ;)
  1837. put_byte(h, mp_get_byte(curvekey, i));
  1838. } // WINSCP
  1839. mp_free(curvekey);
  1840. strbuf_free(otherkey);
  1841. } // WINSCP
  1842. } // WINSCP
  1843. }
  1844. /*
  1845. * Finish up: compute the final output hash (full 64 bytes of
  1846. * SHA-512 this time), and return it encoded as a string.
  1847. */
  1848. ssh_hash_final(h, hashdata);
  1849. put_stringpl(bs, make_ptrlen(hashdata, sizeof(hashdata)));
  1850. smemclr(hashdata, sizeof(hashdata));
  1851. return true;
  1852. } // WINSCP
  1853. } // WINSCP
  1854. } // WINSCP
  1855. }
  1856. static void ssh_ntru_server_getpublic(ecdh_key *dh, BinarySink *bs)
  1857. {
  1858. ntru_server_key *nk = container_of(dh, ntru_server_key, ek);
  1859. /*
  1860. * In the server, this function is called after getkey, so we
  1861. * already have all our pieces prepared. Just concatenate them all
  1862. * into the 'server's public data' string to go in ECDH_REPLY.
  1863. */
  1864. put_datapl(bs, ptrlen_from_strbuf(nk->ciphertext_encoded));
  1865. put_datapl(bs, ptrlen_from_strbuf(nk->confirmation_hash));
  1866. ecdh_key_getpublic(nk->curve25519, bs);
  1867. }
  1868. /* ----------------------------------------------------------------------
  1869. * Selector vtable that instantiates the appropriate one of the above,
  1870. * depending on is_server.
  1871. */
  1872. static ecdh_key *ssh_ntru_new(const ssh_kex *kex, bool is_server)
  1873. {
  1874. if (is_server)
  1875. return ssh_ntru_server_new();
  1876. else
  1877. return ssh_ntru_client_new();
  1878. }
  1879. static const ecdh_keyalg ssh_ntru_selector_vt = {
  1880. /* This is a never-instantiated vtable which only implements the
  1881. * functions that don't require an instance. */
  1882. /*.new =*/ ssh_ntru_new,
  1883. NULL, NULL, NULL, // WINSCP
  1884. /*.description =*/ ssh_ntru_description,
  1885. };
  1886. static const ssh_kex ssh_ntru_curve25519 = {
  1887. /*.name =*/ "[email protected]",
  1888. NULL, // WINSCP
  1889. /*.main_type =*/ KEXTYPE_ECDH,
  1890. /*.hash =*/ &ssh_sha512,
  1891. /*.ecdh_vt =*/ &ssh_ntru_selector_vt,
  1892. };
  1893. static const ssh_kex *const hybrid_list[] = {
  1894. &ssh_ntru_curve25519,
  1895. };
  1896. const ssh_kexes ssh_ntru_hybrid_kex = { lenof(hybrid_list), hybrid_list };