// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC // ---------------------------------------------------------------------------- // Optionally negate modulo p_384, z := (-x) mod p_384 (if p nonzero) or // z := x (if p zero), assuming x reduced // Inputs p, x[6]; output z[6] // // extern void bignum_optneg_p384 // (uint64_t z[static 6], uint64_t p, uint64_t x[static 6]); // // Standard x86-64 ABI: RDI = z, RSI = p, RDX = x // Microsoft x64 ABI: RCX = z, RDX = p, R8 = x // ---------------------------------------------------------------------------- #include "_internal_s2n_bignum.h" S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_optneg_p384) S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_optneg_p384) .text #define z %rdi #define q %rsi #define x %rdx #define n0 %rax #define n1 %rcx #define n2 %r8 #define n3 %r9 #define n4 %r10 #define n5 %r11 #define n0short %eax S2N_BN_SYMBOL(bignum_optneg_p384): #if WINDOWS_ABI pushq %rdi pushq %rsi movq %rcx, %rdi movq %rdx, %rsi movq %r8, %rdx #endif // Adjust q by zeroing it if the input is zero (to avoid giving -0 = p_384, // which is not strictly reduced even though it's correct modulo p_384). // This step is redundant if we know a priori that the input is nonzero, which // is the case for the y coordinate of points on the P-384 curve, for example. movq (x), n0 orq 8(x), n0 movq 16(x), n1 orq 24(x), n1 movq 32(x), n2 orq 40(x), n2 orq n1, n0 orq n2, n0 negq n0 sbbq n0, n0 andq n0, q // Turn q into a bitmask, all 1s for q=false, all 0s for q=true negq q sbbq q, q notq q // Let [n5;n4;n3;n2;n1] = if q then p_384 else -1 movl $0x00000000ffffffff, n0short orq q, n0 movq $0xffffffff00000000, n1 orq q, n1 movq $0xfffffffffffffffe, n2 orq q, n2 movq $0xffffffffffffffff, n3 movq n3, n4 movq n3, n5 // Subtract so [n5;n4;n3;n2;n1;n0] = if q then p_384 - x else -1 - x subq (x), n0 sbbq 8(x), n1 sbbq 16(x), n2 sbbq 24(x), n3 sbbq 32(x), n4 sbbq 40(x), n5 // XOR the words with the bitmask, which in the case q = false has the // effect of restoring ~(-1 - x) = -(-1 - x) - 1 = 1 + x - 1 = x // and write back the digits to the output xorq q, n0 movq n0, (z) xorq q, n1 movq n1, 8(z) xorq q, n2 movq n2, 16(z) xorq q, n3 movq n3, 24(z) xorq q, n4 movq n4, 32(z) xorq q, n5 movq n5, 40(z) #if WINDOWS_ABI popq %rsi popq %rdi #endif ret #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif