Path: blob/main/contrib/bearssl/src/hash/ghash_ctmul.c
39536 views
/*1* Copyright (c) 2016 Thomas Pornin <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining4* a copy of this software and associated documentation files (the5* "Software"), to deal in the Software without restriction, including6* without limitation the rights to use, copy, modify, merge, publish,7* distribute, sublicense, and/or sell copies of the Software, and to8* permit persons to whom the Software is furnished to do so, subject to9* the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#include "inner.h"2526/*27* We compute "carryless multiplications" through normal integer28* multiplications, masking out enough bits to create "holes" in which29* carries may expand without altering our bits; we really use 8 data30* bits per 32-bit word, spaced every fourth bit. Accumulated carries31* may not exceed 8 in total, which fits in 4 bits.32*33* It would be possible to use a 3-bit spacing, allowing two operands,34* one with 7 non-zero data bits, the other one with 10 or 11 non-zero35* data bits; this asymmetric splitting makes the overall code more36* complex with thresholds and exceptions, and does not appear to be37* worth the effort.38*/3940/*41* We cannot really autodetect whether multiplications are "slow" or42* not. A typical example is the ARM Cortex M0+, which exists in two43* versions: one with a 1-cycle multiplication opcode, the other with44* a 32-cycle multiplication opcode. They both use exactly the same45* architecture and ABI, and cannot be distinguished from each other46* at compile-time.47*48* Since most modern CPU (even embedded CPU) still have fast49* multiplications, we use the "fast mul" code by default.50*/5152#if BR_SLOW_MUL5354/*55* This implementation uses Karatsuba-like reduction to make fewer56* integer multiplications (9 instead of 16), at the expense of extra57* logical operations (XOR, shifts...). On modern x86 CPU that offer58* fast, pipelined multiplications, this code is about twice slower than59* the simpler code with 16 multiplications. This tendency may be60* reversed on low-end platforms with expensive multiplications.61*/6263#define MUL32(h, l, x, y) do { \64uint64_t mul32tmp = MUL(x, y); \65(h) = (uint32_t)(mul32tmp >> 32); \66(l) = (uint32_t)mul32tmp; \67} while (0)6869static inline void70bmul(uint32_t *hi, uint32_t *lo, uint32_t x, uint32_t y)71{72uint32_t x0, x1, x2, x3;73uint32_t y0, y1, y2, y3;74uint32_t a0, a1, a2, a3, a4, a5, a6, a7, a8;75uint32_t b0, b1, b2, b3, b4, b5, b6, b7, b8;7677x0 = x & (uint32_t)0x11111111;78x1 = x & (uint32_t)0x22222222;79x2 = x & (uint32_t)0x44444444;80x3 = x & (uint32_t)0x88888888;81y0 = y & (uint32_t)0x11111111;82y1 = y & (uint32_t)0x22222222;83y2 = y & (uint32_t)0x44444444;84y3 = y & (uint32_t)0x88888888;8586/*87* (x0+W*x1)*(y0+W*y1) -> a0:b088* (x2+W*x3)*(y2+W*y3) -> a3:b389* ((x0+x2)+W*(x1+x3))*((y0+y2)+W*(y1+y3)) -> a6:b690*/91a0 = x0;92b0 = y0;93a1 = x1 >> 1;94b1 = y1 >> 1;95a2 = a0 ^ a1;96b2 = b0 ^ b1;97a3 = x2 >> 2;98b3 = y2 >> 2;99a4 = x3 >> 3;100b4 = y3 >> 3;101a5 = a3 ^ a4;102b5 = b3 ^ b4;103a6 = a0 ^ a3;104b6 = b0 ^ b3;105a7 = a1 ^ a4;106b7 = b1 ^ b4;107a8 = a6 ^ a7;108b8 = b6 ^ b7;109110MUL32(b0, a0, b0, a0);111MUL32(b1, a1, b1, a1);112MUL32(b2, a2, b2, a2);113MUL32(b3, a3, b3, a3);114MUL32(b4, a4, b4, a4);115MUL32(b5, a5, b5, a5);116MUL32(b6, a6, b6, a6);117MUL32(b7, a7, b7, a7);118MUL32(b8, a8, b8, a8);119120a0 &= (uint32_t)0x11111111;121a1 &= (uint32_t)0x11111111;122a2 &= (uint32_t)0x11111111;123a3 &= (uint32_t)0x11111111;124a4 &= (uint32_t)0x11111111;125a5 &= (uint32_t)0x11111111;126a6 &= (uint32_t)0x11111111;127a7 &= (uint32_t)0x11111111;128a8 &= (uint32_t)0x11111111;129b0 &= (uint32_t)0x11111111;130b1 &= (uint32_t)0x11111111;131b2 &= (uint32_t)0x11111111;132b3 &= (uint32_t)0x11111111;133b4 &= (uint32_t)0x11111111;134b5 &= (uint32_t)0x11111111;135b6 &= (uint32_t)0x11111111;136b7 &= (uint32_t)0x11111111;137b8 &= (uint32_t)0x11111111;138139a2 ^= a0 ^ a1;140b2 ^= b0 ^ b1;141a0 ^= (a2 << 1) ^ (a1 << 2);142b0 ^= (b2 << 1) ^ (b1 << 2);143a5 ^= a3 ^ a4;144b5 ^= b3 ^ b4;145a3 ^= (a5 << 1) ^ (a4 << 2);146b3 ^= (b5 << 1) ^ (b4 << 2);147a8 ^= a6 ^ a7;148b8 ^= b6 ^ b7;149a6 ^= (a8 << 1) ^ (a7 << 2);150b6 ^= (b8 << 1) ^ (b7 << 2);151a6 ^= a0 ^ a3;152b6 ^= b0 ^ b3;153*lo = a0 ^ (a6 << 2) ^ (a3 << 4);154*hi = b0 ^ (b6 << 2) ^ (b3 << 4) ^ (a6 >> 30) ^ (a3 >> 28);155}156157#else158159/*160* Simple multiplication in GF(2)[X], using 16 integer multiplications.161*/162163static inline void164bmul(uint32_t *hi, uint32_t *lo, uint32_t x, uint32_t y)165{166uint32_t x0, x1, x2, x3;167uint32_t y0, y1, y2, y3;168uint64_t z0, z1, z2, z3;169uint64_t z;170171x0 = x & (uint32_t)0x11111111;172x1 = x & (uint32_t)0x22222222;173x2 = x & (uint32_t)0x44444444;174x3 = x & (uint32_t)0x88888888;175y0 = y & (uint32_t)0x11111111;176y1 = y & (uint32_t)0x22222222;177y2 = y & (uint32_t)0x44444444;178y3 = y & (uint32_t)0x88888888;179z0 = MUL(x0, y0) ^ MUL(x1, y3) ^ MUL(x2, y2) ^ MUL(x3, y1);180z1 = MUL(x0, y1) ^ MUL(x1, y0) ^ MUL(x2, y3) ^ MUL(x3, y2);181z2 = MUL(x0, y2) ^ MUL(x1, y1) ^ MUL(x2, y0) ^ MUL(x3, y3);182z3 = MUL(x0, y3) ^ MUL(x1, y2) ^ MUL(x2, y1) ^ MUL(x3, y0);183z0 &= (uint64_t)0x1111111111111111;184z1 &= (uint64_t)0x2222222222222222;185z2 &= (uint64_t)0x4444444444444444;186z3 &= (uint64_t)0x8888888888888888;187z = z0 | z1 | z2 | z3;188*lo = (uint32_t)z;189*hi = (uint32_t)(z >> 32);190}191192#endif193194/* see bearssl_hash.h */195void196br_ghash_ctmul(void *y, const void *h, const void *data, size_t len)197{198const unsigned char *buf, *hb;199unsigned char *yb;200uint32_t yw[4];201uint32_t hw[4];202203/*204* Throughout the loop we handle the y and h values as arrays205* of 32-bit words.206*/207buf = data;208yb = y;209hb = h;210yw[3] = br_dec32be(yb);211yw[2] = br_dec32be(yb + 4);212yw[1] = br_dec32be(yb + 8);213yw[0] = br_dec32be(yb + 12);214hw[3] = br_dec32be(hb);215hw[2] = br_dec32be(hb + 4);216hw[1] = br_dec32be(hb + 8);217hw[0] = br_dec32be(hb + 12);218while (len > 0) {219const unsigned char *src;220unsigned char tmp[16];221int i;222uint32_t a[9], b[9], zw[8];223uint32_t c0, c1, c2, c3, d0, d1, d2, d3, e0, e1, e2, e3;224225/*226* Get the next 16-byte block (using zero-padding if227* necessary).228*/229if (len >= 16) {230src = buf;231buf += 16;232len -= 16;233} else {234memcpy(tmp, buf, len);235memset(tmp + len, 0, (sizeof tmp) - len);236src = tmp;237len = 0;238}239240/*241* Decode the block. The GHASH standard mandates242* big-endian encoding.243*/244yw[3] ^= br_dec32be(src);245yw[2] ^= br_dec32be(src + 4);246yw[1] ^= br_dec32be(src + 8);247yw[0] ^= br_dec32be(src + 12);248249/*250* We multiply two 128-bit field elements. We use251* Karatsuba to turn that into three 64-bit252* multiplications, which are themselves done with a253* total of nine 32-bit multiplications.254*/255256/*257* y[0,1]*h[0,1] -> 0..2258* y[2,3]*h[2,3] -> 3..5259* (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6..8260*/261a[0] = yw[0];262b[0] = hw[0];263a[1] = yw[1];264b[1] = hw[1];265a[2] = a[0] ^ a[1];266b[2] = b[0] ^ b[1];267268a[3] = yw[2];269b[3] = hw[2];270a[4] = yw[3];271b[4] = hw[3];272a[5] = a[3] ^ a[4];273b[5] = b[3] ^ b[4];274275a[6] = a[0] ^ a[3];276b[6] = b[0] ^ b[3];277a[7] = a[1] ^ a[4];278b[7] = b[1] ^ b[4];279a[8] = a[6] ^ a[7];280b[8] = b[6] ^ b[7];281282for (i = 0; i < 9; i ++) {283bmul(&b[i], &a[i], b[i], a[i]);284}285286c0 = a[0];287c1 = b[0] ^ a[2] ^ a[0] ^ a[1];288c2 = a[1] ^ b[2] ^ b[0] ^ b[1];289c3 = b[1];290d0 = a[3];291d1 = b[3] ^ a[5] ^ a[3] ^ a[4];292d2 = a[4] ^ b[5] ^ b[3] ^ b[4];293d3 = b[4];294e0 = a[6];295e1 = b[6] ^ a[8] ^ a[6] ^ a[7];296e2 = a[7] ^ b[8] ^ b[6] ^ b[7];297e3 = b[7];298299e0 ^= c0 ^ d0;300e1 ^= c1 ^ d1;301e2 ^= c2 ^ d2;302e3 ^= c3 ^ d3;303c2 ^= e0;304c3 ^= e1;305d0 ^= e2;306d1 ^= e3;307308/*309* GHASH specification has the bits "reversed" (most310* significant is in fact least significant), which does311* not matter for a carryless multiplication, except that312* the 255-bit result must be shifted by 1 bit.313*/314zw[0] = c0 << 1;315zw[1] = (c1 << 1) | (c0 >> 31);316zw[2] = (c2 << 1) | (c1 >> 31);317zw[3] = (c3 << 1) | (c2 >> 31);318zw[4] = (d0 << 1) | (c3 >> 31);319zw[5] = (d1 << 1) | (d0 >> 31);320zw[6] = (d2 << 1) | (d1 >> 31);321zw[7] = (d3 << 1) | (d2 >> 31);322323/*324* We now do the reduction modulo the field polynomial325* to get back to 128 bits.326*/327for (i = 0; i < 4; i ++) {328uint32_t lw;329330lw = zw[i];331zw[i + 4] ^= lw ^ (lw >> 1) ^ (lw >> 2) ^ (lw >> 7);332zw[i + 3] ^= (lw << 31) ^ (lw << 30) ^ (lw << 25);333}334memcpy(yw, zw + 4, sizeof yw);335}336337/*338* Encode back the result.339*/340br_enc32be(yb, yw[3]);341br_enc32be(yb + 4, yw[2]);342br_enc32be(yb + 8, yw[1]);343br_enc32be(yb + 12, yw[0]);344}345346347