oxedyne/fe2o3/fe2o3_crypto/src/c/cbd.c
2.6 KiB, 1 run
created by r1870400018:192, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | /*--------------------------------------------------------------------- |
| 2 | This file has been adapted from the implementation |
| 3 | (available at, Public Domain https://github.com/pq-crystals/kyber) |
| 4 | of "CRYSTALS – Kyber: a CCA-secure module-lattice-based KEM" |
| 5 | by : Joppe Bos, Leo Ducas, Eike Kiltz, Tancrede Lepoint, |
| 6 | Vadim Lyubashevsky, John M. Schanck, Peter Schwabe & Damien stehle |
| 7 | ----------------------------------------------------------------------*/ |
| 8 | |
| 9 | #include "SABER_params.h" |
| 10 | #include "api.h" |
| 11 | #include "cbd.h" |
| 12 | #include <stdint.h> |
| 13 | |
| 14 | static uint64_t load_littleendian(const uint8_t *x, int bytes) |
| 15 | { |
| 16 | int i; |
| 17 | uint64_t r = x[0]; |
| 18 | for (i = 1; i < bytes; i++) { |
| 19 | r = r | (uint64_t)x[i] << (8 * i); |
| 20 | } |
| 21 | return r; |
| 22 | } |
| 23 | |
| 24 | void cbd(uint16_t s[SABER_N], const uint8_t buf[SABER_POLYCOINBYTES]) |
| 25 | { |
| 26 | #if SABER_MU == 6 |
| 27 | uint32_t t, d, a[4], b[4]; |
| 28 | int i, j; |
| 29 | |
| 30 | for (i = 0; i < SABER_N / 4; i++) |
| 31 | { |
| 32 | t = load_littleendian(buf + 3 * i, 3); |
| 33 | d = 0; |
| 34 | for (j = 0; j < 3; j++) |
| 35 | d += (t >> j) & 0x249249; |
| 36 | |
| 37 | a[0] = d & 0x7; |
| 38 | b[0] = (d >> 3) & 0x7; |
| 39 | a[1] = (d >> 6) & 0x7; |
| 40 | b[1] = (d >> 9) & 0x7; |
| 41 | a[2] = (d >> 12) & 0x7; |
| 42 | b[2] = (d >> 15) & 0x7; |
| 43 | a[3] = (d >> 18) & 0x7; |
| 44 | b[3] = (d >> 21); |
| 45 | |
| 46 | s[4 * i + 0] = (uint16_t)(a[0] - b[0]); |
| 47 | s[4 * i + 1] = (uint16_t)(a[1] - b[1]); |
| 48 | s[4 * i + 2] = (uint16_t)(a[2] - b[2]); |
| 49 | s[4 * i + 3] = (uint16_t)(a[3] - b[3]); |
| 50 | } |
| 51 | #elif SABER_MU == 8 |
| 52 | uint32_t t, d, a[4], b[4]; |
| 53 | int i, j; |
| 54 | |
| 55 | for (i = 0; i < SABER_N / 4; i++) |
| 56 | { |
| 57 | t = load_littleendian(buf + 4 * i, 4); |
| 58 | d = 0; |
| 59 | for (j = 0; j < 4; j++) |
| 60 | d += (t >> j) & 0x11111111; |
| 61 | |
| 62 | a[0] = d & 0xf; |
| 63 | b[0] = (d >> 4) & 0xf; |
| 64 | a[1] = (d >> 8) & 0xf; |
| 65 | b[1] = (d >> 12) & 0xf; |
| 66 | a[2] = (d >> 16) & 0xf; |
| 67 | b[2] = (d >> 20) & 0xf; |
| 68 | a[3] = (d >> 24) & 0xf; |
| 69 | b[3] = (d >> 28); |
| 70 | |
| 71 | s[4 * i + 0] = (uint16_t)(a[0] - b[0]); |
| 72 | s[4 * i + 1] = (uint16_t)(a[1] - b[1]); |
| 73 | s[4 * i + 2] = (uint16_t)(a[2] - b[2]); |
| 74 | s[4 * i + 3] = (uint16_t)(a[3] - b[3]); |
| 75 | } |
| 76 | #elif SABER_MU == 10 |
| 77 | uint64_t t, d, a[4], b[4]; |
| 78 | int i, j; |
| 79 | |
| 80 | for (i = 0; i < SABER_N / 4; i++) |
| 81 | { |
| 82 | t = load_littleendian(buf + 5 * i, 5); |
| 83 | d = 0; |
| 84 | for (j = 0; j < 5; j++) |
| 85 | d += (t >> j) & 0x0842108421UL; |
| 86 | |
| 87 | a[0] = d & 0x1f; |
| 88 | b[0] = (d >> 5) & 0x1f; |
| 89 | a[1] = (d >> 10) & 0x1f; |
| 90 | b[1] = (d >> 15) & 0x1f; |
| 91 | a[2] = (d >> 20) & 0x1f; |
| 92 | b[2] = (d >> 25) & 0x1f; |
| 93 | a[3] = (d >> 30) & 0x1f; |
| 94 | b[3] = (d >> 35); |
| 95 | |
| 96 | s[4 * i + 0] = (uint16_t)(a[0] - b[0]); |
| 97 | s[4 * i + 1] = (uint16_t)(a[1] - b[1]); |
| 98 | s[4 * i + 2] = (uint16_t)(a[2] - b[2]); |
| 99 | s[4 * i + 3] = (uint16_t)(a[3] - b[3]); |
| 100 | } |
| 101 | #else |
| 102 | #error "Unsupported SABER parameter." |
| 103 | #endif |
| 104 | } |