From b74717972baf1ae0a97085e299f2824eb9362a99 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Tue, 12 Aug 2025 10:17:36 +0000 Subject: Bring in bignum_mod{add,sub}() from s2n-bignum. These provide modular addition and subtraction. --- src/lib/libcrypto/bn/arch/amd64/bignum_modadd.S | 99 +++++++++++++++++++++++++ src/lib/libcrypto/bn/arch/amd64/bignum_modsub.S | 86 +++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 src/lib/libcrypto/bn/arch/amd64/bignum_modadd.S create mode 100644 src/lib/libcrypto/bn/arch/amd64/bignum_modsub.S (limited to 'src') diff --git a/src/lib/libcrypto/bn/arch/amd64/bignum_modadd.S b/src/lib/libcrypto/bn/arch/amd64/bignum_modadd.S new file mode 100644 index 0000000000..5d668f54ed --- /dev/null +++ b/src/lib/libcrypto/bn/arch/amd64/bignum_modadd.S @@ -0,0 +1,99 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + +// ---------------------------------------------------------------------------- +// Add modulo m, z := (x + y) mod m, assuming x and y reduced +// Inputs x[k], y[k], m[k]; output z[k] +// +// extern void bignum_modadd(uint64_t k, uint64_t *z, const uint64_t *x, +// const uint64_t *y, const uint64_t *m); +// +// Standard x86-64 ABI: RDI = k, RSI = z, RDX = x, RCX = y, R8 = m +// Microsoft x64 ABI: RCX = k, RDX = z, R8 = x, R9 = y, [RSP+40] = m +// ---------------------------------------------------------------------------- + +#include "_internal_s2n_bignum.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_modadd) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_modadd) + .text + +#define k rdi +#define z rsi +#define x rdx +#define y rcx +#define m r8 +#define i r9 +#define j r10 +#define a rax +#define c r11 + +S2N_BN_SYMBOL(bignum_modadd): + _CET_ENDBR + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 + mov r8, [rsp+56] +#endif + +// If k = 0 do nothing + + test k, k + jz bignum_modadd_end + +// First just add (c::z) := x + y + + xor c, c + mov j, k + xor i, i +bignum_modadd_addloop: + mov a, [x+8*i] + adc a, [y+8*i] + mov [z+8*i], a + inc i + dec j + jnz bignum_modadd_addloop + adc c, 0 + +// Now do a comparison subtraction (c::z) - m, recording mask for (c::z) >= m + + mov j, k + xor i, i +bignum_modadd_cmploop: + mov a, [z+8*i] + sbb a, [m+8*i] + inc i + dec j + jnz bignum_modadd_cmploop + sbb c, 0 + not c + +// Now do a masked subtraction z := z - [c] * m + + xor i, i +bignum_modadd_subloop: + mov a, [m+8*i] + and a, c + neg j + sbb [z+8*i], a + sbb j, j + inc i + cmp i, k + jc bignum_modadd_subloop + +bignum_modadd_end: +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/lib/libcrypto/bn/arch/amd64/bignum_modsub.S b/src/lib/libcrypto/bn/arch/amd64/bignum_modsub.S new file mode 100644 index 0000000000..319aa2a3db --- /dev/null +++ b/src/lib/libcrypto/bn/arch/amd64/bignum_modsub.S @@ -0,0 +1,86 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + +// ---------------------------------------------------------------------------- +// Subtract modulo m, z := (x - y) mod m, assuming x and y reduced +// Inputs x[k], y[k], m[k]; output z[k] +// +// extern void bignum_modsub(uint64_t k, uint64_t *z, const uint64_t *x, +// const uint64_t *y, const uint64_t *m); +// +// Standard x86-64 ABI: RDI = k, RSI = z, RDX = x, RCX = y, R8 = m +// Microsoft x64 ABI: RCX = k, RDX = z, R8 = x, R9 = y, [RSP+40] = m +// ---------------------------------------------------------------------------- + +#include "_internal_s2n_bignum.h" + + .intel_syntax noprefix + S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_modsub) + S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_modsub) + .text + +#define k rdi +#define z rsi +#define x rdx +#define y rcx +#define m r8 +#define i r9 +#define j r10 +#define a rax +#define c r11 + +S2N_BN_SYMBOL(bignum_modsub): + _CET_ENDBR + +#if WINDOWS_ABI + push rdi + push rsi + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + mov rcx, r9 + mov r8, [rsp+56] +#endif + +// If k = 0 do nothing + + test k, k + jz bignum_modsub_end + +// Subtract z := x - y and record a mask for the carry x - y < 0 + + xor c, c + mov j, k + xor i, i +bignum_modsub_subloop: + mov a, [x+8*i] + sbb a, [y+8*i] + mov [z+8*i], a + inc i + dec j + jnz bignum_modsub_subloop + sbb c, c + +// Now do a masked addition z := z + [c] * m + + xor i, i +bignum_modsub_addloop: + mov a, [m+8*i] + and a, c + neg j + adc [z+8*i], a + sbb j, j + inc i + cmp i, k + jc bignum_modsub_addloop + +bignum_modsub_end: +#if WINDOWS_ABI + pop rsi + pop rdi +#endif + ret + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif -- cgit v1.2.3-55-g6feb