ntru.c 58 KB

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