sph_bmw.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. /* $Id: bmw.c 227 2010-06-16 17:28:38Z tp $ */
  2. /*
  3. * BMW implementation.
  4. *
  5. * ==========================(LICENSE BEGIN)============================
  6. *
  7. * Copyright (c) 2007-2010 Projet RNRT SAPHIR
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining
  10. * a copy of this software and associated documentation files (the
  11. * "Software"), to deal in the Software without restriction, including
  12. * without limitation the rights to use, copy, modify, merge, publish,
  13. * distribute, sublicense, and/or sell copies of the Software, and to
  14. * permit persons to whom the Software is furnished to do so, subject to
  15. * the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be
  18. * included in all copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. *
  28. * ===========================(LICENSE END)=============================
  29. *
  30. * @author Thomas Pornin <thomas.pornin@cryptolog.com>
  31. */
  32. #include <stddef.h>
  33. #include <string.h>
  34. #include <limits.h>
  35. #ifdef __cplusplus
  36. extern "C"{
  37. #endif
  38. #include "sph_bmw.h"
  39. #if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_BMW
  40. #define SPH_SMALL_FOOTPRINT_BMW 1
  41. #endif
  42. #ifdef _MSC_VER
  43. #pragma warning (disable: 4146)
  44. #endif
  45. static const sph_u32 IV224[] = {
  46. SPH_C32(0x00010203), SPH_C32(0x04050607),
  47. SPH_C32(0x08090A0B), SPH_C32(0x0C0D0E0F),
  48. SPH_C32(0x10111213), SPH_C32(0x14151617),
  49. SPH_C32(0x18191A1B), SPH_C32(0x1C1D1E1F),
  50. SPH_C32(0x20212223), SPH_C32(0x24252627),
  51. SPH_C32(0x28292A2B), SPH_C32(0x2C2D2E2F),
  52. SPH_C32(0x30313233), SPH_C32(0x34353637),
  53. SPH_C32(0x38393A3B), SPH_C32(0x3C3D3E3F)
  54. };
  55. static const sph_u32 IV256[] = {
  56. SPH_C32(0x40414243), SPH_C32(0x44454647),
  57. SPH_C32(0x48494A4B), SPH_C32(0x4C4D4E4F),
  58. SPH_C32(0x50515253), SPH_C32(0x54555657),
  59. SPH_C32(0x58595A5B), SPH_C32(0x5C5D5E5F),
  60. SPH_C32(0x60616263), SPH_C32(0x64656667),
  61. SPH_C32(0x68696A6B), SPH_C32(0x6C6D6E6F),
  62. SPH_C32(0x70717273), SPH_C32(0x74757677),
  63. SPH_C32(0x78797A7B), SPH_C32(0x7C7D7E7F)
  64. };
  65. #if SPH_64
  66. static const sph_u64 IV384[] = {
  67. SPH_C64(0x0001020304050607), SPH_C64(0x08090A0B0C0D0E0F),
  68. SPH_C64(0x1011121314151617), SPH_C64(0x18191A1B1C1D1E1F),
  69. SPH_C64(0x2021222324252627), SPH_C64(0x28292A2B2C2D2E2F),
  70. SPH_C64(0x3031323334353637), SPH_C64(0x38393A3B3C3D3E3F),
  71. SPH_C64(0x4041424344454647), SPH_C64(0x48494A4B4C4D4E4F),
  72. SPH_C64(0x5051525354555657), SPH_C64(0x58595A5B5C5D5E5F),
  73. SPH_C64(0x6061626364656667), SPH_C64(0x68696A6B6C6D6E6F),
  74. SPH_C64(0x7071727374757677), SPH_C64(0x78797A7B7C7D7E7F)
  75. };
  76. static const sph_u64 IV512[] = {
  77. SPH_C64(0x8081828384858687), SPH_C64(0x88898A8B8C8D8E8F),
  78. SPH_C64(0x9091929394959697), SPH_C64(0x98999A9B9C9D9E9F),
  79. SPH_C64(0xA0A1A2A3A4A5A6A7), SPH_C64(0xA8A9AAABACADAEAF),
  80. SPH_C64(0xB0B1B2B3B4B5B6B7), SPH_C64(0xB8B9BABBBCBDBEBF),
  81. SPH_C64(0xC0C1C2C3C4C5C6C7), SPH_C64(0xC8C9CACBCCCDCECF),
  82. SPH_C64(0xD0D1D2D3D4D5D6D7), SPH_C64(0xD8D9DADBDCDDDEDF),
  83. SPH_C64(0xE0E1E2E3E4E5E6E7), SPH_C64(0xE8E9EAEBECEDEEEF),
  84. SPH_C64(0xF0F1F2F3F4F5F6F7), SPH_C64(0xF8F9FAFBFCFDFEFF)
  85. };
  86. #endif
  87. #define XCAT(x, y) XCAT_(x, y)
  88. #define XCAT_(x, y) x ## y
  89. #define LPAR (
  90. #define I16_16 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
  91. #define I16_17 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
  92. #define I16_18 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
  93. #define I16_19 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
  94. #define I16_20 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
  95. #define I16_21 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
  96. #define I16_22 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
  97. #define I16_23 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
  98. #define I16_24 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
  99. #define I16_25 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
  100. #define I16_26 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25
  101. #define I16_27 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
  102. #define I16_28 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
  103. #define I16_29 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
  104. #define I16_30 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
  105. #define I16_31 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
  106. #define M16_16 0, 1, 3, 4, 7, 10, 11
  107. #define M16_17 1, 2, 4, 5, 8, 11, 12
  108. #define M16_18 2, 3, 5, 6, 9, 12, 13
  109. #define M16_19 3, 4, 6, 7, 10, 13, 14
  110. #define M16_20 4, 5, 7, 8, 11, 14, 15
  111. #define M16_21 5, 6, 8, 9, 12, 15, 16
  112. #define M16_22 6, 7, 9, 10, 13, 0, 1
  113. #define M16_23 7, 8, 10, 11, 14, 1, 2
  114. #define M16_24 8, 9, 11, 12, 15, 2, 3
  115. #define M16_25 9, 10, 12, 13, 0, 3, 4
  116. #define M16_26 10, 11, 13, 14, 1, 4, 5
  117. #define M16_27 11, 12, 14, 15, 2, 5, 6
  118. #define M16_28 12, 13, 15, 16, 3, 6, 7
  119. #define M16_29 13, 14, 0, 1, 4, 7, 8
  120. #define M16_30 14, 15, 1, 2, 5, 8, 9
  121. #define M16_31 15, 16, 2, 3, 6, 9, 10
  122. #define ss0(x) (((x) >> 1) ^ SPH_T32((x) << 3) \
  123. ^ SPH_ROTL32(x, 4) ^ SPH_ROTL32(x, 19))
  124. #define ss1(x) (((x) >> 1) ^ SPH_T32((x) << 2) \
  125. ^ SPH_ROTL32(x, 8) ^ SPH_ROTL32(x, 23))
  126. #define ss2(x) (((x) >> 2) ^ SPH_T32((x) << 1) \
  127. ^ SPH_ROTL32(x, 12) ^ SPH_ROTL32(x, 25))
  128. #define ss3(x) (((x) >> 2) ^ SPH_T32((x) << 2) \
  129. ^ SPH_ROTL32(x, 15) ^ SPH_ROTL32(x, 29))
  130. #define ss4(x) (((x) >> 1) ^ (x))
  131. #define ss5(x) (((x) >> 2) ^ (x))
  132. #define rs1(x) SPH_ROTL32(x, 3)
  133. #define rs2(x) SPH_ROTL32(x, 7)
  134. #define rs3(x) SPH_ROTL32(x, 13)
  135. #define rs4(x) SPH_ROTL32(x, 16)
  136. #define rs5(x) SPH_ROTL32(x, 19)
  137. #define rs6(x) SPH_ROTL32(x, 23)
  138. #define rs7(x) SPH_ROTL32(x, 27)
  139. #define Ks(j) SPH_T32((sph_u32)(j) * SPH_C32(0x05555555))
  140. #define add_elt_s(mf, hf, j0m, j1m, j3m, j4m, j7m, j10m, j11m, j16) \
  141. (SPH_T32(SPH_ROTL32(mf(j0m), j1m) + SPH_ROTL32(mf(j3m), j4m) \
  142. - SPH_ROTL32(mf(j10m), j11m) + Ks(j16)) ^ hf(j7m))
  143. #define expand1s_inner(qf, mf, hf, i16, \
  144. i0, i1, i2, i3, i4, i5, i6, i7, i8, \
  145. i9, i10, i11, i12, i13, i14, i15, \
  146. i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
  147. SPH_T32(ss1(qf(i0)) + ss2(qf(i1)) + ss3(qf(i2)) + ss0(qf(i3)) \
  148. + ss1(qf(i4)) + ss2(qf(i5)) + ss3(qf(i6)) + ss0(qf(i7)) \
  149. + ss1(qf(i8)) + ss2(qf(i9)) + ss3(qf(i10)) + ss0(qf(i11)) \
  150. + ss1(qf(i12)) + ss2(qf(i13)) + ss3(qf(i14)) + ss0(qf(i15)) \
  151. + add_elt_s(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
  152. #define expand1s(qf, mf, hf, i16) \
  153. expand1s_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
  154. #define expand1s_(qf, mf, hf, i16, ix, iy) \
  155. expand1s_inner LPAR qf, mf, hf, i16, ix, iy)
  156. #define expand2s_inner(qf, mf, hf, i16, \
  157. i0, i1, i2, i3, i4, i5, i6, i7, i8, \
  158. i9, i10, i11, i12, i13, i14, i15, \
  159. i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
  160. SPH_T32(qf(i0) + rs1(qf(i1)) + qf(i2) + rs2(qf(i3)) \
  161. + qf(i4) + rs3(qf(i5)) + qf(i6) + rs4(qf(i7)) \
  162. + qf(i8) + rs5(qf(i9)) + qf(i10) + rs6(qf(i11)) \
  163. + qf(i12) + rs7(qf(i13)) + ss4(qf(i14)) + ss5(qf(i15)) \
  164. + add_elt_s(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
  165. #define expand2s(qf, mf, hf, i16) \
  166. expand2s_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
  167. #define expand2s_(qf, mf, hf, i16, ix, iy) \
  168. expand2s_inner LPAR qf, mf, hf, i16, ix, iy)
  169. #if SPH_64
  170. #define sb0(x) (((x) >> 1) ^ SPH_T64((x) << 3) \
  171. ^ SPH_ROTL64(x, 4) ^ SPH_ROTL64(x, 37))
  172. #define sb1(x) (((x) >> 1) ^ SPH_T64((x) << 2) \
  173. ^ SPH_ROTL64(x, 13) ^ SPH_ROTL64(x, 43))
  174. #define sb2(x) (((x) >> 2) ^ SPH_T64((x) << 1) \
  175. ^ SPH_ROTL64(x, 19) ^ SPH_ROTL64(x, 53))
  176. #define sb3(x) (((x) >> 2) ^ SPH_T64((x) << 2) \
  177. ^ SPH_ROTL64(x, 28) ^ SPH_ROTL64(x, 59))
  178. #define sb4(x) (((x) >> 1) ^ (x))
  179. #define sb5(x) (((x) >> 2) ^ (x))
  180. #define rb1(x) SPH_ROTL64(x, 5)
  181. #define rb2(x) SPH_ROTL64(x, 11)
  182. #define rb3(x) SPH_ROTL64(x, 27)
  183. #define rb4(x) SPH_ROTL64(x, 32)
  184. #define rb5(x) SPH_ROTL64(x, 37)
  185. #define rb6(x) SPH_ROTL64(x, 43)
  186. #define rb7(x) SPH_ROTL64(x, 53)
  187. #define Kb(j) SPH_T64((sph_u64)(j) * SPH_C64(0x0555555555555555))
  188. #if SPH_SMALL_FOOTPRINT_BMW
  189. static const sph_u64 Kb_tab[] = {
  190. Kb(16), Kb(17), Kb(18), Kb(19), Kb(20), Kb(21), Kb(22), Kb(23),
  191. Kb(24), Kb(25), Kb(26), Kb(27), Kb(28), Kb(29), Kb(30), Kb(31)
  192. };
  193. #define rol_off(mf, j, off) \
  194. SPH_ROTL64(mf(((j) + (off)) & 15), (((j) + (off)) & 15) + 1)
  195. #define add_elt_b(mf, hf, j) \
  196. (SPH_T64(rol_off(mf, j, 0) + rol_off(mf, j, 3) \
  197. - rol_off(mf, j, 10) + Kb_tab[j]) ^ hf(((j) + 7) & 15))
  198. #define expand1b(qf, mf, hf, i) \
  199. SPH_T64(sb1(qf((i) - 16)) + sb2(qf((i) - 15)) \
  200. + sb3(qf((i) - 14)) + sb0(qf((i) - 13)) \
  201. + sb1(qf((i) - 12)) + sb2(qf((i) - 11)) \
  202. + sb3(qf((i) - 10)) + sb0(qf((i) - 9)) \
  203. + sb1(qf((i) - 8)) + sb2(qf((i) - 7)) \
  204. + sb3(qf((i) - 6)) + sb0(qf((i) - 5)) \
  205. + sb1(qf((i) - 4)) + sb2(qf((i) - 3)) \
  206. + sb3(qf((i) - 2)) + sb0(qf((i) - 1)) \
  207. + add_elt_b(mf, hf, (i) - 16))
  208. #define expand2b(qf, mf, hf, i) \
  209. SPH_T64(qf((i) - 16) + rb1(qf((i) - 15)) \
  210. + qf((i) - 14) + rb2(qf((i) - 13)) \
  211. + qf((i) - 12) + rb3(qf((i) - 11)) \
  212. + qf((i) - 10) + rb4(qf((i) - 9)) \
  213. + qf((i) - 8) + rb5(qf((i) - 7)) \
  214. + qf((i) - 6) + rb6(qf((i) - 5)) \
  215. + qf((i) - 4) + rb7(qf((i) - 3)) \
  216. + sb4(qf((i) - 2)) + sb5(qf((i) - 1)) \
  217. + add_elt_b(mf, hf, (i) - 16))
  218. #else
  219. #define add_elt_b(mf, hf, j0m, j1m, j3m, j4m, j7m, j10m, j11m, j16) \
  220. (SPH_T64(SPH_ROTL64(mf(j0m), j1m) + SPH_ROTL64(mf(j3m), j4m) \
  221. - SPH_ROTL64(mf(j10m), j11m) + Kb(j16)) ^ hf(j7m))
  222. #define expand1b_inner(qf, mf, hf, i16, \
  223. i0, i1, i2, i3, i4, i5, i6, i7, i8, \
  224. i9, i10, i11, i12, i13, i14, i15, \
  225. i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
  226. SPH_T64(sb1(qf(i0)) + sb2(qf(i1)) + sb3(qf(i2)) + sb0(qf(i3)) \
  227. + sb1(qf(i4)) + sb2(qf(i5)) + sb3(qf(i6)) + sb0(qf(i7)) \
  228. + sb1(qf(i8)) + sb2(qf(i9)) + sb3(qf(i10)) + sb0(qf(i11)) \
  229. + sb1(qf(i12)) + sb2(qf(i13)) + sb3(qf(i14)) + sb0(qf(i15)) \
  230. + add_elt_b(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
  231. #define expand1b(qf, mf, hf, i16) \
  232. expand1b_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
  233. #define expand1b_(qf, mf, hf, i16, ix, iy) \
  234. expand1b_inner LPAR qf, mf, hf, i16, ix, iy)
  235. #define expand2b_inner(qf, mf, hf, i16, \
  236. i0, i1, i2, i3, i4, i5, i6, i7, i8, \
  237. i9, i10, i11, i12, i13, i14, i15, \
  238. i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
  239. SPH_T64(qf(i0) + rb1(qf(i1)) + qf(i2) + rb2(qf(i3)) \
  240. + qf(i4) + rb3(qf(i5)) + qf(i6) + rb4(qf(i7)) \
  241. + qf(i8) + rb5(qf(i9)) + qf(i10) + rb6(qf(i11)) \
  242. + qf(i12) + rb7(qf(i13)) + sb4(qf(i14)) + sb5(qf(i15)) \
  243. + add_elt_b(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
  244. #define expand2b(qf, mf, hf, i16) \
  245. expand2b_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
  246. #define expand2b_(qf, mf, hf, i16, ix, iy) \
  247. expand2b_inner LPAR qf, mf, hf, i16, ix, iy)
  248. #endif
  249. #endif
  250. #define MAKE_W(tt, i0, op01, i1, op12, i2, op23, i3, op34, i4) \
  251. tt((M(i0) ^ H(i0)) op01 (M(i1) ^ H(i1)) op12 (M(i2) ^ H(i2)) \
  252. op23 (M(i3) ^ H(i3)) op34 (M(i4) ^ H(i4)))
  253. #define Ws0 MAKE_W(SPH_T32, 5, -, 7, +, 10, +, 13, +, 14)
  254. #define Ws1 MAKE_W(SPH_T32, 6, -, 8, +, 11, +, 14, -, 15)
  255. #define Ws2 MAKE_W(SPH_T32, 0, +, 7, +, 9, -, 12, +, 15)
  256. #define Ws3 MAKE_W(SPH_T32, 0, -, 1, +, 8, -, 10, +, 13)
  257. #define Ws4 MAKE_W(SPH_T32, 1, +, 2, +, 9, -, 11, -, 14)
  258. #define Ws5 MAKE_W(SPH_T32, 3, -, 2, +, 10, -, 12, +, 15)
  259. #define Ws6 MAKE_W(SPH_T32, 4, -, 0, -, 3, -, 11, +, 13)
  260. #define Ws7 MAKE_W(SPH_T32, 1, -, 4, -, 5, -, 12, -, 14)
  261. #define Ws8 MAKE_W(SPH_T32, 2, -, 5, -, 6, +, 13, -, 15)
  262. #define Ws9 MAKE_W(SPH_T32, 0, -, 3, +, 6, -, 7, +, 14)
  263. #define Ws10 MAKE_W(SPH_T32, 8, -, 1, -, 4, -, 7, +, 15)
  264. #define Ws11 MAKE_W(SPH_T32, 8, -, 0, -, 2, -, 5, +, 9)
  265. #define Ws12 MAKE_W(SPH_T32, 1, +, 3, -, 6, -, 9, +, 10)
  266. #define Ws13 MAKE_W(SPH_T32, 2, +, 4, +, 7, +, 10, +, 11)
  267. #define Ws14 MAKE_W(SPH_T32, 3, -, 5, +, 8, -, 11, -, 12)
  268. #define Ws15 MAKE_W(SPH_T32, 12, -, 4, -, 6, -, 9, +, 13)
  269. #if SPH_SMALL_FOOTPRINT_BMW
  270. #define MAKE_Qas do { \
  271. unsigned u; \
  272. sph_u32 Ws[16]; \
  273. Ws[ 0] = Ws0; \
  274. Ws[ 1] = Ws1; \
  275. Ws[ 2] = Ws2; \
  276. Ws[ 3] = Ws3; \
  277. Ws[ 4] = Ws4; \
  278. Ws[ 5] = Ws5; \
  279. Ws[ 6] = Ws6; \
  280. Ws[ 7] = Ws7; \
  281. Ws[ 8] = Ws8; \
  282. Ws[ 9] = Ws9; \
  283. Ws[10] = Ws10; \
  284. Ws[11] = Ws11; \
  285. Ws[12] = Ws12; \
  286. Ws[13] = Ws13; \
  287. Ws[14] = Ws14; \
  288. Ws[15] = Ws15; \
  289. for (u = 0; u < 15; u += 5) { \
  290. qt[u + 0] = SPH_T32(ss0(Ws[u + 0]) + H(u + 1)); \
  291. qt[u + 1] = SPH_T32(ss1(Ws[u + 1]) + H(u + 2)); \
  292. qt[u + 2] = SPH_T32(ss2(Ws[u + 2]) + H(u + 3)); \
  293. qt[u + 3] = SPH_T32(ss3(Ws[u + 3]) + H(u + 4)); \
  294. qt[u + 4] = SPH_T32(ss4(Ws[u + 4]) + H(u + 5)); \
  295. } \
  296. qt[15] = SPH_T32(ss0(Ws[15]) + H(0)); \
  297. } while (0)
  298. #define MAKE_Qbs do { \
  299. qt[16] = expand1s(Qs, M, H, 16); \
  300. qt[17] = expand1s(Qs, M, H, 17); \
  301. qt[18] = expand2s(Qs, M, H, 18); \
  302. qt[19] = expand2s(Qs, M, H, 19); \
  303. qt[20] = expand2s(Qs, M, H, 20); \
  304. qt[21] = expand2s(Qs, M, H, 21); \
  305. qt[22] = expand2s(Qs, M, H, 22); \
  306. qt[23] = expand2s(Qs, M, H, 23); \
  307. qt[24] = expand2s(Qs, M, H, 24); \
  308. qt[25] = expand2s(Qs, M, H, 25); \
  309. qt[26] = expand2s(Qs, M, H, 26); \
  310. qt[27] = expand2s(Qs, M, H, 27); \
  311. qt[28] = expand2s(Qs, M, H, 28); \
  312. qt[29] = expand2s(Qs, M, H, 29); \
  313. qt[30] = expand2s(Qs, M, H, 30); \
  314. qt[31] = expand2s(Qs, M, H, 31); \
  315. } while (0)
  316. #else
  317. #define MAKE_Qas do { \
  318. qt[ 0] = SPH_T32(ss0(Ws0 ) + H( 1)); \
  319. qt[ 1] = SPH_T32(ss1(Ws1 ) + H( 2)); \
  320. qt[ 2] = SPH_T32(ss2(Ws2 ) + H( 3)); \
  321. qt[ 3] = SPH_T32(ss3(Ws3 ) + H( 4)); \
  322. qt[ 4] = SPH_T32(ss4(Ws4 ) + H( 5)); \
  323. qt[ 5] = SPH_T32(ss0(Ws5 ) + H( 6)); \
  324. qt[ 6] = SPH_T32(ss1(Ws6 ) + H( 7)); \
  325. qt[ 7] = SPH_T32(ss2(Ws7 ) + H( 8)); \
  326. qt[ 8] = SPH_T32(ss3(Ws8 ) + H( 9)); \
  327. qt[ 9] = SPH_T32(ss4(Ws9 ) + H(10)); \
  328. qt[10] = SPH_T32(ss0(Ws10) + H(11)); \
  329. qt[11] = SPH_T32(ss1(Ws11) + H(12)); \
  330. qt[12] = SPH_T32(ss2(Ws12) + H(13)); \
  331. qt[13] = SPH_T32(ss3(Ws13) + H(14)); \
  332. qt[14] = SPH_T32(ss4(Ws14) + H(15)); \
  333. qt[15] = SPH_T32(ss0(Ws15) + H( 0)); \
  334. } while (0)
  335. #define MAKE_Qbs do { \
  336. qt[16] = expand1s(Qs, M, H, 16); \
  337. qt[17] = expand1s(Qs, M, H, 17); \
  338. qt[18] = expand2s(Qs, M, H, 18); \
  339. qt[19] = expand2s(Qs, M, H, 19); \
  340. qt[20] = expand2s(Qs, M, H, 20); \
  341. qt[21] = expand2s(Qs, M, H, 21); \
  342. qt[22] = expand2s(Qs, M, H, 22); \
  343. qt[23] = expand2s(Qs, M, H, 23); \
  344. qt[24] = expand2s(Qs, M, H, 24); \
  345. qt[25] = expand2s(Qs, M, H, 25); \
  346. qt[26] = expand2s(Qs, M, H, 26); \
  347. qt[27] = expand2s(Qs, M, H, 27); \
  348. qt[28] = expand2s(Qs, M, H, 28); \
  349. qt[29] = expand2s(Qs, M, H, 29); \
  350. qt[30] = expand2s(Qs, M, H, 30); \
  351. qt[31] = expand2s(Qs, M, H, 31); \
  352. } while (0)
  353. #endif
  354. #define MAKE_Qs do { \
  355. MAKE_Qas; \
  356. MAKE_Qbs; \
  357. } while (0)
  358. #define Qs(j) (qt[j])
  359. #if SPH_64
  360. #define Wb0 MAKE_W(SPH_T64, 5, -, 7, +, 10, +, 13, +, 14)
  361. #define Wb1 MAKE_W(SPH_T64, 6, -, 8, +, 11, +, 14, -, 15)
  362. #define Wb2 MAKE_W(SPH_T64, 0, +, 7, +, 9, -, 12, +, 15)
  363. #define Wb3 MAKE_W(SPH_T64, 0, -, 1, +, 8, -, 10, +, 13)
  364. #define Wb4 MAKE_W(SPH_T64, 1, +, 2, +, 9, -, 11, -, 14)
  365. #define Wb5 MAKE_W(SPH_T64, 3, -, 2, +, 10, -, 12, +, 15)
  366. #define Wb6 MAKE_W(SPH_T64, 4, -, 0, -, 3, -, 11, +, 13)
  367. #define Wb7 MAKE_W(SPH_T64, 1, -, 4, -, 5, -, 12, -, 14)
  368. #define Wb8 MAKE_W(SPH_T64, 2, -, 5, -, 6, +, 13, -, 15)
  369. #define Wb9 MAKE_W(SPH_T64, 0, -, 3, +, 6, -, 7, +, 14)
  370. #define Wb10 MAKE_W(SPH_T64, 8, -, 1, -, 4, -, 7, +, 15)
  371. #define Wb11 MAKE_W(SPH_T64, 8, -, 0, -, 2, -, 5, +, 9)
  372. #define Wb12 MAKE_W(SPH_T64, 1, +, 3, -, 6, -, 9, +, 10)
  373. #define Wb13 MAKE_W(SPH_T64, 2, +, 4, +, 7, +, 10, +, 11)
  374. #define Wb14 MAKE_W(SPH_T64, 3, -, 5, +, 8, -, 11, -, 12)
  375. #define Wb15 MAKE_W(SPH_T64, 12, -, 4, -, 6, -, 9, +, 13)
  376. #if SPH_SMALL_FOOTPRINT_BMW
  377. #define MAKE_Qab do { \
  378. unsigned u; \
  379. sph_u64 Wb[16]; \
  380. Wb[ 0] = Wb0; \
  381. Wb[ 1] = Wb1; \
  382. Wb[ 2] = Wb2; \
  383. Wb[ 3] = Wb3; \
  384. Wb[ 4] = Wb4; \
  385. Wb[ 5] = Wb5; \
  386. Wb[ 6] = Wb6; \
  387. Wb[ 7] = Wb7; \
  388. Wb[ 8] = Wb8; \
  389. Wb[ 9] = Wb9; \
  390. Wb[10] = Wb10; \
  391. Wb[11] = Wb11; \
  392. Wb[12] = Wb12; \
  393. Wb[13] = Wb13; \
  394. Wb[14] = Wb14; \
  395. Wb[15] = Wb15; \
  396. for (u = 0; u < 15; u += 5) { \
  397. qt[u + 0] = SPH_T64(sb0(Wb[u + 0]) + H(u + 1)); \
  398. qt[u + 1] = SPH_T64(sb1(Wb[u + 1]) + H(u + 2)); \
  399. qt[u + 2] = SPH_T64(sb2(Wb[u + 2]) + H(u + 3)); \
  400. qt[u + 3] = SPH_T64(sb3(Wb[u + 3]) + H(u + 4)); \
  401. qt[u + 4] = SPH_T64(sb4(Wb[u + 4]) + H(u + 5)); \
  402. } \
  403. qt[15] = SPH_T64(sb0(Wb[15]) + H(0)); \
  404. } while (0)
  405. #define MAKE_Qbb do { \
  406. unsigned u; \
  407. for (u = 16; u < 18; u ++) \
  408. qt[u] = expand1b(Qb, M, H, u); \
  409. for (u = 18; u < 32; u ++) \
  410. qt[u] = expand2b(Qb, M, H, u); \
  411. } while (0)
  412. #else
  413. #define MAKE_Qab do { \
  414. qt[ 0] = SPH_T64(sb0(Wb0 ) + H( 1)); \
  415. qt[ 1] = SPH_T64(sb1(Wb1 ) + H( 2)); \
  416. qt[ 2] = SPH_T64(sb2(Wb2 ) + H( 3)); \
  417. qt[ 3] = SPH_T64(sb3(Wb3 ) + H( 4)); \
  418. qt[ 4] = SPH_T64(sb4(Wb4 ) + H( 5)); \
  419. qt[ 5] = SPH_T64(sb0(Wb5 ) + H( 6)); \
  420. qt[ 6] = SPH_T64(sb1(Wb6 ) + H( 7)); \
  421. qt[ 7] = SPH_T64(sb2(Wb7 ) + H( 8)); \
  422. qt[ 8] = SPH_T64(sb3(Wb8 ) + H( 9)); \
  423. qt[ 9] = SPH_T64(sb4(Wb9 ) + H(10)); \
  424. qt[10] = SPH_T64(sb0(Wb10) + H(11)); \
  425. qt[11] = SPH_T64(sb1(Wb11) + H(12)); \
  426. qt[12] = SPH_T64(sb2(Wb12) + H(13)); \
  427. qt[13] = SPH_T64(sb3(Wb13) + H(14)); \
  428. qt[14] = SPH_T64(sb4(Wb14) + H(15)); \
  429. qt[15] = SPH_T64(sb0(Wb15) + H( 0)); \
  430. } while (0)
  431. #define MAKE_Qbb do { \
  432. qt[16] = expand1b(Qb, M, H, 16); \
  433. qt[17] = expand1b(Qb, M, H, 17); \
  434. qt[18] = expand2b(Qb, M, H, 18); \
  435. qt[19] = expand2b(Qb, M, H, 19); \
  436. qt[20] = expand2b(Qb, M, H, 20); \
  437. qt[21] = expand2b(Qb, M, H, 21); \
  438. qt[22] = expand2b(Qb, M, H, 22); \
  439. qt[23] = expand2b(Qb, M, H, 23); \
  440. qt[24] = expand2b(Qb, M, H, 24); \
  441. qt[25] = expand2b(Qb, M, H, 25); \
  442. qt[26] = expand2b(Qb, M, H, 26); \
  443. qt[27] = expand2b(Qb, M, H, 27); \
  444. qt[28] = expand2b(Qb, M, H, 28); \
  445. qt[29] = expand2b(Qb, M, H, 29); \
  446. qt[30] = expand2b(Qb, M, H, 30); \
  447. qt[31] = expand2b(Qb, M, H, 31); \
  448. } while (0)
  449. #endif
  450. #define MAKE_Qb do { \
  451. MAKE_Qab; \
  452. MAKE_Qbb; \
  453. } while (0)
  454. #define Qb(j) (qt[j])
  455. #endif
  456. #define FOLD(type, mkQ, tt, rol, mf, qf, dhf) do { \
  457. type qt[32], xl, xh; \
  458. mkQ; \
  459. xl = qf(16) ^ qf(17) ^ qf(18) ^ qf(19) \
  460. ^ qf(20) ^ qf(21) ^ qf(22) ^ qf(23); \
  461. xh = xl ^ qf(24) ^ qf(25) ^ qf(26) ^ qf(27) \
  462. ^ qf(28) ^ qf(29) ^ qf(30) ^ qf(31); \
  463. dhf( 0) = tt(((xh << 5) ^ (qf(16) >> 5) ^ mf( 0)) \
  464. + (xl ^ qf(24) ^ qf( 0))); \
  465. dhf( 1) = tt(((xh >> 7) ^ (qf(17) << 8) ^ mf( 1)) \
  466. + (xl ^ qf(25) ^ qf( 1))); \
  467. dhf( 2) = tt(((xh >> 5) ^ (qf(18) << 5) ^ mf( 2)) \
  468. + (xl ^ qf(26) ^ qf( 2))); \
  469. dhf( 3) = tt(((xh >> 1) ^ (qf(19) << 5) ^ mf( 3)) \
  470. + (xl ^ qf(27) ^ qf( 3))); \
  471. dhf( 4) = tt(((xh >> 3) ^ (qf(20) << 0) ^ mf( 4)) \
  472. + (xl ^ qf(28) ^ qf( 4))); \
  473. dhf( 5) = tt(((xh << 6) ^ (qf(21) >> 6) ^ mf( 5)) \
  474. + (xl ^ qf(29) ^ qf( 5))); \
  475. dhf( 6) = tt(((xh >> 4) ^ (qf(22) << 6) ^ mf( 6)) \
  476. + (xl ^ qf(30) ^ qf( 6))); \
  477. dhf( 7) = tt(((xh >> 11) ^ (qf(23) << 2) ^ mf( 7)) \
  478. + (xl ^ qf(31) ^ qf( 7))); \
  479. dhf( 8) = tt(rol(dhf(4), 9) + (xh ^ qf(24) ^ mf( 8)) \
  480. + ((xl << 8) ^ qf(23) ^ qf( 8))); \
  481. dhf( 9) = tt(rol(dhf(5), 10) + (xh ^ qf(25) ^ mf( 9)) \
  482. + ((xl >> 6) ^ qf(16) ^ qf( 9))); \
  483. dhf(10) = tt(rol(dhf(6), 11) + (xh ^ qf(26) ^ mf(10)) \
  484. + ((xl << 6) ^ qf(17) ^ qf(10))); \
  485. dhf(11) = tt(rol(dhf(7), 12) + (xh ^ qf(27) ^ mf(11)) \
  486. + ((xl << 4) ^ qf(18) ^ qf(11))); \
  487. dhf(12) = tt(rol(dhf(0), 13) + (xh ^ qf(28) ^ mf(12)) \
  488. + ((xl >> 3) ^ qf(19) ^ qf(12))); \
  489. dhf(13) = tt(rol(dhf(1), 14) + (xh ^ qf(29) ^ mf(13)) \
  490. + ((xl >> 4) ^ qf(20) ^ qf(13))); \
  491. dhf(14) = tt(rol(dhf(2), 15) + (xh ^ qf(30) ^ mf(14)) \
  492. + ((xl >> 7) ^ qf(21) ^ qf(14))); \
  493. dhf(15) = tt(rol(dhf(3), 16) + (xh ^ qf(31) ^ mf(15)) \
  494. + ((xl >> 2) ^ qf(22) ^ qf(15))); \
  495. } while (0)
  496. #define FOLDs FOLD(sph_u32, MAKE_Qs, SPH_T32, SPH_ROTL32, M, Qs, dH)
  497. #if SPH_64
  498. #define FOLDb FOLD(sph_u64, MAKE_Qb, SPH_T64, SPH_ROTL64, M, Qb, dH)
  499. #endif
  500. static void
  501. compress_small(const unsigned char *data, const sph_u32 h[16], sph_u32 dh[16])
  502. {
  503. #if SPH_LITTLE_FAST
  504. #define M(x) sph_dec32le_aligned(data + 4 * (x))
  505. #else
  506. sph_u32 mv[16];
  507. mv[ 0] = sph_dec32le_aligned(data + 0);
  508. mv[ 1] = sph_dec32le_aligned(data + 4);
  509. mv[ 2] = sph_dec32le_aligned(data + 8);
  510. mv[ 3] = sph_dec32le_aligned(data + 12);
  511. mv[ 4] = sph_dec32le_aligned(data + 16);
  512. mv[ 5] = sph_dec32le_aligned(data + 20);
  513. mv[ 6] = sph_dec32le_aligned(data + 24);
  514. mv[ 7] = sph_dec32le_aligned(data + 28);
  515. mv[ 8] = sph_dec32le_aligned(data + 32);
  516. mv[ 9] = sph_dec32le_aligned(data + 36);
  517. mv[10] = sph_dec32le_aligned(data + 40);
  518. mv[11] = sph_dec32le_aligned(data + 44);
  519. mv[12] = sph_dec32le_aligned(data + 48);
  520. mv[13] = sph_dec32le_aligned(data + 52);
  521. mv[14] = sph_dec32le_aligned(data + 56);
  522. mv[15] = sph_dec32le_aligned(data + 60);
  523. #define M(x) (mv[x])
  524. #endif
  525. #define H(x) (h[x])
  526. #define dH(x) (dh[x])
  527. FOLDs;
  528. #undef M
  529. #undef H
  530. #undef dH
  531. }
  532. static const sph_u32 final_s[16] = {
  533. SPH_C32(0xaaaaaaa0), SPH_C32(0xaaaaaaa1), SPH_C32(0xaaaaaaa2),
  534. SPH_C32(0xaaaaaaa3), SPH_C32(0xaaaaaaa4), SPH_C32(0xaaaaaaa5),
  535. SPH_C32(0xaaaaaaa6), SPH_C32(0xaaaaaaa7), SPH_C32(0xaaaaaaa8),
  536. SPH_C32(0xaaaaaaa9), SPH_C32(0xaaaaaaaa), SPH_C32(0xaaaaaaab),
  537. SPH_C32(0xaaaaaaac), SPH_C32(0xaaaaaaad), SPH_C32(0xaaaaaaae),
  538. SPH_C32(0xaaaaaaaf)
  539. };
  540. static void
  541. bmw32_init(sph_bmw_small_context *sc, const sph_u32 *iv)
  542. {
  543. memcpy(sc->H, iv, sizeof sc->H);
  544. sc->ptr = 0;
  545. #if SPH_64
  546. sc->bit_count = 0;
  547. #else
  548. sc->bit_count_high = 0;
  549. sc->bit_count_low = 0;
  550. #endif
  551. }
  552. static void
  553. bmw32(sph_bmw_small_context *sc, const void *data, size_t len)
  554. {
  555. unsigned char *buf;
  556. size_t ptr;
  557. sph_u32 htmp[16];
  558. sph_u32 *h1, *h2;
  559. #if !SPH_64
  560. sph_u32 tmp;
  561. #endif
  562. #if SPH_64
  563. sc->bit_count += (sph_u64)len << 3;
  564. #else
  565. tmp = sc->bit_count_low;
  566. sc->bit_count_low = SPH_T32(tmp + ((sph_u32)len << 3));
  567. if (sc->bit_count_low < tmp)
  568. sc->bit_count_high ++;
  569. sc->bit_count_high += len >> 29;
  570. #endif
  571. buf = sc->buf;
  572. ptr = sc->ptr;
  573. h1 = sc->H;
  574. h2 = htmp;
  575. while (len > 0) {
  576. size_t clen;
  577. clen = (sizeof sc->buf) - ptr;
  578. if (clen > len)
  579. clen = len;
  580. memcpy(buf + ptr, data, clen);
  581. data = (const unsigned char *)data + clen;
  582. len -= clen;
  583. ptr += clen;
  584. if (ptr == sizeof sc->buf) {
  585. sph_u32 *ht;
  586. compress_small(buf, h1, h2);
  587. ht = h1;
  588. h1 = h2;
  589. h2 = ht;
  590. ptr = 0;
  591. }
  592. }
  593. sc->ptr = ptr;
  594. if (h1 != sc->H)
  595. memcpy(sc->H, h1, sizeof sc->H);
  596. }
  597. static void
  598. bmw32_close(sph_bmw_small_context *sc, unsigned ub, unsigned n,
  599. void *dst, size_t out_size_w32)
  600. {
  601. unsigned char *buf, *out;
  602. size_t ptr, u, v;
  603. unsigned z;
  604. sph_u32 h1[16], h2[16], *h;
  605. buf = sc->buf;
  606. ptr = sc->ptr;
  607. z = 0x80 >> n;
  608. buf[ptr ++] = ((ub & -z) | z) & 0xFF;
  609. h = sc->H;
  610. if (ptr > (sizeof sc->buf) - 8) {
  611. memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
  612. compress_small(buf, h, h1);
  613. ptr = 0;
  614. h = h1;
  615. }
  616. memset(buf + ptr, 0, (sizeof sc->buf) - 8 - ptr);
  617. #if SPH_64
  618. sph_enc64le_aligned(buf + (sizeof sc->buf) - 8,
  619. SPH_T64(sc->bit_count + n));
  620. #else
  621. sph_enc32le_aligned(buf + (sizeof sc->buf) - 8,
  622. sc->bit_count_low + n);
  623. sph_enc32le_aligned(buf + (sizeof sc->buf) - 4,
  624. SPH_T32(sc->bit_count_high));
  625. #endif
  626. compress_small(buf, h, h2);
  627. for (u = 0; u < 16; u ++)
  628. sph_enc32le_aligned(buf + 4 * u, h2[u]);
  629. compress_small(buf, final_s, h1);
  630. out = dst;
  631. for (u = 0, v = 16 - out_size_w32; u < out_size_w32; u ++, v ++)
  632. sph_enc32le(out + 4 * u, h1[v]);
  633. }
  634. #if SPH_64
  635. static void
  636. compress_big(const unsigned char *data, const sph_u64 h[16], sph_u64 dh[16])
  637. {
  638. #if SPH_LITTLE_FAST
  639. #define M(x) sph_dec64le_aligned(data + 8 * (x))
  640. #else
  641. sph_u64 mv[16];
  642. mv[ 0] = sph_dec64le_aligned(data + 0);
  643. mv[ 1] = sph_dec64le_aligned(data + 8);
  644. mv[ 2] = sph_dec64le_aligned(data + 16);
  645. mv[ 3] = sph_dec64le_aligned(data + 24);
  646. mv[ 4] = sph_dec64le_aligned(data + 32);
  647. mv[ 5] = sph_dec64le_aligned(data + 40);
  648. mv[ 6] = sph_dec64le_aligned(data + 48);
  649. mv[ 7] = sph_dec64le_aligned(data + 56);
  650. mv[ 8] = sph_dec64le_aligned(data + 64);
  651. mv[ 9] = sph_dec64le_aligned(data + 72);
  652. mv[10] = sph_dec64le_aligned(data + 80);
  653. mv[11] = sph_dec64le_aligned(data + 88);
  654. mv[12] = sph_dec64le_aligned(data + 96);
  655. mv[13] = sph_dec64le_aligned(data + 104);
  656. mv[14] = sph_dec64le_aligned(data + 112);
  657. mv[15] = sph_dec64le_aligned(data + 120);
  658. #define M(x) (mv[x])
  659. #endif
  660. #define H(x) (h[x])
  661. #define dH(x) (dh[x])
  662. FOLDb;
  663. #undef M
  664. #undef H
  665. #undef dH
  666. }
  667. static const sph_u64 final_b[16] = {
  668. SPH_C64(0xaaaaaaaaaaaaaaa0), SPH_C64(0xaaaaaaaaaaaaaaa1),
  669. SPH_C64(0xaaaaaaaaaaaaaaa2), SPH_C64(0xaaaaaaaaaaaaaaa3),
  670. SPH_C64(0xaaaaaaaaaaaaaaa4), SPH_C64(0xaaaaaaaaaaaaaaa5),
  671. SPH_C64(0xaaaaaaaaaaaaaaa6), SPH_C64(0xaaaaaaaaaaaaaaa7),
  672. SPH_C64(0xaaaaaaaaaaaaaaa8), SPH_C64(0xaaaaaaaaaaaaaaa9),
  673. SPH_C64(0xaaaaaaaaaaaaaaaa), SPH_C64(0xaaaaaaaaaaaaaaab),
  674. SPH_C64(0xaaaaaaaaaaaaaaac), SPH_C64(0xaaaaaaaaaaaaaaad),
  675. SPH_C64(0xaaaaaaaaaaaaaaae), SPH_C64(0xaaaaaaaaaaaaaaaf)
  676. };
  677. static void
  678. bmw64_init(sph_bmw_big_context *sc, const sph_u64 *iv)
  679. {
  680. memcpy(sc->H, iv, sizeof sc->H);
  681. sc->ptr = 0;
  682. sc->bit_count = 0;
  683. }
  684. static void
  685. bmw64(sph_bmw_big_context *sc, const void *data, size_t len)
  686. {
  687. unsigned char *buf;
  688. size_t ptr;
  689. sph_u64 htmp[16];
  690. sph_u64 *h1, *h2;
  691. sc->bit_count += (sph_u64)len << 3;
  692. buf = sc->buf;
  693. ptr = sc->ptr;
  694. h1 = sc->H;
  695. h2 = htmp;
  696. while (len > 0) {
  697. size_t clen;
  698. clen = (sizeof sc->buf) - ptr;
  699. if (clen > len)
  700. clen = len;
  701. memcpy(buf + ptr, data, clen);
  702. data = (const unsigned char *)data + clen;
  703. len -= clen;
  704. ptr += clen;
  705. if (ptr == sizeof sc->buf) {
  706. sph_u64 *ht;
  707. compress_big(buf, h1, h2);
  708. ht = h1;
  709. h1 = h2;
  710. h2 = ht;
  711. ptr = 0;
  712. }
  713. }
  714. sc->ptr = ptr;
  715. if (h1 != sc->H)
  716. memcpy(sc->H, h1, sizeof sc->H);
  717. }
  718. static void
  719. bmw64_close(sph_bmw_big_context *sc, unsigned ub, unsigned n,
  720. void *dst, size_t out_size_w64)
  721. {
  722. unsigned char *buf, *out;
  723. size_t ptr, u, v;
  724. unsigned z;
  725. sph_u64 h1[16], h2[16], *h;
  726. buf = sc->buf;
  727. ptr = sc->ptr;
  728. z = 0x80 >> n;
  729. buf[ptr ++] = ((ub & -z) | z) & 0xFF;
  730. h = sc->H;
  731. if (ptr > (sizeof sc->buf) - 8) {
  732. memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
  733. compress_big(buf, h, h1);
  734. ptr = 0;
  735. h = h1;
  736. }
  737. memset(buf + ptr, 0, (sizeof sc->buf) - 8 - ptr);
  738. sph_enc64le_aligned(buf + (sizeof sc->buf) - 8,
  739. SPH_T64(sc->bit_count + n));
  740. compress_big(buf, h, h2);
  741. for (u = 0; u < 16; u ++)
  742. sph_enc64le_aligned(buf + 8 * u, h2[u]);
  743. compress_big(buf, final_b, h1);
  744. out = dst;
  745. for (u = 0, v = 16 - out_size_w64; u < out_size_w64; u ++, v ++)
  746. sph_enc64le(out + 8 * u, h1[v]);
  747. }
  748. #endif
  749. /* see sph_bmw.h */
  750. void
  751. sph_bmw224_init(void *cc)
  752. {
  753. bmw32_init(cc, IV224);
  754. }
  755. /* see sph_bmw.h */
  756. void
  757. sph_bmw224(void *cc, const void *data, size_t len)
  758. {
  759. bmw32(cc, data, len);
  760. }
  761. /* see sph_bmw.h */
  762. void
  763. sph_bmw224_close(void *cc, void *dst)
  764. {
  765. sph_bmw224_addbits_and_close(cc, 0, 0, dst);
  766. }
  767. /* see sph_bmw.h */
  768. void
  769. sph_bmw224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
  770. {
  771. bmw32_close(cc, ub, n, dst, 7);
  772. sph_bmw224_init(cc);
  773. }
  774. /* see sph_bmw.h */
  775. void
  776. sph_bmw256_init(void *cc)
  777. {
  778. bmw32_init(cc, IV256);
  779. }
  780. /* see sph_bmw.h */
  781. void
  782. sph_bmw256(void *cc, const void *data, size_t len)
  783. {
  784. bmw32(cc, data, len);
  785. }
  786. /* see sph_bmw.h */
  787. void
  788. sph_bmw256_close(void *cc, void *dst)
  789. {
  790. sph_bmw256_addbits_and_close(cc, 0, 0, dst);
  791. }
  792. /* see sph_bmw.h */
  793. void
  794. sph_bmw256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
  795. {
  796. bmw32_close(cc, ub, n, dst, 8);
  797. sph_bmw256_init(cc);
  798. }
  799. #if SPH_64
  800. /* see sph_bmw.h */
  801. void
  802. sph_bmw384_init(void *cc)
  803. {
  804. bmw64_init(cc, IV384);
  805. }
  806. /* see sph_bmw.h */
  807. void
  808. sph_bmw384(void *cc, const void *data, size_t len)
  809. {
  810. bmw64(cc, data, len);
  811. }
  812. /* see sph_bmw.h */
  813. void
  814. sph_bmw384_close(void *cc, void *dst)
  815. {
  816. sph_bmw384_addbits_and_close(cc, 0, 0, dst);
  817. }
  818. /* see sph_bmw.h */
  819. void
  820. sph_bmw384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
  821. {
  822. bmw64_close(cc, ub, n, dst, 6);
  823. sph_bmw384_init(cc);
  824. }
  825. /* see sph_bmw.h */
  826. void
  827. sph_bmw512_init(void *cc)
  828. {
  829. bmw64_init(cc, IV512);
  830. }
  831. /* see sph_bmw.h */
  832. void
  833. sph_bmw512(void *cc, const void *data, size_t len)
  834. {
  835. bmw64(cc, data, len);
  836. }
  837. /* see sph_bmw.h */
  838. void
  839. sph_bmw512_close(void *cc, void *dst)
  840. {
  841. sph_bmw512_addbits_and_close(cc, 0, 0, dst);
  842. }
  843. /* see sph_bmw.h */
  844. void
  845. sph_bmw512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
  846. {
  847. bmw64_close(cc, ub, n, dst, 8);
  848. sph_bmw512_init(cc);
  849. }
  850. #endif
  851. #ifdef __cplusplus
  852. }
  853. #endif