[PATCH 2/5] dilithium: Added optimized dilithium inverse NTT support for ppc64le.
Danny Tsen via Gcrypt-devel <[email protected]> Mon, 23 Feb 2026 18:27:50 -0600
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <[email protected]> |
Optimized dilithium (ML-DSA) inverse NTT algorithm for ppc64le (Power 8 and above). Signed-off-by: Danny Tsen <[email protected]> --- cipher/dilithium_intt_p8le.S | 915 +++++++++++++++++++++++++++++++++++ 1 file changed, 915 insertions(+) create mode 100644 cipher/dilithium_intt_p8le.S diff --git a/cipher/dilithium_intt_p8le.S b/cipher/dilithium_intt_p8le.S new file mode 100644 index 00000000..b0f67979 --- /dev/null +++ b/cipher/dilithium_intt_p8le.S @@ -0,0 +1,915 @@ +/* + * This file was modified for use by Libgcrypt. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * You can also use this file under the same licence of original code. + * SPDX-License-Identifier: CC0 OR Apache-2.0 + * + */ +/* + * + * Copyright IBM Corp. 2025, 2026 + * + * =================================================================================== + * Written by Danny Tsen <[email protected]> + */ + +#define QINV_OFFSET 16 +#define FCONST_OFFSET 32 +#define ZETA_INTT_OFFSET 48 + +#define MLDSA_Q 8380417 +#define MLDSA_QINV 58728449 +#define FCONST 41978 + +#define QINV 0 +#define V_Q 1 +#define V_F 2 +#define V_ZETA 2 +#define V_Z0 2 +#define V_Z1 3 +#define V_Z2 4 +#define V_Z3 5 + +.machine "any" +.text + +.macro SAVE_REGS + stdu 1, -352(1) + mflr 0 + std 14, 56(1) + std 15, 64(1) + std 16, 72(1) + std 17, 80(1) + std 18, 88(1) + std 19, 96(1) + std 20, 104(1) + std 21, 112(1) + li 10, 128 + li 11, 144 + li 12, 160 + li 14, 176 + li 15, 192 + li 16, 208 + stxvx 32+20, 10, 1 + stxvx 32+21, 11, 1 + stxvx 32+22, 12, 1 + stxvx 32+23, 14, 1 + stxvx 32+24, 15, 1 + stxvx 32+25, 16, 1 + li 10, 224 + li 11, 240 + li 12, 256 + li 14, 272 + stxvx 32+26, 10, 1 + stxvx 32+27, 11, 1 + stxvx 32+28, 12, 1 + stxvx 32+29, 14, 1 +.endm + +.macro RESTORE_REGS + li 10, 128 + li 11, 144 + li 12, 160 + li 14, 176 + li 15, 192 + li 16, 208 + lxvx 32+20, 10, 1 + lxvx 32+21, 11, 1 + lxvx 32+22, 12, 1 + lxvx 32+23, 14, 1 + lxvx 32+24, 15, 1 + lxvx 32+25, 16, 1 + li 10, 224 + li 11, 240 + li 12, 256 + li 14, 272 + lxvx 32+26, 10, 1 + lxvx 32+27, 11, 1 + lxvx 32+28, 12, 1 + lxvx 32+29, 14, 1 + ld 14, 56(1) + ld 15, 64(1) + ld 16, 72(1) + ld 17, 80(1) + ld 18, 88(1) + ld 19, 96(1) + ld 20, 104(1) + ld 21, 112(1) + + mtlr 0 + addi 1, 1, 352 +.endm + +/* + * Init_Coeffs_offset: initial offset setup for the coefficient array. + * + * start: beginning of the offset to the coefficient array. + * next: Next offset. + * len: Index difference between coefficients. + * + * r7: len * 2, each coefficient component is 32 bits. + * + * registers used for offset to coefficients, r[j] and r[j+len] + * R9: offset to r0 = j + * R16: offset to r1 = r0 + next + * R18: offset to r2 = r1 + next + * R20: offset to r3 = r2 + next + * + * R10: offset to r'0 = r0 + len*2 + * R17: offset to r'1 = r'0 + next + * R19: offset to r'2 = r'1 + next + * R21: offset to r'3 = r'2 + next + * + */ +.macro Init_Coeffs_offset start next + li 9, \start /* first offset to j */ + add 10, 7, 9 /* J + len*2 */ + addi 16, 9, \next + addi 17, 10, \next + addi 18, 16, \next + addi 19, 17, \next + addi 20, 18, \next + addi 21, 19, \next +.endm + +/* + * For Len=1, load 1-1-1-1 layout + * + * Load Coefficients and setup vectors + * rj0, rjlen1, rj2, rjlen3 + * rj4, rjlen5, rj6, rjlen7 + * + * Each vmrgew and vmrgow will transpose vectors as, + * + * rj vector = (rj0, rj4, rj2, rj6) + * rjlen vector = (rjlen1, rjlen5, rjlen3, rjlen7) + * + * r' =r[j+len]: V18, V19, V20, V21 + * r = r[j]: V14, V15, V16, V17 + * + * In order to do the coefficients computation, zeta vector will arrange + * in the proper order to match the multiplication. + */ +.macro Load_41Coeffs + lxvd2x 32+10, 0, 5 + lxvd2x 32+11, 10, 5 + vmrgew 18, 10, 11 + vmrgow 14, 10, 11 + lxvd2x 32+12, 11, 5 + lxvd2x 32+13, 12, 5 + vmrgew 19, 12, 13 + vmrgow 15, 12, 13 + lxvd2x 32+10, 15, 5 + lxvd2x 32+11, 16, 5 + vmrgew 20, 10, 11 + vmrgow 16, 10, 11 + lxvd2x 32+12, 17, 5 + lxvd2x 32+13, 18, 5 + vmrgew 21, 12, 13 + vmrgow 17, 12, 13 +.endm + +/* + * For Len=2, Load 2 - 2 - 2 - 2 layout + * + * Load Coefficients and setup vectors for 8 coefficients in the + * following order, + * rj0, rj1, rjlen2, rjlen3, + * rj4, rj5, rjlen6, arlen7 + * Each xxpermdi will transpose vectors as, + * r[j]= rj0, rj1, rj4, rj5 + * r[j+len]= rjlen2, rjlen3, rjlen6, arlen7 + * + * r' =r[j+len]: V18, V19, V20, V21 + * r = r[j]: V14, V15, V16, V17 + * + * In order to do the coefficients computation, zeta vector will arrange + * in the proper order to match the multiplication. + */ +.macro Load_42Coeffs + lxvd2x 1, 0, 5 + lxvd2x 2, 10, 5 + xxpermdi 32+18, 1, 2, 3 + xxpermdi 32+14, 1, 2, 0 + lxvd2x 3, 11, 5 + lxvd2x 4, 12, 5 + xxpermdi 32+19, 3, 4, 3 + xxpermdi 32+15, 3, 4, 0 + lxvd2x 1, 15, 5 + lxvd2x 2, 16, 5 + xxpermdi 32+20, 1, 2, 3 + xxpermdi 32+16, 1, 2, 0 + lxvd2x 3, 17, 5 + lxvd2x 4, 18, 5 + xxpermdi 32+21, 3, 4, 3 + xxpermdi 32+17, 3, 4, 0 +.endm + +/* + * For Len=8, + * Load coefficient with 2 legs with 64 bytes apart in + * r[j+len] (r') vectors from offset, R10, R17, R19 and R21 + * r[j] (r) vectors from offset, R9, R16, R18 and R20 + * r[j+len]: V18, V19, V20, V21 + * r = r[j]: V14, V15, V16, V17 + */ +.macro Load_22Coeffs start next + li 9, \start + add 10, 7, 9 + addi 16, 9, \next + addi 17, 10, \next + li 18, \start+64 + add 19, 7, 18 + addi 20, 18, \next + addi 21, 19, \next + lxvd2x 32+18, 3, 10 + lxvd2x 32+19, 3, 17 + lxvd2x 32+20, 3, 19 + lxvd2x 32+21, 3, 21 + + lxvd2x 32+14, 3, 9 + lxvd2x 32+15, 3, 16 + lxvd2x 32+16, 3, 18 + lxvd2x 32+17, 3, 20 +.endm + +/* + * Load coefficient with 2 legs with len*2 bytes apart in + * r[j+len] (r') vectors from offset, R10, R17, R19 and R21 + * r[j] (r) vectors from offset, R9, R16, R18 and R20 + * r[j+len]: V18, V19, V20, V21 + * r = r[j]: V14, V15, V16, V17 + */ +.macro Load_4Coeffs start next + Init_Coeffs_offset \start, \next + + lxvd2x 32+18, 3, 10 + lxvd2x 32+19, 3, 17 + lxvd2x 32+20, 3, 19 + lxvd2x 32+21, 3, 21 + + lxvd2x 32+14, 3, 9 + lxvd2x 32+15, 3, 16 + lxvd2x 32+16, 3, 18 + lxvd2x 32+17, 3, 20 +.endm + +/* + * Compute final final r[j] and r[j+len] + * final r[j]: V26, V27, V28, V29 + * final r[j+len]: V6, V7, V8, V9 + */ +.macro Compute_4Coeff + vadduwm 26, 14, 18 + vsubuwm 6, 14, 18 + + vadduwm 27, 15, 19 + vsubuwm 7, 15, 19 + + vadduwm 28, 16, 20 + vsubuwm 8, 16, 20 + + vadduwm 29, 17, 21 + vsubuwm 9, 17, 21 +.endm + +.macro Write_One + stxvd2x 32+26, 3, 9 + stxvd2x 32+10, 3, 10 + stxvd2x 32+27, 3, 16 + stxvd2x 32+11, 3, 17 + stxvd2x 32+28, 3, 18 + stxvd2x 32+12, 3, 19 + stxvd2x 32+29, 3, 20 + stxvd2x 32+13, 3, 21 +.endm + +/* + * For Len=2 + * Transpose the final coefficients of 2-2-2-2 layout to the original + * coefficient array order. + */ +.macro PermWrite42 + xxpermdi 32+14, 32+26, 32+10, 0 + xxpermdi 32+15, 32+26, 32+10, 3 + xxpermdi 32+16, 32+27, 32+11, 0 + xxpermdi 32+17, 32+27, 32+11, 3 + xxpermdi 32+18, 32+28, 32+12, 0 + xxpermdi 32+19, 32+28, 32+12, 3 + xxpermdi 32+20, 32+29, 32+13, 0 + xxpermdi 32+21, 32+29, 32+13, 3 + stxvd2x 32+14, 0, 5 + stxvd2x 32+15, 10, 5 + stxvd2x 32+16, 11, 5 + stxvd2x 32+17, 12, 5 + stxvd2x 32+18, 15, 5 + stxvd2x 32+19, 16, 5 + stxvd2x 32+20, 17, 5 + stxvd2x 32+21, 18, 5 +.endm + +/* + * For Len=1 + * Transpose the final coefficients of 1-1-1-1 layout to the original + * coefficient array order. + */ +.macro PermWrite41 + vmrgew 14, 10, 26 + vmrgow 15, 10, 26 + vmrgew 16, 11, 27 + vmrgow 17, 11, 27 + vmrgew 18, 12, 28 + vmrgow 19, 12, 28 + vmrgew 20, 13, 29 + vmrgow 21, 13, 29 + stxvd2x 32+14, 0, 5 + stxvd2x 32+15, 10, 5 + stxvd2x 32+16, 11, 5 + stxvd2x 32+17, 12, 5 + stxvd2x 32+18, 15, 5 + stxvd2x 32+19, 16, 5 + stxvd2x 32+20, 17, 5 + stxvd2x 32+21, 18, 5 +.endm + +.macro Load_next_4zetas + li 10, 16 + li 11, 32 + li 12, 48 + lxvd2x 32+V_Z0, 0, 14 + lxvd2x 32+V_Z1, 10, 14 + lxvd2x 32+V_Z2, 11, 14 + lxvd2x 32+V_Z3, 12, 14 + addi 14, 14, 64 +.endm + +/* + * montgomery_reduce + * montgomery_reduce((int64_t)zeta * a[j + len]) + * a = zeta * a[j+len] + * t = (int64_t)(int32_t)a*QINV; + * t = (a - (int64_t)t*Q) >> 32; + * + * Or + * montgomery_reduce((int64_t)f * a[j]) + * + * ----------------------------------- + * MREDUCE_4X(_vz0, _vz1, _vz2, _vz3) + */ +.macro MREDUCE_4x _vz0 _vz1 _vz2 _vz3 + /* Coefficients computation results in abosulte value of 2^64 in + even and odd pairs */ + vmulesw 10, 6, \_vz0 + vmulosw 11, 6, \_vz0 + vmulesw 12, 7, \_vz1 + vmulosw 13, 7, \_vz1 + vmulesw 14, 8, \_vz2 + vmulosw 15, 8, \_vz2 + vmulesw 16, 9, \_vz3 + vmulosw 17, 9, \_vz3 + + /* Compute a*q^(-1) mod 2^32 and results in the upper 32 bits of + even pair */ + vmulosw 18, 10, QINV + vmulosw 19, 11, QINV + vmulosw 20, 12, QINV + vmulosw 21, 13, QINV + vmulosw 22, 14, QINV + vmulosw 23, 15, QINV + vmulosw 24, 16, QINV + vmulosw 25, 17, QINV + + vmulosw 18, 18, V_Q + vmulosw 19, 19, V_Q + vmulosw 20, 20, V_Q + vmulosw 21, 21, V_Q + vmulosw 22, 22, V_Q + vmulosw 23, 23, V_Q + vmulosw 24, 24, V_Q + vmulosw 25, 25, V_Q + + vsubudm 18, 10, 18 + vsubudm 19, 11, 19 + vsubudm 20, 12, 20 + vsubudm 21, 13, 21 + vsubudm 22, 14, 22 + vsubudm 23, 15, 23 + vsubudm 24, 16, 24 + vsubudm 25, 17, 25 + + vmrgew 10, 18, 19 + vmrgew 11, 20, 21 + vmrgew 12, 22, 23 + vmrgew 13, 24, 25 +.endm + +/* + * For Len=1, layer with 1-1-1-1 layout. + */ +.macro iNTT_MREDUCE_41x + Load_next_4zetas + Load_41Coeffs + Compute_4Coeff + MREDUCE_4x V_Z0, V_Z1, V_Z2, V_Z3 + PermWrite41 + addi 5, 5, 128 +.endm + +/* + * For Len=2, layer with 2-2-2-2 layout. + */ +.macro iNTT_MREDUCE_42x + Load_next_4zetas + Load_42Coeffs + Compute_4Coeff + MREDUCE_4x V_Z0, V_Z1, V_Z2, V_Z3 + PermWrite42 + addi 5, 5, 128 +.endm + +/* + * For Len=8 + */ +.macro iNTT_MREDUCE_22x start next _vz0 _vz1 _vz2 _vz3 + Load_22Coeffs \start, \next + Compute_4Coeff + MREDUCE_4x \_vz0, \_vz1, \_vz2, \_vz3 + Write_One +.endm + +/* + * For Len=128, 64, 32, 16 and 4. + */ +.macro iNTT_MREDUCE_4x start next _vz0 _vz1 _vz2 _vz3 + Load_4Coeffs \start, \next + Compute_4Coeff + MREDUCE_4x \_vz0, \_vz1, \_vz2, \_vz3 + Write_One +.endm + +.macro Reload_4coeffs + lxvd2x 32+6, 0, 6 + lxvd2x 32+7, 10, 6 + lxvd2x 32+8, 11, 6 + lxvd2x 32+9, 12, 6 +.endm + +.macro Write_F + stxvd2x 32+10, 0, 6 + stxvd2x 32+11, 10, 6 + stxvd2x 32+12, 11, 6 + stxvd2x 32+13, 12, 6 + addi 6, 6, 64 +.endm + +.macro POLY_Mont_Reduce_4x + Reload_4coeffs + MREDUCE_4x V_F, V_F, V_F, V_F + Write_F + + Reload_4coeffs + MREDUCE_4x V_F, V_F, V_F, V_F + Write_F + + Reload_4coeffs + MREDUCE_4x V_F, V_F, V_F, V_F + Write_F + + Reload_4coeffs + MREDUCE_4x V_F, V_F, V_F, V_F + Write_F +.endm + +/* + * mldsa_intt_ppc(int32_t *r) + * + * Compute Inverse NTT based on the following 8 layers - + * len = 1, 2, 4, 8, 16, 32, 64, 128. + * + * Each layer compute the coefficients on 2 legs, start and start + len*2 offsets. + * + * leg 1 leg 2 + * ----- ----- + * start start+len*2 + * start+next start+len*2+next + * start+next+next start+len*2+next+next + * start+next+next+next start+len*2+next+next+next + * + * Each computation loads 8 vectors, 4 for each leg. + * The final coefficient (t) from each vector of leg1 and leg2 then do the + * add/sub operations to obtain the final results. + * + * -> leg1 = leg1 + t, leg2 = leg1 - t + * + * The resulting coefficients then store back to each leg's offset. + * + * Each vector has the same corresponding zeta except len=2. + * + * len=2 has 2-2-2-2 layout which means every 2 32-bit coefficients has the same zeta. + * e.g. + * coeff vector a1 a2 a3 a4 a5 a6 a7 a8 + * zeta vector z1 z1 z2 z2 z3 z3 z4 z4 + * + * For len=2, each vector will get permuted to leg1 and leg2. Zeta is + * pre-arranged for the leg1 and leg2. After the computation, each vector needs + * to transpose back to its original 2-2-2-2 layout. + * + */ +.global mldsa_intt_ppc +.align 4 +mldsa_intt_ppc: + + SAVE_REGS + + /* load Q and Q_NEG_INV */ + addis 8,2,mldsa_consts@toc@ha + addi 8,8,mldsa_consts@toc@l + lvx V_Q, 0, 8 + li 10, QINV_OFFSET + lvx QINV, 10, 8 + + /* set zetas array */ + addi 14, 8, ZETA_INTT_OFFSET + +.align 4 + /* + * 1. len = 1, start = 0, 2, 4, 6, 8, 10, 12,...254 + * + * Compute coefficients of the inverse NTT based on the following sequences, + * 0, 1, 2, 3 + * 4, 5, 6, 7 + * 8, 9, 10, 11 + * 12, 13, 14, 15 + * ... + * 240, 241, 242, 243 + * 244, 245, 246, 247 + * 248, 249, 250, 251 + * 252, 253, 254, 255 + * + * These are indexes to the 32 bits array. Each loads 4 vectors. + */ + mr 5, 3 + li 7, 4 + + li 10, 16 + li 11, 32 + li 12, 48 + li 15, 64 + li 16, 80 + li 17, 96 + li 18, 112 + + iNTT_MREDUCE_41x + iNTT_MREDUCE_41x + iNTT_MREDUCE_41x + iNTT_MREDUCE_41x + iNTT_MREDUCE_41x + iNTT_MREDUCE_41x + iNTT_MREDUCE_41x + iNTT_MREDUCE_41x + +.align 4 + /* + * 2. len = 2, start = 0, 4, 8, 12,...244, 248, 252 + * + * Compute coefficients of the NTT based on 2 legs, + * 0 - 4 + * 8 - 12 + * 16 - 20 + * ... + * 240 - 244 + * 248 - 252 + * + * These are indexes to the 32 bits array + */ + mr 5, 3 + li 7, 8 + + iNTT_MREDUCE_42x + iNTT_MREDUCE_42x + iNTT_MREDUCE_42x + iNTT_MREDUCE_42x + iNTT_MREDUCE_42x + iNTT_MREDUCE_42x + iNTT_MREDUCE_42x + iNTT_MREDUCE_42x + +.align 4 + /* + * 3. len = 4, start = 0, 32, 64, 96, 128, 160, 192, 224 + * + * Compute coefficients of the NTT based on 2 legs, + * 0 - 4 + * 32 - 36 + * 64 - 68 + * ... + * 192 - 196 + * 224 - 228 + * + * These are indexes to the 32 bits array + */ + + li 7, 16 + + Load_next_4zetas + iNTT_MREDUCE_4x 0, 32, V_Z0, V_Z1, V_Z2, V_Z3 + Load_next_4zetas + iNTT_MREDUCE_4x 128, 32, V_Z0, V_Z1, V_Z2, V_Z3 + Load_next_4zetas + iNTT_MREDUCE_4x 128*2, 32, V_Z0, V_Z1, V_Z2, V_Z3 + Load_next_4zetas + iNTT_MREDUCE_4x 128*3, 32, V_Z0, V_Z1, V_Z2, V_Z3 + Load_next_4zetas + iNTT_MREDUCE_4x 128*4, 32, V_Z0, V_Z1, V_Z2, V_Z3 + Load_next_4zetas + iNTT_MREDUCE_4x 128*5, 32, V_Z0, V_Z1, V_Z2, V_Z3 + Load_next_4zetas + iNTT_MREDUCE_4x 128*6, 32, V_Z0, V_Z1, V_Z2, V_Z3 + Load_next_4zetas + iNTT_MREDUCE_4x 128*7, 32, V_Z0, V_Z1, V_Z2, V_Z3 + +.align 4 + /* + * 4. len = 8, start = 0, 32, 64, 96, 128, 160, 192, 224 + * + * Compute coefficients of the NTT based on 2 legs, + * 0 - 8 + * 32 - 40 + * 64 - 72 + * ... + * 192 - 200 + * 224 - 232 + * + * These are indexes to the 32 bits array + */ + + li 7, 32 + Load_next_4zetas + iNTT_MREDUCE_22x 0, 16, V_Z0, V_Z0, V_Z1, V_Z1 + iNTT_MREDUCE_22x 128, 16, V_Z2, V_Z2, V_Z3, V_Z3 + + Load_next_4zetas + iNTT_MREDUCE_22x 128*2, 16, V_Z0, V_Z0, V_Z1, V_Z1 + iNTT_MREDUCE_22x 128*3, 16, V_Z2, V_Z2, V_Z3, V_Z3 + + Load_next_4zetas + iNTT_MREDUCE_22x 128*4, 16, V_Z0, V_Z0, V_Z1, V_Z1 + iNTT_MREDUCE_22x 128*5, 16, V_Z2, V_Z2, V_Z3, V_Z3 + + Load_next_4zetas + iNTT_MREDUCE_22x 128*6, 16, V_Z0, V_Z0, V_Z1, V_Z1 + iNTT_MREDUCE_22x 128*7, 16, V_Z2, V_Z2, V_Z3, V_Z3 + +.align 4 + /* + * 5. len = 16, start = 0, 32, 64, 96, 128, 160, 192, 224 + * + * Compute coefficients of the NTT based on 2 legs, + * 0 - 16 + * 32 - 48 + * 64 - 80 + * ... + * 192 - 208 + * 224 - 240 + * + * These are indexes to the 32 bits array + */ + li 7, 64 + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 0, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 128, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 128*2, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 128*3, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 128*4, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 128*5, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 128*6, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 128*7, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + +.align 4 + /* + * 6. len = 32, start = 0, 64, 128, 192 + * + * Compute coefficients of the NTT based on 2 legs, + * 0 - 32 + * ... + * 64 - 96 + * ... + * 128 - 160 + * ... + * 192 - 224 + * ... + * + * These are indexes to the 32 bits array + */ + li 7, 128 + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 0, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 256, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 256+64, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 512, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 512+64, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 768, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 768+64, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + +.align 4 + /* + * 7. len = 64, start = 0, 128 + * + * Compute coefficients of the NTT based on 2 legs, + * 0 - 64 + * 16 - 80 + * 32 - 96 + * ... + * 128 - 192 + * 144 - 208 + * 160 - 224 + * 176 - 240 + * These are indexes to the 32 bits array + */ + li 7, 256 + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 0, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 128, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 192, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + iNTT_MREDUCE_4x 512, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 512+64, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 512+128, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 512+192, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + /* + * 8. len = 128, start = 0 + * + * Compute coefficients of the NTT based on 2 legs, + * 0 - 128 + * 16 - 144 + * 32 - 160 + * ... + * 112 - 240 + * These are indexes to the 32 bits array + */ + li 7, 512 + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + + iNTT_MREDUCE_4x 0, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64*2, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64*3, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64*4, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64*5, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64*6, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + iNTT_MREDUCE_4x 64*7, 16, V_ZETA, V_ZETA, V_ZETA, V_ZETA + + /* + * Montgomery reduce loops with constant f=41978 (mont^2/256) + * + * a[j] = montgomery_reduce((int64_t)f * a[j]) + */ + addi 10, 8, FCONST_OFFSET + lvx V_F, 0, 10 + + li 10, 16 + li 11, 32 + li 12, 48 + + mr 6, 3 + + POLY_Mont_Reduce_4x + POLY_Mont_Reduce_4x + POLY_Mont_Reduce_4x + POLY_Mont_Reduce_4x + + RESTORE_REGS + blr +.size mldsa_intt_ppc,.-mldsa_intt_ppc + +.rodata +.align 4 +mldsa_consts: +.long MLDSA_Q, MLDSA_Q, MLDSA_Q, MLDSA_Q +.long MLDSA_QINV, MLDSA_QINV, MLDSA_QINV, MLDSA_QINV +/* Constant for INTT, f=mont^2/256 */ +.long FCONST, FCONST, FCONST, FCONST + +/* zetas for qinv */ +mldsa_zetas: +/* Zetas for Lane=1: setup as (3, 2, 1, 4) order */ +.long -1400424, -1976782, -3937738, 846154, -3919660, 1362209, 554416, 48306 +.long 976891, 3545687, -183443, -1612842, 2235985, 2286327, 2939036, 420899 +.long 1104333, 3833893, 1667432, 260646, -1723600, -1910376, 426683, 1803090 +.long 975884, -472078, -2213111, -1717735, -3523897, -269760, 3038916, -3866901 +.long -1652634, 1799107, -810149, 3694233, -162844, -3014001, 3183426, -1616392 +.long -3369112, 1207385, -1957272, -185531, -2432395, 164721, 2013608, -2454455 +.long 3724270, 3776993, 2584293, -594136, 2831860, 1846953, 542412, 1671176 +.long -777191, -3406031, -1500165, -2235880, -1917081, 1374803, 1279661, 2546312 +.long -1312455, 1962642, 451100, -3306115, -1237275, 1430225, 1333058, 3318210 +.long -1869119, 1050970, 2994039, -1903435, -1250494, 3548272, 3767016, -2635921 +.long -1247620, -1595974, -4055324, -2486353, -2691481, -1265009, -2842341, 2590150 +.long 3342277, -203044, -3437287, -1735879, -286988, -4108315, -342297, 2437823 +.long 525098, 3595838, 3556995, 768622, 3122442, -3207046, 655327, -2031748 +.long 1613174, 522500, -495491, 43260, -1859098, -819034, -900702, -909542 +.long 3759364, 3193378, 3520352, 1197226, -2434439, -3513181, -266997, 1235728 +.long -2244091, 3562462, 3342478, 2446433, -3407706, -3817976, -2091667, -2316500 +/* For Len=2 */ +.long -3839961, -3839961, 3628969, 3628969, 3881060, 3881060, 3019102, 3019102 +.long 1439742, 1439742, 812732, 812732, 1584928, 1584928, -1285669, -1285669 +.long -1341330, -1341330, -1315589, -1315589, 177440, 177440, 2409325, 2409325 +.long 1851402, 1851402, -3159746, -3159746, 3553272, 3553272, -189548, -189548 +.long 1316856, 1316856, -759969, -759969, 210977, 210977, -2389356, -2389356 +.long 3249728, 3249728, -1653064, -1653064, 8578, 8578, 3724342, 3724342 +.long -3958618, -3958618, -904516, -904516, 1100098, 1100098, -44288, -44288 +.long -3097992, -3097992, -508951, -508951, -264944, -264944, 3343383, 3343383 +.long 1430430, 1430430, -1852771, -1852771, -1349076, -1349076, 381987, 381987 +.long 1308169, 1308169, 22981, 22981, 1228525, 1228525, 671102, 671102 +.long 2477047, 2477047, 411027, 411027, 3693493, 3693493, 2967645, 2967645 +.long -2715295, -2715295, -2147896, -2147896, 983419, 983419, -3412210, -3412210 +.long -126922, -126922, 3632928, 3632928, 3157330, 3157330, 3190144, 3190144 +.long 1000202, 1000202, 4083598, 4083598, -1939314, -1939314, 1257611, 1257611 +.long 1585221, 1585221, -2176455, -2176455, -3475950, -3475950, 1452451, 1452451 +.long 3041255, 3041255, 3677745, 3677745, 1528703, 1528703, 3930395, 3930395 +/* For Lane=4 */ +.long 2797779, 2797779, 2797779, 2797779, -2071892, -2071892, -2071892, -2071892 +.long 2556880, 2556880, 2556880, 2556880, -3900724, -3900724, -3900724, -3900724 +.long -3881043, -3881043, -3881043, -3881043, -954230, -954230, -954230, -954230 +.long -531354, -531354, -531354, -531354, -811944, -811944, -811944, -811944 +.long -3699596, -3699596, -3699596, -3699596, 1600420, 1600420, 1600420, 1600420 +.long 2140649, 2140649, 2140649, 2140649, -3507263, -3507263, -3507263, -3507263 +.long 3821735, 3821735, 3821735, 3821735, -3505694, -3505694, -3505694, -3505694 +.long 1643818, 1643818, 1643818, 1643818, 1699267, 1699267, 1699267, 1699267 +.long 539299, 539299, 539299, 539299, -2348700, -2348700, -2348700, -2348700 +.long 300467, 300467, 300467, 300467, -3539968, -3539968, -3539968, -3539968 +.long 2867647, 2867647, 2867647, 2867647, -3574422, -3574422, -3574422, -3574422 +.long 3043716, 3043716, 3043716, 3043716, 3861115, 3861115, 3861115, 3861115 +.long -3915439, -3915439, -3915439, -3915439, 2537516, 2537516, 2537516, 2537516 +.long 3592148, 3592148, 3592148, 3592148, 1661693, 1661693, 1661693, 1661693 +.long -3530437, -3530437, -3530437, -3530437, -3077325, -3077325, -3077325, -3077325 +.long -95776, -95776, -95776, -95776, -2706023, -2706023, -2706023, -2706023 +/* zetas for other len */ +.long -280005, -280005, -280005, -280005, -4010497, -4010497, -4010497, -4010497 +.long 19422, 19422, 19422, 19422, -1757237, -1757237, -1757237, -1757237 +.long 3277672, 3277672, 3277672, 3277672, 1399561, 1399561, 1399561, 1399561 +.long 3859737, 3859737, 3859737, 3859737, 2118186, 2118186, 2118186, 2118186 +.long 2108549, 2108549, 2108549, 2108549, -2619752, -2619752, -2619752, -2619752 +.long 1119584, 1119584, 1119584, 1119584, 549488, 549488, 549488, 549488 +.long -3585928, -3585928, -3585928, -3585928, 1079900, 1079900, 1079900, 1079900 +.long -1024112, -1024112, -1024112, -1024112, -2725464, -2725464, -2725464, -2725464 +.long -2680103, -2680103, -2680103, -2680103, -3111497, -3111497, -3111497, -3111497 +.long 2884855, 2884855, 2884855, 2884855, -3119733, -3119733, -3119733, -3119733 +.long 2091905, 2091905, 2091905, 2091905, 359251, 359251, 359251, 359251 +.long -2353451, -2353451, -2353451, -2353451, -1826347, -1826347, -1826347, -1826347 +.long -466468, -466468, -466468, -466468, 876248, 876248, 876248, 876248 +.long 777960, 777960, 777960, 777960, -237124, -237124, -237124, -237124 +.long 518909, 518909, 518909, 518909, 2608894, 2608894, 2608894, 2608894 +.long -25847, -25847, -25847, -25847 -- 2.47.3