// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC // ---------------------------------------------------------------------------- // Halve modulo p_521, z := (x / 2) mod p_521, assuming x reduced // Input x[9]; output z[9] // // extern void bignum_half_p521 // (uint64_t z[static 9], uint64_t x[static 9]); // // Standard x86-64 ABI: RDI = z, RSI = x // Microsoft x64 ABI: RCX = z, RDX = x // ---------------------------------------------------------------------------- #include "_internal_s2n_bignum.h" S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_half_p521) S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_half_p521) .text #define z %rdi #define x %rsi // We use distinct variables for clarity, but these are heavily aliased #define d0 %rcx #define d1 %rdx #define d2 %rcx #define d3 %rdx #define d4 %rcx #define d5 %rdx #define d6 %rcx #define d7 %rdx #define d8 %rcx #define a %rax #define ashort %eax S2N_BN_SYMBOL(bignum_half_p521): #if WINDOWS_ABI pushq %rdi pushq %rsi movq %rcx, %rdi movq %rdx, %rsi #endif // We do a 521-bit rotation one bit right, since 2^521 == 1 (mod p_521) movq (x), d0 movl $1, ashort andq d0, a movq 8(x), d1 shrdq $1, d1, d0 movq d0, (z) movq 16(x), d2 shrdq $1, d2, d1 movq d1, 8(z) movq 24(x), d3 shrdq $1, d3, d2 movq d2, 16(z) movq 32(x), d4 shrdq $1, d4, d3 movq d3, 24(z) movq 40(x), d5 shrdq $1, d5, d4 movq d4, 32(z) movq 48(x), d6 shrdq $1, d6, d5 movq d5, 40(z) movq 56(x), d7 shrdq $1, d7, d6 movq d6, 48(z) movq 64(x), d8 shrdq $1, d8, d7 movq d7, 56(z) shlq $55, d8 shrdq $56, a, d8 movq d8, 64(z) // Return #if WINDOWS_ABI popq %rsi popq %rdi #endif ret #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif