First Commit
This commit is contained in:
84
externals/libressl/crypto/bn/arch/aarch64/bn_arch.h
vendored
Normal file
84
externals/libressl/crypto/bn/arch/aarch64/bn_arch.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.7 2023/04/17 12:51:09 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#define HAVE_BN_ADDW
|
||||
|
||||
static inline void
|
||||
bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG carry, r0;
|
||||
|
||||
__asm__ (
|
||||
"adds %[r0], %[a], %[b] \n"
|
||||
"cset %[carry], cs \n"
|
||||
: [carry]"=r"(carry), [r0]"=r"(r0)
|
||||
: [a]"r"(a), [b]"r"(b)
|
||||
: "cc");
|
||||
|
||||
*out_r1 = carry;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
|
||||
#define HAVE_BN_MULW
|
||||
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG r1, r0;
|
||||
|
||||
/* Unsigned multiplication using a umulh/mul pair. */
|
||||
__asm__ (
|
||||
"umulh %[r1], %[a], %[b] \n"
|
||||
"mul %[r0], %[a], %[b] \n"
|
||||
: [r1]"=&r"(r1), [r0]"=r"(r0)
|
||||
: [a]"r"(a), [b]"r"(b));
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
|
||||
#define HAVE_BN_SUBW
|
||||
|
||||
static inline void
|
||||
bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG borrow, r0;
|
||||
|
||||
__asm__ (
|
||||
"subs %[r0], %[a], %[b] \n"
|
||||
"cset %[borrow], cc \n"
|
||||
: [borrow]"=r"(borrow), [r0]"=r"(r0)
|
||||
: [a]"r"(a), [b]"r"(b)
|
||||
: "cc");
|
||||
|
||||
*out_borrow = borrow;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
165
externals/libressl/crypto/bn/arch/amd64/bignum_add.S
vendored
Normal file
165
externals/libressl/crypto/bn/arch/amd64/bignum_add.S
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Add, z := x + y
|
||||
// Inputs x[m], y[n]; outputs function return (carry-out) and z[p]
|
||||
//
|
||||
// extern uint64_t bignum_add
|
||||
// (uint64_t p, uint64_t *z,
|
||||
// uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
//
|
||||
// Does the z := x + y operation, truncating modulo p words in general and
|
||||
// returning a top carry (0 or 1) in the p'th place, only adding the input
|
||||
// words below p (as well as m and n respectively) to get the sum and carry.
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = p, RSI = z, RDX = m, RCX = x, R8 = n, R9 = y, returns RAX
|
||||
// Microsoft x64 ABI: RCX = p, RDX = z, R8 = m, R9 = x, [RSP+40] = n, [RSP+48] = y, returns RAX
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_add)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_add)
|
||||
.text
|
||||
|
||||
#define p rdi
|
||||
#define z rsi
|
||||
#define m rdx
|
||||
#define x rcx
|
||||
#define n r8
|
||||
#define y r9
|
||||
#define i r10
|
||||
#define a rax
|
||||
|
||||
#define ashort eax
|
||||
|
||||
|
||||
|
||||
S2N_BN_SYMBOL(bignum_add):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
mov rcx, r9
|
||||
mov r8, [rsp+56]
|
||||
mov r9, [rsp+64]
|
||||
#endif
|
||||
|
||||
// Zero the main index counter for both branches
|
||||
|
||||
xor i, i
|
||||
|
||||
// First clamp the two input sizes m := min(p,m) and n := min(p,n) since
|
||||
// we'll never need words past the p'th. Can now assume m <= p and n <= p.
|
||||
// Then compare the modified m and n and branch accordingly
|
||||
|
||||
cmp p, m
|
||||
cmovc m, p
|
||||
cmp p, n
|
||||
cmovc n, p
|
||||
cmp m, n
|
||||
jc ylonger
|
||||
|
||||
// The case where x is longer or of the same size (p >= m >= n)
|
||||
|
||||
sub p, m
|
||||
sub m, n
|
||||
inc m
|
||||
test n, n
|
||||
jz xtest
|
||||
xmainloop:
|
||||
mov a, [x+8*i]
|
||||
adc a, [y+8*i]
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
dec n
|
||||
jnz xmainloop
|
||||
jmp xtest
|
||||
xtoploop:
|
||||
mov a, [x+8*i]
|
||||
adc a, 0
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
xtest:
|
||||
dec m
|
||||
jnz xtoploop
|
||||
mov ashort, 0
|
||||
adc a, 0
|
||||
test p, p
|
||||
jnz tails
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
// The case where y is longer (p >= n > m)
|
||||
|
||||
ylonger:
|
||||
|
||||
sub p, n
|
||||
sub n, m
|
||||
test m, m
|
||||
jz ytoploop
|
||||
ymainloop:
|
||||
mov a, [x+8*i]
|
||||
adc a, [y+8*i]
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
dec m
|
||||
jnz ymainloop
|
||||
ytoploop:
|
||||
mov a, [y+8*i]
|
||||
adc a, 0
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
dec n
|
||||
jnz ytoploop
|
||||
mov ashort, 0
|
||||
adc a, 0
|
||||
test p, p
|
||||
jnz tails
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
// Adding a non-trivial tail, when p > max(m,n)
|
||||
|
||||
tails:
|
||||
mov [z+8*i],a
|
||||
xor a, a
|
||||
jmp tail
|
||||
tailloop:
|
||||
mov [z+8*i],a
|
||||
tail:
|
||||
inc i
|
||||
dec p
|
||||
jnz tailloop
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
155
externals/libressl/crypto/bn/arch/amd64/bignum_cmadd.S
vendored
Normal file
155
externals/libressl/crypto/bn/arch/amd64/bignum_cmadd.S
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multiply-add with single-word multiplier, z := z + c * y
|
||||
// Inputs c, y[n]; outputs function return (carry-out) and z[k]
|
||||
//
|
||||
// extern uint64_t bignum_cmadd
|
||||
// (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y);
|
||||
//
|
||||
// Does the "z := z + c * y" operation where y is n digits, result z is p.
|
||||
// Truncates the result in general.
|
||||
//
|
||||
// The return value is a high/carry word that is meaningful when p = n + 1, or
|
||||
// more generally when n <= p and the result fits in p + 1 digits. In these
|
||||
// cases it gives the top digit of the (p + 1)-digit result.
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = k, RSI = z, RDX = c, RCX = n, R8 = y, returns RAX
|
||||
// Microsoft x64 ABI: RCX = k, RDX = z, R8 = c, R9 = n, [RSP+40] = y, returns RAX
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_cmadd)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_cmadd)
|
||||
.text
|
||||
|
||||
#define p rdi
|
||||
#define z rsi
|
||||
#define c r9
|
||||
#define n rcx
|
||||
#define x r8
|
||||
|
||||
#define i r10
|
||||
#define h r11
|
||||
|
||||
#define r rbx
|
||||
|
||||
#define hshort r11d
|
||||
#define ishort r10d
|
||||
|
||||
|
||||
|
||||
S2N_BN_SYMBOL(bignum_cmadd):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
mov rcx, r9
|
||||
mov r8, [rsp+56]
|
||||
#endif
|
||||
|
||||
// Seems hard to avoid one more register
|
||||
|
||||
push rbx
|
||||
|
||||
// First clamp the input size n := min(p,n) since we can never need to read
|
||||
// past the p'th term of the input to generate p-digit output.
|
||||
// Subtract p := p - min(n,p) so it holds the size of the extra tail needed
|
||||
|
||||
cmp p, n
|
||||
cmovc n, p
|
||||
sub p, n
|
||||
|
||||
// Initialize high part h = 0; if n = 0 do nothing but return that zero
|
||||
|
||||
xor h, h
|
||||
test n, n
|
||||
jz end
|
||||
|
||||
// Move c into a safer register as multiplies overwrite rdx
|
||||
|
||||
mov c, rdx
|
||||
|
||||
// Initialization of the loop: 2^64 * CF + [h,z_0'] = z_0 + c * x_0
|
||||
|
||||
mov rax, [x]
|
||||
mul c
|
||||
add [z], rax
|
||||
mov h, rdx
|
||||
mov ishort, 1
|
||||
dec n
|
||||
jz hightail
|
||||
|
||||
// Main loop, where we always have CF + previous high part h to add in
|
||||
|
||||
loop:
|
||||
adc h, [z+8*i]
|
||||
sbb r, r
|
||||
mov rax, [x+8*i]
|
||||
mul c
|
||||
sub rdx, r
|
||||
add rax, h
|
||||
mov [z+8*i], rax
|
||||
mov h, rdx
|
||||
inc i
|
||||
dec n
|
||||
jnz loop
|
||||
|
||||
hightail:
|
||||
adc h, 0
|
||||
|
||||
// Propagate the carry all the way to the end with h as extra carry word
|
||||
|
||||
tail:
|
||||
test p, p
|
||||
jz end
|
||||
|
||||
add [z+8*i], h
|
||||
mov hshort, 0
|
||||
inc i
|
||||
dec p
|
||||
jz highend
|
||||
|
||||
tloop:
|
||||
adc [z+8*i], h
|
||||
inc i
|
||||
dec p
|
||||
jnz tloop
|
||||
|
||||
highend:
|
||||
|
||||
adc h, 0
|
||||
|
||||
// Return the high/carry word
|
||||
|
||||
end:
|
||||
mov rax, h
|
||||
|
||||
pop rbx
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
138
externals/libressl/crypto/bn/arch/amd64/bignum_cmul.S
vendored
Normal file
138
externals/libressl/crypto/bn/arch/amd64/bignum_cmul.S
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multiply by a single word, z := c * y
|
||||
// Inputs c, y[n]; outputs function return (carry-out) and z[k]
|
||||
//
|
||||
// extern uint64_t bignum_cmul
|
||||
// (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y);
|
||||
//
|
||||
// Does the "z := c * y" operation where y is n digits, result z is p.
|
||||
// Truncates the result in general unless p >= n + 1.
|
||||
//
|
||||
// The return value is a high/carry word that is meaningful when p >= n as
|
||||
// giving the high part of the result. Since this is always zero if p > n,
|
||||
// it is mainly of interest in the special case p = n, i.e. where the source
|
||||
// and destination have the same nominal size, when it gives the extra word
|
||||
// of the full result.
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = k, RSI = z, RDX = c, RCX = n, R8 = y, returns RAX
|
||||
// Microsoft x64 ABI: RCX = k, RDX = z, R8 = c, R9 = n, [RSP+40] = y, returns RAX
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_cmul)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_cmul)
|
||||
.text
|
||||
|
||||
#define p rdi
|
||||
#define z rsi
|
||||
#define c r9
|
||||
#define n rcx
|
||||
#define x r8
|
||||
|
||||
#define i r10
|
||||
#define h r11
|
||||
|
||||
|
||||
|
||||
S2N_BN_SYMBOL(bignum_cmul):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
mov rcx, r9
|
||||
mov r8, [rsp+56]
|
||||
#endif
|
||||
|
||||
// First clamp the input size n := min(p,n) since we can never need to read
|
||||
// past the p'th term of the input to generate p-digit output. Now we can
|
||||
// assume that n <= p
|
||||
|
||||
cmp p, n
|
||||
cmovc n, p
|
||||
|
||||
// Initialize current input/output pointer offset i and high part h.
|
||||
// But then if n = 0 skip the multiplication and go to the tail part
|
||||
|
||||
xor h, h
|
||||
xor i, i
|
||||
test n, n
|
||||
jz tail
|
||||
|
||||
// Move c into a safer register as multiplies overwrite rdx
|
||||
|
||||
mov c, rdx
|
||||
|
||||
// Initialization of the loop: [h,l] = c * x_0
|
||||
|
||||
mov rax, [x]
|
||||
mul c
|
||||
mov [z], rax
|
||||
mov h, rdx
|
||||
inc i
|
||||
cmp i, n
|
||||
jz tail
|
||||
|
||||
// Main loop doing the multiplications
|
||||
|
||||
loop:
|
||||
mov rax, [x+8*i]
|
||||
mul c
|
||||
add rax, h
|
||||
adc rdx, 0
|
||||
mov [z+8*i], rax
|
||||
mov h, rdx
|
||||
inc i
|
||||
cmp i, n
|
||||
jc loop
|
||||
|
||||
// Add a tail when the destination is longer
|
||||
|
||||
tail:
|
||||
cmp i, p
|
||||
jnc end
|
||||
mov [z+8*i], h
|
||||
xor h, h
|
||||
inc i
|
||||
cmp i, p
|
||||
jnc end
|
||||
|
||||
tloop:
|
||||
mov [z+8*i], h
|
||||
inc i
|
||||
cmp i, p
|
||||
jc tloop
|
||||
|
||||
// Return the high/carry word
|
||||
|
||||
end:
|
||||
mov rax, h
|
||||
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
167
externals/libressl/crypto/bn/arch/amd64/bignum_mul.S
vendored
Normal file
167
externals/libressl/crypto/bn/arch/amd64/bignum_mul.S
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multiply z := x * y
|
||||
// Inputs x[m], y[n]; output z[k]
|
||||
//
|
||||
// extern void bignum_mul
|
||||
// (uint64_t k, uint64_t *z,
|
||||
// uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
//
|
||||
// Does the "z := x * y" operation where x is m digits, y is n, result z is k.
|
||||
// Truncates the result in general unless k >= m + n
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = k, RSI = z, RDX = m, RCX = x, R8 = n, R9 = y
|
||||
// Microsoft x64 ABI: RCX = k, RDX = z, R8 = m, R9 = x, [RSP+40] = n, [RSP+48] = y
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_mul)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_mul)
|
||||
.text
|
||||
|
||||
// These are actually right
|
||||
|
||||
#define p rdi
|
||||
#define z rsi
|
||||
#define n r8
|
||||
|
||||
// These are not
|
||||
|
||||
#define c r15
|
||||
#define h r14
|
||||
#define l r13
|
||||
#define x r12
|
||||
#define y r11
|
||||
#define i rbx
|
||||
#define k r10
|
||||
#define m rbp
|
||||
|
||||
// These are always local scratch since multiplier result is in these
|
||||
|
||||
#define a rax
|
||||
#define d rdx
|
||||
|
||||
|
||||
|
||||
S2N_BN_SYMBOL(bignum_mul):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
mov rcx, r9
|
||||
mov r8, [rsp+56]
|
||||
mov r9, [rsp+64]
|
||||
#endif
|
||||
|
||||
// We use too many registers, and also we need rax:rdx for multiplications
|
||||
|
||||
push rbx
|
||||
push rbp
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
mov m, rdx
|
||||
|
||||
// If the result size is zero, do nothing
|
||||
// Note that even if either or both inputs has size zero, we can't
|
||||
// just give up because we at least need to zero the output array
|
||||
// If we did a multiply-add variant, however, then we could
|
||||
|
||||
test p, p
|
||||
jz end
|
||||
|
||||
// Set initial 2-part sum to zero (we zero c inside the body)
|
||||
|
||||
xor h,h
|
||||
xor l,l
|
||||
|
||||
// Otherwise do outer loop k = 0 ... k = p - 1
|
||||
|
||||
xor k, k
|
||||
|
||||
outerloop:
|
||||
|
||||
// Zero our carry term first; we eventually want it and a zero is useful now
|
||||
// Set a = max 0 (k + 1 - n), i = min (k + 1) m
|
||||
// This defines the range a <= j < i for the inner summation
|
||||
// Note that since k < p < 2^64 we can assume k + 1 doesn't overflow
|
||||
// And since we want to increment it anyway, we might as well do it now
|
||||
|
||||
xor c, c // c = 0
|
||||
inc k // k = k + 1
|
||||
|
||||
mov a, k // a = k + 1
|
||||
sub a, n // a = k + 1 - n
|
||||
cmovc a, c // a = max 0 (k + 1 - n)
|
||||
|
||||
mov i, m // i = m
|
||||
cmp k, m // CF <=> k + 1 < m
|
||||
cmovc i, k // i = min (k + 1) m
|
||||
|
||||
// Turn i into a loop count, and skip things if it's <= 0
|
||||
// Otherwise set up initial pointers x -> x0[a] and y -> y0[k - a]
|
||||
// and then launch into the main inner loop, postdecrementing i
|
||||
|
||||
mov d, k
|
||||
sub d, i
|
||||
sub i, a
|
||||
jbe innerend
|
||||
lea x,[rcx+8*a]
|
||||
lea y,[r9+8*d-8]
|
||||
|
||||
innerloop:
|
||||
mov rax, [y+8*i]
|
||||
mul QWORD PTR [x]
|
||||
add x, 8
|
||||
add l, rax
|
||||
adc h, rdx
|
||||
adc c, 0
|
||||
dec i
|
||||
jnz innerloop
|
||||
|
||||
innerend:
|
||||
|
||||
mov [z], l
|
||||
mov l, h
|
||||
mov h, c
|
||||
add z, 8
|
||||
|
||||
cmp k, p
|
||||
jc outerloop
|
||||
|
||||
end:
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbp
|
||||
pop rbx
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
157
externals/libressl/crypto/bn/arch/amd64/bignum_mul_4_8_alt.S
vendored
Normal file
157
externals/libressl/crypto/bn/arch/amd64/bignum_mul_4_8_alt.S
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multiply z := x * y
|
||||
// Inputs x[4], y[4]; output z[8]
|
||||
//
|
||||
// extern void bignum_mul_4_8_alt
|
||||
// (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = z, RSI = x, RDX = y
|
||||
// Microsoft x64 ABI: RCX = z, RDX = x, R8 = y
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_mul_4_8_alt)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_mul_4_8_alt)
|
||||
.text
|
||||
|
||||
// These are actually right
|
||||
|
||||
#define z rdi
|
||||
#define x rsi
|
||||
|
||||
// This is moved from rdx to free it for muls
|
||||
|
||||
#define y rcx
|
||||
|
||||
// Other variables used as a rotating 3-word window to add terms to
|
||||
|
||||
#define t0 r8
|
||||
#define t1 r9
|
||||
#define t2 r10
|
||||
|
||||
// Macro for the key "multiply and add to (c,h,l)" step
|
||||
|
||||
#define combadd(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, 0
|
||||
|
||||
// A minutely shorter form for when c = 0 initially
|
||||
|
||||
#define combadz(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, c
|
||||
|
||||
// A short form where we don't expect a top carry
|
||||
|
||||
#define combads(h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add l, rax; \
|
||||
adc h, rdx
|
||||
|
||||
S2N_BN_SYMBOL(bignum_mul_4_8_alt):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
#endif
|
||||
|
||||
// Copy y into a safe register to start with
|
||||
|
||||
mov y, rdx
|
||||
|
||||
// Result term 0
|
||||
|
||||
mov rax, [x]
|
||||
mul QWORD PTR [y]
|
||||
|
||||
mov [z], rax
|
||||
mov t0, rdx
|
||||
xor t1, t1
|
||||
|
||||
// Result term 1
|
||||
|
||||
xor t2, t2
|
||||
combads(t1,t0,[x],[y+8])
|
||||
combadz(t2,t1,t0,[x+8],[y])
|
||||
mov [z+8], t0
|
||||
|
||||
// Result term 2
|
||||
|
||||
xor t0, t0
|
||||
combadz(t0,t2,t1,[x],[y+16])
|
||||
combadd(t0,t2,t1,[x+8],[y+8])
|
||||
combadd(t0,t2,t1,[x+16],[y])
|
||||
mov [z+16], t1
|
||||
|
||||
// Result term 3
|
||||
|
||||
xor t1, t1
|
||||
combadz(t1,t0,t2,[x],[y+24])
|
||||
combadd(t1,t0,t2,[x+8],[y+16])
|
||||
combadd(t1,t0,t2,[x+16],[y+8])
|
||||
combadd(t1,t0,t2,[x+24],[y])
|
||||
mov [z+24], t2
|
||||
|
||||
// Result term 4
|
||||
|
||||
xor t2, t2
|
||||
combadz(t2,t1,t0,[x+8],[y+24])
|
||||
combadd(t2,t1,t0,[x+16],[y+16])
|
||||
combadd(t2,t1,t0,[x+24],[y+8])
|
||||
mov [z+32], t0
|
||||
|
||||
// Result term 5
|
||||
|
||||
xor t0, t0
|
||||
combadz(t0,t2,t1,[x+16],[y+24])
|
||||
combadd(t0,t2,t1,[x+24],[y+16])
|
||||
mov [z+40], t1
|
||||
|
||||
// Result term 6
|
||||
|
||||
xor t1, t1
|
||||
combads(t0,t2,[x+24],[y+24])
|
||||
mov [z+48], t2
|
||||
|
||||
// Result term 7
|
||||
|
||||
mov [z+56], t0
|
||||
|
||||
// Return
|
||||
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
244
externals/libressl/crypto/bn/arch/amd64/bignum_mul_8_16_alt.S
vendored
Normal file
244
externals/libressl/crypto/bn/arch/amd64/bignum_mul_8_16_alt.S
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multiply z := x * y
|
||||
// Inputs x[8], y[8]; output z[16]
|
||||
//
|
||||
// extern void bignum_mul_8_16_alt
|
||||
// (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]);
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = z, RSI = x, RDX = y
|
||||
// Microsoft x64 ABI: RCX = z, RDX = x, R8 = y
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_mul_8_16_alt)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_mul_8_16_alt)
|
||||
.text
|
||||
|
||||
// These are actually right
|
||||
|
||||
#define z rdi
|
||||
#define x rsi
|
||||
|
||||
// This is moved from rdx to free it for muls
|
||||
|
||||
#define y rcx
|
||||
|
||||
// Other variables used as a rotating 3-word window to add terms to
|
||||
|
||||
#define t0 r8
|
||||
#define t1 r9
|
||||
#define t2 r10
|
||||
|
||||
// Macro for the key "multiply and add to (c,h,l)" step
|
||||
|
||||
#define combadd(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, 0
|
||||
|
||||
// A minutely shorter form for when c = 0 initially
|
||||
|
||||
#define combadz(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, c
|
||||
|
||||
// A short form where we don't expect a top carry
|
||||
|
||||
#define combads(h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add l, rax; \
|
||||
adc h, rdx
|
||||
|
||||
S2N_BN_SYMBOL(bignum_mul_8_16_alt):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
#endif
|
||||
|
||||
// Copy y into a safe register to start with
|
||||
|
||||
mov y, rdx
|
||||
|
||||
// Result term 0
|
||||
|
||||
mov rax, [x]
|
||||
mul QWORD PTR [y]
|
||||
|
||||
mov [z], rax
|
||||
mov t0, rdx
|
||||
xor t1, t1
|
||||
|
||||
// Result term 1
|
||||
|
||||
xor t2, t2
|
||||
combads(t1,t0,[x],[y+8])
|
||||
combadz(t2,t1,t0,[x+8],[y])
|
||||
mov [z+8], t0
|
||||
|
||||
// Result term 2
|
||||
|
||||
xor t0, t0
|
||||
combadz(t0,t2,t1,[x],[y+16])
|
||||
combadd(t0,t2,t1,[x+8],[y+8])
|
||||
combadd(t0,t2,t1,[x+16],[y])
|
||||
mov [z+16], t1
|
||||
|
||||
// Result term 3
|
||||
|
||||
xor t1, t1
|
||||
combadz(t1,t0,t2,[x],[y+24])
|
||||
combadd(t1,t0,t2,[x+8],[y+16])
|
||||
combadd(t1,t0,t2,[x+16],[y+8])
|
||||
combadd(t1,t0,t2,[x+24],[y])
|
||||
mov [z+24], t2
|
||||
|
||||
// Result term 4
|
||||
|
||||
xor t2, t2
|
||||
combadz(t2,t1,t0,[x],[y+32])
|
||||
combadd(t2,t1,t0,[x+8],[y+24])
|
||||
combadd(t2,t1,t0,[x+16],[y+16])
|
||||
combadd(t2,t1,t0,[x+24],[y+8])
|
||||
combadd(t2,t1,t0,[x+32],[y])
|
||||
mov [z+32], t0
|
||||
|
||||
// Result term 5
|
||||
|
||||
xor t0, t0
|
||||
combadz(t0,t2,t1,[x],[y+40])
|
||||
combadd(t0,t2,t1,[x+8],[y+32])
|
||||
combadd(t0,t2,t1,[x+16],[y+24])
|
||||
combadd(t0,t2,t1,[x+24],[y+16])
|
||||
combadd(t0,t2,t1,[x+32],[y+8])
|
||||
combadd(t0,t2,t1,[x+40],[y])
|
||||
mov [z+40], t1
|
||||
|
||||
// Result term 6
|
||||
|
||||
xor t1, t1
|
||||
combadz(t1,t0,t2,[x],[y+48])
|
||||
combadd(t1,t0,t2,[x+8],[y+40])
|
||||
combadd(t1,t0,t2,[x+16],[y+32])
|
||||
combadd(t1,t0,t2,[x+24],[y+24])
|
||||
combadd(t1,t0,t2,[x+32],[y+16])
|
||||
combadd(t1,t0,t2,[x+40],[y+8])
|
||||
combadd(t1,t0,t2,[x+48],[y])
|
||||
mov [z+48], t2
|
||||
|
||||
// Result term 7
|
||||
|
||||
xor t2, t2
|
||||
combadz(t2,t1,t0,[x],[y+56])
|
||||
combadd(t2,t1,t0,[x+8],[y+48])
|
||||
combadd(t2,t1,t0,[x+16],[y+40])
|
||||
combadd(t2,t1,t0,[x+24],[y+32])
|
||||
combadd(t2,t1,t0,[x+32],[y+24])
|
||||
combadd(t2,t1,t0,[x+40],[y+16])
|
||||
combadd(t2,t1,t0,[x+48],[y+8])
|
||||
combadd(t2,t1,t0,[x+56],[y])
|
||||
mov [z+56], t0
|
||||
|
||||
// Result term 8
|
||||
|
||||
xor t0, t0
|
||||
combadz(t0,t2,t1,[x+8],[y+56])
|
||||
combadd(t0,t2,t1,[x+16],[y+48])
|
||||
combadd(t0,t2,t1,[x+24],[y+40])
|
||||
combadd(t0,t2,t1,[x+32],[y+32])
|
||||
combadd(t0,t2,t1,[x+40],[y+24])
|
||||
combadd(t0,t2,t1,[x+48],[y+16])
|
||||
combadd(t0,t2,t1,[x+56],[y+8])
|
||||
mov [z+64], t1
|
||||
|
||||
// Result term 9
|
||||
|
||||
xor t1, t1
|
||||
combadz(t1,t0,t2,[x+16],[y+56])
|
||||
combadd(t1,t0,t2,[x+24],[y+48])
|
||||
combadd(t1,t0,t2,[x+32],[y+40])
|
||||
combadd(t1,t0,t2,[x+40],[y+32])
|
||||
combadd(t1,t0,t2,[x+48],[y+24])
|
||||
combadd(t1,t0,t2,[x+56],[y+16])
|
||||
mov [z+72], t2
|
||||
|
||||
// Result term 10
|
||||
|
||||
xor t2, t2
|
||||
combadz(t2,t1,t0,[x+24],[y+56])
|
||||
combadd(t2,t1,t0,[x+32],[y+48])
|
||||
combadd(t2,t1,t0,[x+40],[y+40])
|
||||
combadd(t2,t1,t0,[x+48],[y+32])
|
||||
combadd(t2,t1,t0,[x+56],[y+24])
|
||||
mov [z+80], t0
|
||||
|
||||
// Result term 11
|
||||
|
||||
xor t0, t0
|
||||
combadz(t0,t2,t1,[x+32],[y+56])
|
||||
combadd(t0,t2,t1,[x+40],[y+48])
|
||||
combadd(t0,t2,t1,[x+48],[y+40])
|
||||
combadd(t0,t2,t1,[x+56],[y+32])
|
||||
mov [z+88], t1
|
||||
|
||||
// Result term 12
|
||||
|
||||
xor t1, t1
|
||||
combadz(t1,t0,t2,[x+40],[y+56])
|
||||
combadd(t1,t0,t2,[x+48],[y+48])
|
||||
combadd(t1,t0,t2,[x+56],[y+40])
|
||||
mov [z+96], t2
|
||||
|
||||
// Result term 13
|
||||
|
||||
xor t2, t2
|
||||
combadz(t2,t1,t0,[x+48],[y+56])
|
||||
combadd(t2,t1,t0,[x+56],[y+48])
|
||||
mov [z+104], t0
|
||||
|
||||
// Result term 14
|
||||
|
||||
combads(t2,t1,[x+56],[y+56])
|
||||
mov [z+112], t1
|
||||
|
||||
// Result term 11
|
||||
|
||||
mov [z+120], t2
|
||||
|
||||
// Return
|
||||
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
197
externals/libressl/crypto/bn/arch/amd64/bignum_sqr.S
vendored
Normal file
197
externals/libressl/crypto/bn/arch/amd64/bignum_sqr.S
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Square z := x^2
|
||||
// Input x[n]; output z[k]
|
||||
//
|
||||
// extern void bignum_sqr
|
||||
// (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x);
|
||||
//
|
||||
// Does the "z := x^2" operation where x is n digits and result z is k.
|
||||
// Truncates the result in general unless k >= 2 * n
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = k, RSI = z, RDX = n, RCX = x
|
||||
// Microsoft x64 ABI: RCX = k, RDX = z, R8 = n, R9 = x
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sqr)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sqr)
|
||||
.text
|
||||
|
||||
// First three are where arguments come in, but n is moved.
|
||||
|
||||
#define p rdi
|
||||
#define z rsi
|
||||
#define x rcx
|
||||
#define n r8
|
||||
|
||||
// These are always local scratch since multiplier result is in these
|
||||
|
||||
#define a rax
|
||||
#define d rdx
|
||||
|
||||
// Other variables
|
||||
|
||||
#define i rbx
|
||||
#define ll rbp
|
||||
#define hh r9
|
||||
#define k r10
|
||||
#define y r11
|
||||
#define htop r12
|
||||
#define l r13
|
||||
#define h r14
|
||||
#define c r15
|
||||
|
||||
// Short versions
|
||||
|
||||
#define llshort ebp
|
||||
|
||||
S2N_BN_SYMBOL(bignum_sqr):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
mov rcx, r9
|
||||
#endif
|
||||
|
||||
// We use too many registers, and also we need rax:rdx for multiplications
|
||||
|
||||
push rbx
|
||||
push rbp
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
mov n, rdx
|
||||
|
||||
// If p = 0 the result is trivial and nothing needs doing
|
||||
|
||||
test p, p
|
||||
jz end
|
||||
|
||||
// initialize (hh,ll) = 0
|
||||
|
||||
xor llshort, llshort
|
||||
xor hh, hh
|
||||
|
||||
// Iterate outer loop from k = 0 ... k = p - 1 producing result digits
|
||||
|
||||
xor k, k
|
||||
|
||||
outerloop:
|
||||
|
||||
// First let bot = MAX 0 (k + 1 - n) and top = MIN (k + 1) n
|
||||
// We want to accumulate all x[i] * x[k - i] for bot <= i < top
|
||||
// For the optimization of squaring we avoid duplication and do
|
||||
// 2 * x[i] * x[k - i] for i < htop, where htop = MIN ((k+1)/2) n
|
||||
// Initialize i = bot; in fact just compute bot as i directly.
|
||||
|
||||
xor c, c
|
||||
lea i, [k+1]
|
||||
mov htop, i
|
||||
shr htop, 1
|
||||
sub i, n
|
||||
cmovc i, c
|
||||
cmp htop, n
|
||||
cmovnc htop, n
|
||||
|
||||
// Initialize the three-part local sum (c,h,l); c was already done above
|
||||
|
||||
xor l, l
|
||||
xor h, h
|
||||
|
||||
// If htop <= bot then main doubled part of the sum is empty
|
||||
|
||||
cmp i, htop
|
||||
jnc nosumming
|
||||
|
||||
// Use a moving pointer for [y] = x[k-i] for the cofactor
|
||||
|
||||
mov a, k
|
||||
sub a, i
|
||||
lea y, [x+8*a]
|
||||
|
||||
// Do the main part of the sum x[i] * x[k - i] for 2 * i < k
|
||||
|
||||
innerloop:
|
||||
mov a, [x+8*i]
|
||||
mul QWORD PTR [y]
|
||||
add l, a
|
||||
adc h, d
|
||||
adc c, 0
|
||||
sub y, 8
|
||||
inc i
|
||||
cmp i, htop
|
||||
jc innerloop
|
||||
|
||||
// Now double it
|
||||
|
||||
add l, l
|
||||
adc h, h
|
||||
adc c, c
|
||||
|
||||
// If k is even (which means 2 * i = k) and i < n add the extra x[i]^2 term
|
||||
|
||||
nosumming:
|
||||
test k, 1
|
||||
jnz innerend
|
||||
cmp i, n
|
||||
jnc innerend
|
||||
|
||||
mov a, [x+8*i]
|
||||
mul a
|
||||
add l, a
|
||||
adc h, d
|
||||
adc c, 0
|
||||
|
||||
// Now add the local sum into the global sum, store and shift
|
||||
|
||||
innerend:
|
||||
add l, ll
|
||||
mov [z+8*k], l
|
||||
adc h, hh
|
||||
mov ll, h
|
||||
adc c, 0
|
||||
mov hh, c
|
||||
|
||||
inc k
|
||||
cmp k, p
|
||||
jc outerloop
|
||||
|
||||
// Restore registers and return
|
||||
|
||||
end:
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbp
|
||||
pop rbx
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
145
externals/libressl/crypto/bn/arch/amd64/bignum_sqr_4_8_alt.S
vendored
Normal file
145
externals/libressl/crypto/bn/arch/amd64/bignum_sqr_4_8_alt.S
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Square, z := x^2
|
||||
// Input x[4]; output z[8]
|
||||
//
|
||||
// extern void bignum_sqr_4_8_alt
|
||||
// (uint64_t z[static 8], uint64_t x[static 4]);
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = z, RSI = x
|
||||
// Microsoft x64 ABI: RCX = z, RDX = x
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sqr_4_8_alt)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sqr_4_8_alt)
|
||||
.text
|
||||
|
||||
// Input arguments
|
||||
|
||||
#define z rdi
|
||||
#define x rsi
|
||||
|
||||
// Other variables used as a rotating 3-word window to add terms to
|
||||
|
||||
#define t0 rcx
|
||||
#define t1 r8
|
||||
#define t2 r9
|
||||
|
||||
// Macro for the key "multiply and add to (c,h,l)" step, for square term
|
||||
|
||||
#define combadd1(c,h,l,numa) \
|
||||
mov rax, numa; \
|
||||
mul rax; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, 0
|
||||
|
||||
// A short form where we don't expect a top carry
|
||||
|
||||
#define combads(h,l,numa) \
|
||||
mov rax, numa; \
|
||||
mul rax; \
|
||||
add l, rax; \
|
||||
adc h, rdx
|
||||
|
||||
// A version doubling before adding, for non-square terms
|
||||
|
||||
#define combadd2(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add rax, rax; \
|
||||
adc rdx, rdx; \
|
||||
adc c, 0; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, 0
|
||||
|
||||
S2N_BN_SYMBOL(bignum_sqr_4_8_alt):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
#endif
|
||||
|
||||
// Result term 0
|
||||
|
||||
mov rax, [x]
|
||||
mul rax
|
||||
|
||||
mov [z], rax
|
||||
mov t0, rdx
|
||||
xor t1, t1
|
||||
|
||||
// Result term 1
|
||||
|
||||
xor t2, t2
|
||||
combadd2(t2,t1,t0,[x],[x+8])
|
||||
mov [z+8], t0
|
||||
|
||||
// Result term 2
|
||||
|
||||
xor t0, t0
|
||||
combadd1(t0,t2,t1,[x+8])
|
||||
combadd2(t0,t2,t1,[x],[x+16])
|
||||
mov [z+16], t1
|
||||
|
||||
// Result term 3
|
||||
|
||||
xor t1, t1
|
||||
combadd2(t1,t0,t2,[x],[x+24])
|
||||
combadd2(t1,t0,t2,[x+8],[x+16])
|
||||
mov [z+24], t2
|
||||
|
||||
// Result term 4
|
||||
|
||||
xor t2, t2
|
||||
combadd2(t2,t1,t0,[x+8],[x+24])
|
||||
combadd1(t2,t1,t0,[x+16])
|
||||
mov [z+32], t0
|
||||
|
||||
// Result term 5
|
||||
|
||||
xor t0, t0
|
||||
combadd2(t0,t2,t1,[x+16],[x+24])
|
||||
mov [z+40], t1
|
||||
|
||||
// Result term 6
|
||||
|
||||
xor t1, t1
|
||||
combads(t0,t2,[x+24])
|
||||
mov [z+48], t2
|
||||
|
||||
// Result term 7
|
||||
|
||||
mov [z+56], t0
|
||||
|
||||
// Return
|
||||
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
242
externals/libressl/crypto/bn/arch/amd64/bignum_sqr_8_16_alt.S
vendored
Normal file
242
externals/libressl/crypto/bn/arch/amd64/bignum_sqr_8_16_alt.S
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Square, z := x^2
|
||||
// Input x[8]; output z[16]
|
||||
//
|
||||
// extern void bignum_sqr_8_16_alt (uint64_t z[static 16], uint64_t x[static 8]);
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = z, RSI = x
|
||||
// Microsoft x64 ABI: RCX = z, RDX = x
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sqr_8_16_alt)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sqr_8_16_alt)
|
||||
.text
|
||||
|
||||
// Input arguments
|
||||
|
||||
#define z rdi
|
||||
#define x rsi
|
||||
|
||||
// Other variables used as a rotating 3-word window to add terms to
|
||||
|
||||
#define t0 r8
|
||||
#define t1 r9
|
||||
#define t2 r10
|
||||
|
||||
// Additional temporaries for local windows to share doublings
|
||||
|
||||
#define u0 rcx
|
||||
#define u1 r11
|
||||
|
||||
// Macro for the key "multiply and add to (c,h,l)" step
|
||||
|
||||
#define combadd(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, 0
|
||||
|
||||
// Set up initial window (c,h,l) = numa * numb
|
||||
|
||||
#define combaddz(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
xor c, c; \
|
||||
mov l, rax; \
|
||||
mov h, rdx
|
||||
|
||||
// Doubling step (c,h,l) = 2 * (c,hh,ll) + (0,h,l)
|
||||
|
||||
#define doubladd(c,h,l,hh,ll) \
|
||||
add ll, ll; \
|
||||
adc hh, hh; \
|
||||
adc c, c; \
|
||||
add l, ll; \
|
||||
adc h, hh; \
|
||||
adc c, 0
|
||||
|
||||
// Square term incorporation (c,h,l) += numba^2
|
||||
|
||||
#define combadd1(c,h,l,numa) \
|
||||
mov rax, numa; \
|
||||
mul rax; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, 0
|
||||
|
||||
// A short form where we don't expect a top carry
|
||||
|
||||
#define combads(h,l,numa) \
|
||||
mov rax, numa; \
|
||||
mul rax; \
|
||||
add l, rax; \
|
||||
adc h, rdx
|
||||
|
||||
// A version doubling directly before adding, for single non-square terms
|
||||
|
||||
#define combadd2(c,h,l,numa,numb) \
|
||||
mov rax, numa; \
|
||||
mul QWORD PTR numb; \
|
||||
add rax, rax; \
|
||||
adc rdx, rdx; \
|
||||
adc c, 0; \
|
||||
add l, rax; \
|
||||
adc h, rdx; \
|
||||
adc c, 0
|
||||
|
||||
S2N_BN_SYMBOL(bignum_sqr_8_16_alt):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
#endif
|
||||
|
||||
// Result term 0
|
||||
|
||||
mov rax, [x]
|
||||
mul rax
|
||||
|
||||
mov [z], rax
|
||||
mov t0, rdx
|
||||
xor t1, t1
|
||||
|
||||
// Result term 1
|
||||
|
||||
xor t2, t2
|
||||
combadd2(t2,t1,t0,[x],[x+8])
|
||||
mov [z+8], t0
|
||||
|
||||
// Result term 2
|
||||
|
||||
xor t0, t0
|
||||
combadd1(t0,t2,t1,[x+8])
|
||||
combadd2(t0,t2,t1,[x],[x+16])
|
||||
mov [z+16], t1
|
||||
|
||||
// Result term 3
|
||||
|
||||
combaddz(t1,u1,u0,[x],[x+24])
|
||||
combadd(t1,u1,u0,[x+8],[x+16])
|
||||
doubladd(t1,t0,t2,u1,u0)
|
||||
mov [z+24], t2
|
||||
|
||||
// Result term 4
|
||||
|
||||
combaddz(t2,u1,u0,[x],[x+32])
|
||||
combadd(t2,u1,u0,[x+8],[x+24])
|
||||
doubladd(t2,t1,t0,u1,u0)
|
||||
combadd1(t2,t1,t0,[x+16])
|
||||
mov [z+32], t0
|
||||
|
||||
// Result term 5
|
||||
|
||||
combaddz(t0,u1,u0,[x],[x+40])
|
||||
combadd(t0,u1,u0,[x+8],[x+32])
|
||||
combadd(t0,u1,u0,[x+16],[x+24])
|
||||
doubladd(t0,t2,t1,u1,u0)
|
||||
mov [z+40], t1
|
||||
|
||||
// Result term 6
|
||||
|
||||
combaddz(t1,u1,u0,[x],[x+48])
|
||||
combadd(t1,u1,u0,[x+8],[x+40])
|
||||
combadd(t1,u1,u0,[x+16],[x+32])
|
||||
doubladd(t1,t0,t2,u1,u0)
|
||||
combadd1(t1,t0,t2,[x+24])
|
||||
mov [z+48], t2
|
||||
|
||||
// Result term 7
|
||||
|
||||
combaddz(t2,u1,u0,[x],[x+56])
|
||||
combadd(t2,u1,u0,[x+8],[x+48])
|
||||
combadd(t2,u1,u0,[x+16],[x+40])
|
||||
combadd(t2,u1,u0,[x+24],[x+32])
|
||||
doubladd(t2,t1,t0,u1,u0)
|
||||
mov [z+56], t0
|
||||
|
||||
// Result term 8
|
||||
|
||||
combaddz(t0,u1,u0,[x+8],[x+56])
|
||||
combadd(t0,u1,u0,[x+16],[x+48])
|
||||
combadd(t0,u1,u0,[x+24],[x+40])
|
||||
doubladd(t0,t2,t1,u1,u0)
|
||||
combadd1(t0,t2,t1,[x+32])
|
||||
mov [z+64], t1
|
||||
|
||||
// Result term 9
|
||||
|
||||
combaddz(t1,u1,u0,[x+16],[x+56])
|
||||
combadd(t1,u1,u0,[x+24],[x+48])
|
||||
combadd(t1,u1,u0,[x+32],[x+40])
|
||||
doubladd(t1,t0,t2,u1,u0)
|
||||
mov [z+72], t2
|
||||
|
||||
// Result term 10
|
||||
|
||||
combaddz(t2,u1,u0,[x+24],[x+56])
|
||||
combadd(t2,u1,u0,[x+32],[x+48])
|
||||
doubladd(t2,t1,t0,u1,u0)
|
||||
combadd1(t2,t1,t0,[x+40])
|
||||
mov [z+80], t0
|
||||
|
||||
// Result term 11
|
||||
|
||||
combaddz(t0,u1,u0,[x+32],[x+56])
|
||||
combadd(t0,u1,u0,[x+40],[x+48])
|
||||
doubladd(t0,t2,t1,u1,u0)
|
||||
mov [z+88], t1
|
||||
|
||||
// Result term 12
|
||||
|
||||
xor t1, t1
|
||||
combadd2(t1,t0,t2,[x+40],[x+56])
|
||||
combadd1(t1,t0,t2,[x+48])
|
||||
mov [z+96], t2
|
||||
|
||||
// Result term 13
|
||||
|
||||
xor t2, t2
|
||||
combadd2(t2,t1,t0,[x+48],[x+56])
|
||||
mov [z+104], t0
|
||||
|
||||
// Result term 14
|
||||
|
||||
combads(t2,t1,[x+56])
|
||||
mov [z+112], t1
|
||||
|
||||
// Result term 15
|
||||
|
||||
mov [z+120], t2
|
||||
|
||||
// Return
|
||||
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
153
externals/libressl/crypto/bn/arch/amd64/bignum_sub.S
vendored
Normal file
153
externals/libressl/crypto/bn/arch/amd64/bignum_sub.S
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Subtract, z := x - y
|
||||
// Inputs x[m], y[n]; outputs function return (carry-out) and z[p]
|
||||
//
|
||||
// extern uint64_t bignum_sub
|
||||
// (uint64_t p, uint64_t *z,
|
||||
// uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
//
|
||||
// Does the z := x - y operation, truncating modulo p words in general and
|
||||
// returning a top borrow (0 or 1) in the p'th place, only subtracting input
|
||||
// words below p (as well as m and n respectively) to get the diff and borrow.
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = p, RSI = z, RDX = m, RCX = x, R8 = n, R9 = y, returns RAX
|
||||
// Microsoft x64 ABI: RCX = p, RDX = z, R8 = m, R9 = x, [RSP+40] = n, [RSP+48] = y, returns RAX
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_sub)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sub)
|
||||
.text
|
||||
|
||||
#define p rdi
|
||||
#define z rsi
|
||||
#define m rdx
|
||||
#define x rcx
|
||||
#define n r8
|
||||
#define y r9
|
||||
#define i r10
|
||||
#define a rax
|
||||
|
||||
#define ashort eax
|
||||
|
||||
|
||||
|
||||
S2N_BN_SYMBOL(bignum_sub):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
mov rsi, rdx
|
||||
mov rdx, r8
|
||||
mov rcx, r9
|
||||
mov r8, [rsp+56]
|
||||
mov r9, [rsp+64]
|
||||
#endif
|
||||
|
||||
// Zero the main index counter for both branches
|
||||
|
||||
xor i, i
|
||||
|
||||
// First clamp the two input sizes m := min(p,m) and n := min(p,n) since
|
||||
// we'll never need words past the p'th. Can now assume m <= p and n <= p.
|
||||
// Then compare the modified m and n and branch accordingly
|
||||
|
||||
cmp p, m
|
||||
cmovc m, p
|
||||
cmp p, n
|
||||
cmovc n, p
|
||||
cmp m, n
|
||||
jc ylonger
|
||||
|
||||
// The case where x is longer or of the same size (p >= m >= n)
|
||||
|
||||
sub p, m
|
||||
sub m, n
|
||||
inc m
|
||||
test n, n
|
||||
jz xtest
|
||||
xmainloop:
|
||||
mov a, [x+8*i]
|
||||
sbb a, [y+8*i]
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
dec n
|
||||
jnz xmainloop
|
||||
jmp xtest
|
||||
xtoploop:
|
||||
mov a, [x+8*i]
|
||||
sbb a, 0
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
xtest:
|
||||
dec m
|
||||
jnz xtoploop
|
||||
sbb a, a
|
||||
test p, p
|
||||
jz tailskip
|
||||
tailloop:
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
dec p
|
||||
jnz tailloop
|
||||
tailskip:
|
||||
neg a
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
// The case where y is longer (p >= n > m)
|
||||
|
||||
ylonger:
|
||||
|
||||
sub p, n
|
||||
sub n, m
|
||||
test m, m
|
||||
jz ytoploop
|
||||
ymainloop:
|
||||
mov a, [x+8*i]
|
||||
sbb a, [y+8*i]
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
dec m
|
||||
jnz ymainloop
|
||||
ytoploop:
|
||||
mov ashort, 0
|
||||
sbb a, [y+8*i]
|
||||
mov [z+8*i],a
|
||||
inc i
|
||||
dec n
|
||||
jnz ytoploop
|
||||
sbb a, a
|
||||
test p, p
|
||||
jnz tailloop
|
||||
neg a
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
131
externals/libressl/crypto/bn/arch/amd64/bn_arch.c
vendored
Normal file
131
externals/libressl/crypto/bn/arch/amd64/bn_arch.c
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/* $OpenBSD: bn_arch.c,v 1.6 2023/02/22 05:46:37 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "bn_arch.h"
|
||||
#include "bn_local.h"
|
||||
#include "s2n_bignum.h"
|
||||
|
||||
#ifdef HAVE_BN_ADD
|
||||
BN_ULONG
|
||||
bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b,
|
||||
int b_len)
|
||||
{
|
||||
return bignum_add(r_len, (uint64_t *)r, a_len, (uint64_t *)a,
|
||||
b_len, (uint64_t *)b);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_BN_ADD_WORDS
|
||||
BN_ULONG
|
||||
bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n)
|
||||
{
|
||||
return bignum_add(n, (uint64_t *)rd, n, (uint64_t *)ad, n,
|
||||
(uint64_t *)bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_SUB
|
||||
BN_ULONG
|
||||
bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b,
|
||||
int b_len)
|
||||
{
|
||||
return bignum_sub(r_len, (uint64_t *)r, a_len, (uint64_t *)a,
|
||||
b_len, (uint64_t *)b);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_SUB_WORDS
|
||||
BN_ULONG
|
||||
bn_sub_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n)
|
||||
{
|
||||
return bignum_sub(n, (uint64_t *)rd, n, (uint64_t *)ad, n,
|
||||
(uint64_t *)bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_MUL_ADD_WORDS
|
||||
BN_ULONG
|
||||
bn_mul_add_words(BN_ULONG *rd, const BN_ULONG *ad, int num, BN_ULONG w)
|
||||
{
|
||||
return bignum_cmadd(num, (uint64_t *)rd, w, num, (uint64_t *)ad);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_MUL_WORDS
|
||||
BN_ULONG
|
||||
bn_mul_words(BN_ULONG *rd, const BN_ULONG *ad, int num, BN_ULONG w)
|
||||
{
|
||||
return bignum_cmul(num, (uint64_t *)rd, w, num, (uint64_t *)ad);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_MUL_COMBA4
|
||||
void
|
||||
bn_mul_comba4(BN_ULONG *rd, BN_ULONG *ad, BN_ULONG *bd)
|
||||
{
|
||||
/* XXX - consider using non-alt on CPUs that have the ADX extension. */
|
||||
bignum_mul_4_8_alt((uint64_t *)rd, (uint64_t *)ad, (uint64_t *)bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_MUL_COMBA8
|
||||
void
|
||||
bn_mul_comba8(BN_ULONG *rd, BN_ULONG *ad, BN_ULONG *bd)
|
||||
{
|
||||
/* XXX - consider using non-alt on CPUs that have the ADX extension. */
|
||||
bignum_mul_8_16_alt((uint64_t *)rd, (uint64_t *)ad, (uint64_t *)bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_SQR
|
||||
int
|
||||
bn_sqr(BIGNUM *r, const BIGNUM *a, int rn, BN_CTX *ctx)
|
||||
{
|
||||
bignum_sqr(rn, (uint64_t *)r->d, a->top, (uint64_t *)a->d);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_SQR_COMBA4
|
||||
void
|
||||
bn_sqr_comba4(BN_ULONG *rd, const BN_ULONG *ad)
|
||||
{
|
||||
/* XXX - consider using non-alt on CPUs that have the ADX extension. */
|
||||
bignum_sqr_4_8_alt((uint64_t *)rd, (uint64_t *)ad);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_SQR_COMBA8
|
||||
void
|
||||
bn_sqr_comba8(BN_ULONG *rd, const BN_ULONG *ad)
|
||||
{
|
||||
/* XXX - consider using non-alt on CPUs that have the ADX extension. */
|
||||
bignum_sqr_8_16_alt((uint64_t *)rd, (uint64_t *)ad);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BN_WORD_CLZ
|
||||
int
|
||||
bn_word_clz(BN_ULONG w)
|
||||
{
|
||||
return word_clz(w);
|
||||
}
|
||||
#endif
|
||||
95
externals/libressl/crypto/bn/arch/amd64/bn_arch.h
vendored
Normal file
95
externals/libressl/crypto/bn/arch/amd64/bn_arch.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.13 2023/02/16 11:13:05 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define OPENSSL_NO_ASM
|
||||
#else
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#define HAVE_BN_ADD
|
||||
#define HAVE_BN_ADD_WORDS
|
||||
|
||||
#define HAVE_BN_DIV_WORDS
|
||||
|
||||
#define HAVE_BN_MUL_ADD_WORDS
|
||||
#define HAVE_BN_MUL_COMBA4
|
||||
#define HAVE_BN_MUL_COMBA8
|
||||
#define HAVE_BN_MUL_WORDS
|
||||
|
||||
#define HAVE_BN_SQR
|
||||
#define HAVE_BN_SQR_COMBA4
|
||||
#define HAVE_BN_SQR_COMBA8
|
||||
|
||||
#define HAVE_BN_SUB
|
||||
#define HAVE_BN_SUB_WORDS
|
||||
|
||||
#define HAVE_BN_WORD_CLZ
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define HAVE_BN_DIV_REM_WORDS_INLINE
|
||||
|
||||
static inline void
|
||||
bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
|
||||
BN_ULONG *out_r)
|
||||
{
|
||||
BN_ULONG q, r;
|
||||
|
||||
/*
|
||||
* Unsigned division of %rdx:%rax by d with quotient being stored in
|
||||
* %rax and remainder in %rdx.
|
||||
*/
|
||||
__asm__ volatile ("divq %4"
|
||||
: "=a"(q), "=d"(r)
|
||||
: "d"(h), "a"(l), "rm"(d)
|
||||
: "cc");
|
||||
|
||||
*out_q = q;
|
||||
*out_r = r;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define HAVE_BN_MULW
|
||||
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG r1, r0;
|
||||
|
||||
/*
|
||||
* Unsigned multiplication of %rax, with the double word result being
|
||||
* stored in %rdx:%rax.
|
||||
*/
|
||||
__asm__ ("mulq %3"
|
||||
: "=d"(r1), "=a"(r0)
|
||||
: "a"(a), "rm"(b)
|
||||
: "cc");
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
60
externals/libressl/crypto/bn/arch/amd64/word_clz.S
vendored
Normal file
60
externals/libressl/crypto/bn/arch/amd64/word_clz.S
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Count leading zero bits in a single word
|
||||
// Input a; output function return
|
||||
//
|
||||
// extern uint64_t word_clz (uint64_t a);
|
||||
//
|
||||
// Standard x86-64 ABI: RDI = a, returns RAX
|
||||
// Microsoft x64 ABI: RCX = a, returns RAX
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "s2n_bignum_internal.h"
|
||||
|
||||
.intel_syntax noprefix
|
||||
S2N_BN_SYM_VISIBILITY_DIRECTIVE(word_clz)
|
||||
S2N_BN_SYM_PRIVACY_DIRECTIVE(word_clz)
|
||||
.text
|
||||
|
||||
S2N_BN_SYMBOL(word_clz):
|
||||
endbr64
|
||||
|
||||
#if WINDOWS_ABI
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rcx
|
||||
#endif
|
||||
|
||||
// First do rax = 63 - bsr(a), which is right except (maybe) for zero inputs
|
||||
|
||||
bsr rax, rdi
|
||||
xor rax, 63
|
||||
|
||||
// Force return of 64 in the zero-input case
|
||||
|
||||
mov edx, 64
|
||||
test rdi, rdi
|
||||
cmove rax, rdx
|
||||
|
||||
#if WINDOWS_ABI
|
||||
pop rsi
|
||||
pop rdi
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
24
externals/libressl/crypto/bn/arch/arm/bn_arch.h
vendored
Normal file
24
externals/libressl/crypto/bn/arch/arm/bn_arch.h
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.1 2023/01/20 10:04:33 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#endif
|
||||
#endif
|
||||
86
externals/libressl/crypto/bn/arch/i386/bn_arch.h
vendored
Normal file
86
externals/libressl/crypto/bn/arch/i386/bn_arch.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.9 2023/02/16 10:41:03 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#define HAVE_BN_ADD_WORDS
|
||||
|
||||
#define HAVE_BN_DIV_WORDS
|
||||
|
||||
#define HAVE_BN_MUL_ADD_WORDS
|
||||
#define HAVE_BN_MUL_COMBA4
|
||||
#define HAVE_BN_MUL_COMBA8
|
||||
#define HAVE_BN_MUL_WORDS
|
||||
|
||||
#define HAVE_BN_SQR_COMBA4
|
||||
#define HAVE_BN_SQR_COMBA8
|
||||
#define HAVE_BN_SQR_WORDS
|
||||
|
||||
#define HAVE_BN_SUB_WORDS
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define HAVE_BN_DIV_REM_WORDS_INLINE
|
||||
|
||||
static inline void
|
||||
bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
|
||||
BN_ULONG *out_r)
|
||||
{
|
||||
BN_ULONG q, r;
|
||||
|
||||
/*
|
||||
* Unsigned division of %edx:%eax by d with quotient being stored in
|
||||
* %eax and remainder in %edx.
|
||||
*/
|
||||
__asm__ volatile ("divl %4"
|
||||
: "=a"(q), "=d"(r)
|
||||
: "a"(l), "d"(h), "rm"(d)
|
||||
: "cc");
|
||||
|
||||
*out_q = q;
|
||||
*out_r = r;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define HAVE_BN_MULW
|
||||
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG r1, r0;
|
||||
|
||||
/*
|
||||
* Unsigned multiplication of %eax, with the double word result being
|
||||
* stored in %edx:%eax.
|
||||
*/
|
||||
__asm__ ("mull %3"
|
||||
: "=d"(r1), "=a"(r0)
|
||||
: "a"(a), "rm"(b)
|
||||
: "cc");
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
24
externals/libressl/crypto/bn/arch/mips/bn_arch.h
vendored
Normal file
24
externals/libressl/crypto/bn/arch/mips/bn_arch.h
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.1 2023/01/20 10:04:34 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#endif
|
||||
#endif
|
||||
40
externals/libressl/crypto/bn/arch/mips64/bn_arch.h
vendored
Normal file
40
externals/libressl/crypto/bn/arch/mips64/bn_arch.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.7 2023/01/23 12:17:58 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#define HAVE_BN_ADD_WORDS
|
||||
|
||||
#define HAVE_BN_DIV_WORDS
|
||||
#define HAVE_BN_DIV_3_WORDS
|
||||
|
||||
#define HAVE_BN_MUL_ADD_WORDS
|
||||
#define HAVE_BN_MUL_COMBA4
|
||||
#define HAVE_BN_MUL_COMBA8
|
||||
#define HAVE_BN_MUL_WORDS
|
||||
|
||||
#define HAVE_BN_SQR_COMBA4
|
||||
#define HAVE_BN_SQR_COMBA8
|
||||
#define HAVE_BN_SQR_WORDS
|
||||
|
||||
#define HAVE_BN_SUB_WORDS
|
||||
|
||||
#endif
|
||||
#endif
|
||||
39
externals/libressl/crypto/bn/arch/powerpc/bn_arch.h
vendored
Normal file
39
externals/libressl/crypto/bn/arch/powerpc/bn_arch.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.6 2023/01/23 12:17:58 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#define HAVE_BN_ADD_WORDS
|
||||
|
||||
#define HAVE_BN_DIV_WORDS
|
||||
|
||||
#define HAVE_BN_MUL_ADD_WORDS
|
||||
#define HAVE_BN_MUL_COMBA4
|
||||
#define HAVE_BN_MUL_COMBA8
|
||||
#define HAVE_BN_MUL_WORDS
|
||||
|
||||
#define HAVE_BN_SQR_COMBA4
|
||||
#define HAVE_BN_SQR_COMBA8
|
||||
#define HAVE_BN_SQR_WORDS
|
||||
|
||||
#define HAVE_BN_SUB_WORDS
|
||||
|
||||
#endif
|
||||
#endif
|
||||
44
externals/libressl/crypto/bn/arch/powerpc64/bn_arch.h
vendored
Normal file
44
externals/libressl/crypto/bn/arch/powerpc64/bn_arch.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.4 2023/02/16 10:41:03 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#if 0 /* Needs testing and enabling. */
|
||||
#if defined(__GNUC__)
|
||||
#define HAVE_BN_MULW
|
||||
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG r1, r0;
|
||||
|
||||
/* Unsigned multiplication using a mulhdu/mul pair. */
|
||||
__asm__ ("mulhdu %0, %2, %3; mul %1, %2, %3"
|
||||
: "=&r"(r1), "=r"(r0)
|
||||
: "r"(a), "r"(b));
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
48
externals/libressl/crypto/bn/arch/riscv64/bn_arch.h
vendored
Normal file
48
externals/libressl/crypto/bn/arch/riscv64/bn_arch.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.4 2023/02/16 10:41:03 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#if 0 /* Needs testing and enabling. */
|
||||
#if defined(__GNUC__)
|
||||
#define HAVE_BN_MULW
|
||||
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG r1, r0;
|
||||
|
||||
/*
|
||||
* Unsigned multiplication using a mulh/mul pair. Note that the order
|
||||
* of these instructions is important, as they can potentially be fused
|
||||
* into a single operation.
|
||||
*/
|
||||
__asm__ ("mulh %0, %2, %3; mul %1, %2, %3"
|
||||
: "=&r"(r1), "=r"(r0)
|
||||
: "r"(a), "r"(b));
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
24
externals/libressl/crypto/bn/arch/sparc64/bn_arch.h
vendored
Normal file
24
externals/libressl/crypto/bn/arch/sparc64/bn_arch.h
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/* $OpenBSD: bn_arch.h,v 1.1 2023/01/20 10:04:34 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_ARCH_H
|
||||
#define HEADER_BN_ARCH_H
|
||||
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
|
||||
#endif
|
||||
#endif
|
||||
2162
externals/libressl/crypto/bn/bn-mips.S
vendored
Normal file
2162
externals/libressl/crypto/bn/bn-mips.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
345
externals/libressl/crypto/bn/bn_add.c
vendored
Normal file
345
externals/libressl/crypto/bn/bn_add.c
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
/* $OpenBSD: bn_add.c,v 1.24 2023/02/22 05:46:37 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_arch.h"
|
||||
#include "bn_local.h"
|
||||
#include "bn_internal.h"
|
||||
|
||||
/*
|
||||
* bn_add_words() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b
|
||||
* are both arrays of words. Any carry resulting from the addition is returned.
|
||||
*/
|
||||
#ifndef HAVE_BN_ADD_WORDS
|
||||
BN_ULONG
|
||||
bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
|
||||
{
|
||||
BN_ULONG carry = 0;
|
||||
|
||||
assert(n >= 0);
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
|
||||
#ifndef OPENSSL_SMALL_FOOTPRINT
|
||||
while (n & ~3) {
|
||||
bn_addw_addw(a[0], b[0], carry, &carry, &r[0]);
|
||||
bn_addw_addw(a[1], b[1], carry, &carry, &r[1]);
|
||||
bn_addw_addw(a[2], b[2], carry, &carry, &r[2]);
|
||||
bn_addw_addw(a[3], b[3], carry, &carry, &r[3]);
|
||||
a += 4;
|
||||
b += 4;
|
||||
r += 4;
|
||||
n -= 4;
|
||||
}
|
||||
#endif
|
||||
while (n) {
|
||||
bn_addw_addw(a[0], b[0], carry, &carry, &r[0]);
|
||||
a++;
|
||||
b++;
|
||||
r++;
|
||||
n--;
|
||||
}
|
||||
return carry;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_add() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b are both
|
||||
* arrays of words (r may be the same as a or b). The length of a and b may
|
||||
* differ, while r must be at least max(a_len, b_len) in length. Any carry
|
||||
* resulting from the addition is returned.
|
||||
*/
|
||||
#ifndef HAVE_BN_ADD
|
||||
BN_ULONG
|
||||
bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b,
|
||||
int b_len)
|
||||
{
|
||||
int min_len, diff_len;
|
||||
BN_ULONG carry = 0;
|
||||
|
||||
if ((min_len = a_len) > b_len)
|
||||
min_len = b_len;
|
||||
|
||||
diff_len = a_len - b_len;
|
||||
|
||||
carry = bn_add_words(r, a, b, min_len);
|
||||
|
||||
a += min_len;
|
||||
b += min_len;
|
||||
r += min_len;
|
||||
|
||||
/* XXX - consider doing four at a time to match bn_add_words(). */
|
||||
while (diff_len < 0) {
|
||||
/* Compute r[0] = 0 + b[0] + carry. */
|
||||
bn_addw(b[0], carry, &carry, &r[0]);
|
||||
diff_len++;
|
||||
b++;
|
||||
r++;
|
||||
}
|
||||
|
||||
/* XXX - consider doing four at a time to match bn_add_words(). */
|
||||
while (diff_len > 0) {
|
||||
/* Compute r[0] = a[0] + 0 + carry. */
|
||||
bn_addw(a[0], carry, &carry, &r[0]);
|
||||
diff_len--;
|
||||
a++;
|
||||
r++;
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_sub_words() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b
|
||||
* are both arrays of words. Any borrow resulting from the subtraction is
|
||||
* returned.
|
||||
*/
|
||||
#ifndef HAVE_BN_SUB_WORDS
|
||||
BN_ULONG
|
||||
bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
|
||||
{
|
||||
BN_ULONG borrow = 0;
|
||||
|
||||
assert(n >= 0);
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
|
||||
#ifndef OPENSSL_SMALL_FOOTPRINT
|
||||
while (n & ~3) {
|
||||
bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]);
|
||||
bn_subw_subw(a[1], b[1], borrow, &borrow, &r[1]);
|
||||
bn_subw_subw(a[2], b[2], borrow, &borrow, &r[2]);
|
||||
bn_subw_subw(a[3], b[3], borrow, &borrow, &r[3]);
|
||||
a += 4;
|
||||
b += 4;
|
||||
r += 4;
|
||||
n -= 4;
|
||||
}
|
||||
#endif
|
||||
while (n) {
|
||||
bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]);
|
||||
a++;
|
||||
b++;
|
||||
r++;
|
||||
n--;
|
||||
}
|
||||
return borrow;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_sub() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b are both
|
||||
* arrays of words (r may be the same as a or b). The length of a and b may
|
||||
* differ, while r must be at least max(a_len, b_len) in length. Any borrow
|
||||
* resulting from the subtraction is returned.
|
||||
*/
|
||||
#ifndef HAVE_BN_SUB
|
||||
BN_ULONG
|
||||
bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b,
|
||||
int b_len)
|
||||
{
|
||||
int min_len, diff_len;
|
||||
BN_ULONG borrow = 0;
|
||||
|
||||
if ((min_len = a_len) > b_len)
|
||||
min_len = b_len;
|
||||
|
||||
diff_len = a_len - b_len;
|
||||
|
||||
borrow = bn_sub_words(r, a, b, min_len);
|
||||
|
||||
a += min_len;
|
||||
b += min_len;
|
||||
r += min_len;
|
||||
|
||||
/* XXX - consider doing four at a time to match bn_sub_words. */
|
||||
while (diff_len < 0) {
|
||||
/* Compute r[0] = 0 - b[0] - borrow. */
|
||||
bn_subw(0 - b[0], borrow, &borrow, &r[0]);
|
||||
diff_len++;
|
||||
b++;
|
||||
r++;
|
||||
}
|
||||
|
||||
/* XXX - consider doing four at a time to match bn_sub_words. */
|
||||
while (diff_len > 0) {
|
||||
/* Compute r[0] = a[0] - 0 - borrow. */
|
||||
bn_subw(a[0], borrow, &borrow, &r[0]);
|
||||
diff_len--;
|
||||
a++;
|
||||
r++;
|
||||
}
|
||||
|
||||
return borrow;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
BN_ULONG carry;
|
||||
int rn;
|
||||
|
||||
if ((rn = a->top) < b->top)
|
||||
rn = b->top;
|
||||
if (rn == INT_MAX)
|
||||
return 0;
|
||||
if (!bn_wexpand(r, rn + 1))
|
||||
return 0;
|
||||
|
||||
carry = bn_add(r->d, rn, a->d, a->top, b->d, b->top);
|
||||
r->d[rn] = carry;
|
||||
|
||||
r->top = rn + (carry & 1);
|
||||
r->neg = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
BN_ULONG borrow;
|
||||
int rn;
|
||||
|
||||
if (a->top < b->top) {
|
||||
BNerror(BN_R_ARG2_LT_ARG3);
|
||||
return 0;
|
||||
}
|
||||
rn = a->top;
|
||||
|
||||
if (!bn_wexpand(r, rn))
|
||||
return 0;
|
||||
|
||||
borrow = bn_sub(r->d, rn, a->d, a->top, b->d, b->top);
|
||||
if (borrow > 0) {
|
||||
BNerror(BN_R_ARG2_LT_ARG3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r->top = rn;
|
||||
r->neg = 0;
|
||||
|
||||
bn_correct_top(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
int ret, r_neg;
|
||||
|
||||
if (a->neg == b->neg) {
|
||||
r_neg = a->neg;
|
||||
ret = BN_uadd(r, a, b);
|
||||
} else {
|
||||
int cmp = BN_ucmp(a, b);
|
||||
|
||||
if (cmp > 0) {
|
||||
r_neg = a->neg;
|
||||
ret = BN_usub(r, a, b);
|
||||
} else if (cmp < 0) {
|
||||
r_neg = b->neg;
|
||||
ret = BN_usub(r, b, a);
|
||||
} else {
|
||||
r_neg = 0;
|
||||
BN_zero(r);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
BN_set_negative(r, r_neg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
int ret, r_neg;
|
||||
|
||||
if (a->neg != b->neg) {
|
||||
r_neg = a->neg;
|
||||
ret = BN_uadd(r, a, b);
|
||||
} else {
|
||||
int cmp = BN_ucmp(a, b);
|
||||
|
||||
if (cmp > 0) {
|
||||
r_neg = a->neg;
|
||||
ret = BN_usub(r, a, b);
|
||||
} else if (cmp < 0) {
|
||||
r_neg = !b->neg;
|
||||
ret = BN_usub(r, b, a);
|
||||
} else {
|
||||
r_neg = 0;
|
||||
BN_zero(r);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
BN_set_negative(r, r_neg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
365
externals/libressl/crypto/bn/bn_blind.c
vendored
Normal file
365
externals/libressl/crypto/bn/bn_blind.c
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
/* $OpenBSD: bn_blind.c,v 1.22 2023/04/25 19:57:59 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
#define BN_BLINDING_COUNTER 32
|
||||
|
||||
struct bn_blinding_st {
|
||||
BIGNUM *A;
|
||||
BIGNUM *Ai;
|
||||
BIGNUM *e;
|
||||
BIGNUM *mod; /* just a reference */
|
||||
CRYPTO_THREADID tid;
|
||||
int counter;
|
||||
unsigned long flags;
|
||||
BN_MONT_CTX *m_ctx;
|
||||
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
||||
};
|
||||
|
||||
BN_BLINDING *
|
||||
BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
|
||||
{
|
||||
BN_BLINDING *ret = NULL;
|
||||
|
||||
|
||||
if ((ret = calloc(1, sizeof(BN_BLINDING))) == NULL) {
|
||||
BNerror(ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
if (A != NULL) {
|
||||
if ((ret->A = BN_dup(A)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
if (Ai != NULL) {
|
||||
if ((ret->Ai = BN_dup(Ai)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* save a copy of mod in the BN_BLINDING structure */
|
||||
if ((ret->mod = BN_dup(mod)) == NULL)
|
||||
goto err;
|
||||
if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
|
||||
BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
|
||||
|
||||
/* Set the counter to the special value -1
|
||||
* to indicate that this is never-used fresh blinding
|
||||
* that does not need updating before first use. */
|
||||
ret->counter = -1;
|
||||
CRYPTO_THREADID_current(&ret->tid);
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
if (ret != NULL)
|
||||
BN_BLINDING_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
BN_BLINDING_free(BN_BLINDING *r)
|
||||
{
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
||||
BN_free(r->A);
|
||||
BN_free(r->Ai);
|
||||
BN_free(r->e);
|
||||
BN_free(r->mod);
|
||||
free(r);
|
||||
}
|
||||
|
||||
int
|
||||
BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((b->A == NULL) || (b->Ai == NULL)) {
|
||||
BNerror(BN_R_NOT_INITIALIZED);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (b->counter == -1)
|
||||
b->counter = 0;
|
||||
|
||||
if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
|
||||
!(b->flags & BN_BLINDING_NO_RECREATE)) {
|
||||
/* re-create blinding parameters */
|
||||
if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
|
||||
goto err;
|
||||
} else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
|
||||
if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (b->counter == BN_BLINDING_COUNTER)
|
||||
b->counter = 0;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
|
||||
{
|
||||
return BN_BLINDING_convert_ex(n, NULL, b, ctx);
|
||||
}
|
||||
|
||||
int
|
||||
BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
|
||||
if ((b->A == NULL) || (b->Ai == NULL)) {
|
||||
BNerror(BN_R_NOT_INITIALIZED);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (b->counter == -1)
|
||||
/* Fresh blinding, doesn't need updating. */
|
||||
b->counter = 0;
|
||||
else if (!BN_BLINDING_update(b, ctx))
|
||||
return (0);
|
||||
|
||||
if (r != NULL) {
|
||||
if (!bn_copy(r, b->Ai))
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (!BN_mod_mul(n, n,b->A, b->mod, ctx))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
|
||||
{
|
||||
return BN_BLINDING_invert_ex(n, NULL, b, ctx);
|
||||
}
|
||||
|
||||
int
|
||||
BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
if (r != NULL)
|
||||
ret = BN_mod_mul(n, n, r, b->mod, ctx);
|
||||
else {
|
||||
if (b->Ai == NULL) {
|
||||
BNerror(BN_R_NOT_INITIALIZED);
|
||||
return (0);
|
||||
}
|
||||
ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
CRYPTO_THREADID *
|
||||
BN_BLINDING_thread_id(BN_BLINDING *b)
|
||||
{
|
||||
return &b->tid;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
BN_BLINDING_get_flags(const BN_BLINDING *b)
|
||||
{
|
||||
return b->flags;
|
||||
}
|
||||
|
||||
void
|
||||
BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
|
||||
{
|
||||
b->flags = flags;
|
||||
}
|
||||
|
||||
BN_BLINDING *
|
||||
BN_BLINDING_create_param(BN_BLINDING *b, const BIGNUM *e, BIGNUM *m,
|
||||
BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx)
|
||||
{
|
||||
int retry_counter = 32;
|
||||
BN_BLINDING *ret = NULL;
|
||||
|
||||
if (b == NULL)
|
||||
ret = BN_BLINDING_new(NULL, NULL, m);
|
||||
else
|
||||
ret = b;
|
||||
|
||||
if (ret == NULL)
|
||||
goto err;
|
||||
|
||||
if (ret->A == NULL && (ret->A = BN_new()) == NULL)
|
||||
goto err;
|
||||
if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (e != NULL) {
|
||||
BN_free(ret->e);
|
||||
ret->e = BN_dup(e);
|
||||
}
|
||||
if (ret->e == NULL)
|
||||
goto err;
|
||||
|
||||
if (bn_mod_exp != NULL)
|
||||
ret->bn_mod_exp = bn_mod_exp;
|
||||
if (m_ctx != NULL)
|
||||
ret->m_ctx = m_ctx;
|
||||
|
||||
do {
|
||||
if (!BN_rand_range(ret->A, ret->mod))
|
||||
goto err;
|
||||
if (BN_mod_inverse_ct(ret->Ai, ret->A, ret->mod, ctx) == NULL) {
|
||||
/* this should almost never happen for good RSA keys */
|
||||
unsigned long error = ERR_peek_last_error();
|
||||
if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
|
||||
if (retry_counter-- == 0) {
|
||||
BNerror(BN_R_TOO_MANY_ITERATIONS);
|
||||
goto err;
|
||||
}
|
||||
ERR_clear_error();
|
||||
} else
|
||||
goto err;
|
||||
} else
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
|
||||
if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod,
|
||||
ctx, ret->m_ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_exp_ct(ret->A, ret->A, ret->e, ret->mod, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (b == NULL && ret != NULL) {
|
||||
BN_BLINDING_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
539
externals/libressl/crypto/bn/bn_bpsw.c
vendored
Normal file
539
externals/libressl/crypto/bn/bn_bpsw.c
vendored
Normal file
@@ -0,0 +1,539 @@
|
||||
/* $OpenBSD: bn_bpsw.c,v 1.10 2023/05/10 21:05:24 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 Martin Grenouilloux <martin.grenouilloux@lse.epita.fr>
|
||||
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
#include "bn_prime.h"
|
||||
|
||||
/*
|
||||
* For an odd n compute a / 2 (mod n). If a is even, we can do a plain
|
||||
* division, otherwise calculate (a + n) / 2. Then reduce (mod n).
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_div_by_two_mod_odd_n(BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
if (!BN_is_odd(n))
|
||||
return 0;
|
||||
|
||||
if (BN_is_odd(a)) {
|
||||
if (!BN_add(a, a, n))
|
||||
return 0;
|
||||
}
|
||||
if (!BN_rshift1(a, a))
|
||||
return 0;
|
||||
if (!BN_mod_ct(a, a, n, ctx))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the next binary digit of k and the current Lucas terms U and V, this
|
||||
* helper computes the next terms in the Lucas sequence defined as follows:
|
||||
*
|
||||
* U' = U * V (mod n)
|
||||
* V' = (V^2 + D * U^2) / 2 (mod n)
|
||||
*
|
||||
* If digit == 0, bn_lucas_step() returns U' and V'. If digit == 1, it returns
|
||||
*
|
||||
* U'' = (U' + V') / 2 (mod n)
|
||||
* V'' = (V' + D * U') / 2 (mod n)
|
||||
*
|
||||
* Compare with FIPS 186-4, Appendix C.3.3, step 6.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_lucas_step(BIGNUM *U, BIGNUM *V, int digit, const BIGNUM *D,
|
||||
const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *tmp;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((tmp = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Calculate D * U^2 before computing U'. */
|
||||
if (!BN_sqr(tmp, U, ctx))
|
||||
goto err;
|
||||
if (!BN_mul(tmp, D, tmp, ctx))
|
||||
goto err;
|
||||
|
||||
/* U' = U * V (mod n). */
|
||||
if (!BN_mod_mul(U, U, V, n, ctx))
|
||||
goto err;
|
||||
|
||||
/* V' = (V^2 + D * U^2) / 2 (mod n). */
|
||||
if (!BN_sqr(V, V, ctx))
|
||||
goto err;
|
||||
if (!BN_add(V, V, tmp))
|
||||
goto err;
|
||||
if (!bn_div_by_two_mod_odd_n(V, n, ctx))
|
||||
goto err;
|
||||
|
||||
if (digit == 1) {
|
||||
/* Calculate D * U' before computing U''. */
|
||||
if (!BN_mul(tmp, D, U, ctx))
|
||||
goto err;
|
||||
|
||||
/* U'' = (U' + V') / 2 (mod n). */
|
||||
if (!BN_add(U, U, V))
|
||||
goto err;
|
||||
if (!bn_div_by_two_mod_odd_n(U, n, ctx))
|
||||
goto err;
|
||||
|
||||
/* V'' = (V' + D * U') / 2 (mod n). */
|
||||
if (!BN_add(V, V, tmp))
|
||||
goto err;
|
||||
if (!bn_div_by_two_mod_odd_n(V, n, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the Lucas terms U_k, V_k, see FIPS 186-4, Appendix C.3.3, steps 4-6.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_lucas(BIGNUM *U, BIGNUM *V, const BIGNUM *k, const BIGNUM *D,
|
||||
const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
int digit, i;
|
||||
int ret = 0;
|
||||
|
||||
if (!BN_one(U))
|
||||
goto err;
|
||||
if (!BN_one(V))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Iterate over the digits of k from MSB to LSB. Start at digit 2
|
||||
* since the first digit is dealt with by setting U = 1 and V = 1.
|
||||
*/
|
||||
|
||||
for (i = BN_num_bits(k) - 2; i >= 0; i--) {
|
||||
digit = BN_is_bit_set(k, i);
|
||||
|
||||
if (!bn_lucas_step(U, V, digit, D, n, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a stronger variant of the Lucas test in FIPS 186-4, Appendix C.3.3.
|
||||
* Every strong Lucas pseudoprime n is also a Lucas pseudoprime since
|
||||
* U_{n+1} == 0 follows from U_k == 0 or V_{k * 2^r} == 0 for 0 <= r < s.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_strong_lucas_test(int *is_pseudoprime, const BIGNUM *n, const BIGNUM *D,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *k, *U, *V;
|
||||
int r, s;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((k = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((U = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((V = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Factorize n + 1 = k * 2^s with odd k: shift away the s trailing ones
|
||||
* of n and set the lowest bit of the resulting number k.
|
||||
*/
|
||||
|
||||
s = 0;
|
||||
while (BN_is_bit_set(n, s))
|
||||
s++;
|
||||
if (!BN_rshift(k, n, s))
|
||||
goto err;
|
||||
if (!BN_set_bit(k, 0))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Calculate the Lucas terms U_k and V_k. If either of them is zero,
|
||||
* then n is a strong Lucas pseudoprime.
|
||||
*/
|
||||
|
||||
if (!bn_lucas(U, V, k, D, n, ctx))
|
||||
goto err;
|
||||
|
||||
if (BN_is_zero(U) || BN_is_zero(V)) {
|
||||
*is_pseudoprime = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the Lucas terms U_{k * 2^r}, V_{k * 2^r} for 1 <= r < s.
|
||||
* If any V_{k * 2^r} is zero then n is a strong Lucas pseudoprime.
|
||||
*/
|
||||
|
||||
for (r = 1; r < s; r++) {
|
||||
if (!bn_lucas_step(U, V, 0, D, n, ctx))
|
||||
goto err;
|
||||
|
||||
if (BN_is_zero(V)) {
|
||||
*is_pseudoprime = 1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we got here, n is definitely composite.
|
||||
*/
|
||||
|
||||
*is_pseudoprime = 0;
|
||||
|
||||
done:
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test n for primality using the strong Lucas test with Selfridge's Method A.
|
||||
* Returns 1 if n is prime or a strong Lucas-Selfridge pseudoprime.
|
||||
* If it returns 0 then n is definitely composite.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_strong_lucas_selfridge(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *D, *two;
|
||||
int is_perfect_square, jacobi_symbol, sign;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
/* If n is a perfect square, it is composite. */
|
||||
if (!bn_is_perfect_square(&is_perfect_square, n, ctx))
|
||||
goto err;
|
||||
if (is_perfect_square) {
|
||||
*is_pseudoprime = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first D in the Selfridge sequence 5, -7, 9, -11, 13, ...
|
||||
* such that the Jacobi symbol (D/n) is -1.
|
||||
*/
|
||||
|
||||
if ((D = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((two = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
sign = 1;
|
||||
if (!BN_set_word(D, 5))
|
||||
goto err;
|
||||
if (!BN_set_word(two, 2))
|
||||
goto err;
|
||||
|
||||
while (1) {
|
||||
/* For odd n the Kronecker symbol computes the Jacobi symbol. */
|
||||
if ((jacobi_symbol = BN_kronecker(D, n, ctx)) == -2)
|
||||
goto err;
|
||||
|
||||
/* We found the value for D. */
|
||||
if (jacobi_symbol == -1)
|
||||
break;
|
||||
|
||||
/* n and D have prime factors in common. */
|
||||
if (jacobi_symbol == 0) {
|
||||
*is_pseudoprime = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sign = -sign;
|
||||
if (!BN_uadd(D, D, two))
|
||||
goto err;
|
||||
BN_set_negative(D, sign == -1);
|
||||
}
|
||||
|
||||
if (!bn_strong_lucas_test(is_pseudoprime, n, D, ctx))
|
||||
goto err;
|
||||
|
||||
done:
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fermat criterion in Miller-Rabin test.
|
||||
*
|
||||
* Check whether 1 < base < n - 1 witnesses that n is composite. For prime n:
|
||||
*
|
||||
* * Fermat's little theorem: base^(n-1) = 1 (mod n).
|
||||
* * The only square roots of 1 (mod n) are 1 and -1.
|
||||
*
|
||||
* Calculate base^((n-1)/2) by writing n - 1 = k * 2^s with odd k. Iteratively
|
||||
* compute power = (base^k)^(2^(s-1)) by successive squaring of base^k.
|
||||
*
|
||||
* If power ever reaches -1, base^(n-1) is equal to 1 and n is a pseudoprime
|
||||
* for base. If power reaches 1 before -1 during successive squaring, we have
|
||||
* an unexpected square root of 1 and n is composite. Otherwise base^(n-1) != 1,
|
||||
* and n is composite.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_fermat(int *is_pseudoprime, const BIGNUM *n, const BIGNUM *n_minus_one,
|
||||
const BIGNUM *k, int s, const BIGNUM *base, BN_CTX *ctx, BN_MONT_CTX *mctx)
|
||||
{
|
||||
BIGNUM *power;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((power = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Sanity check: ensure that 1 < base < n - 1. */
|
||||
if (BN_cmp(base, BN_value_one()) <= 0 || BN_cmp(base, n_minus_one) >= 0)
|
||||
goto err;
|
||||
|
||||
if (!BN_mod_exp_mont_ct(power, base, k, n, ctx, mctx))
|
||||
goto err;
|
||||
|
||||
if (BN_is_one(power) || BN_cmp(power, n_minus_one) == 0) {
|
||||
*is_pseudoprime = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Loop invariant: power is neither 1 nor -1 (mod n). */
|
||||
for (i = 1; i < s; i++) {
|
||||
if (!BN_mod_sqr(power, power, n, ctx))
|
||||
goto err;
|
||||
|
||||
/* n is a pseudoprime for base. */
|
||||
if (BN_cmp(power, n_minus_one) == 0) {
|
||||
*is_pseudoprime = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* n is composite: there's a square root of unity != 1 or -1. */
|
||||
if (BN_is_one(power)) {
|
||||
*is_pseudoprime = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here, n is definitely composite: base^(n-1) != 1.
|
||||
*/
|
||||
|
||||
*is_pseudoprime = 0;
|
||||
|
||||
done:
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Miller-Rabin primality test for base 2 and for |rounds| of random bases.
|
||||
* On success: is_pseudoprime == 0 implies that n is composite.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_miller_rabin(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx,
|
||||
size_t rounds)
|
||||
{
|
||||
BN_MONT_CTX *mctx = NULL;
|
||||
BIGNUM *base, *k, *n_minus_one, *three;
|
||||
size_t i;
|
||||
int s;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((base = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((k = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((n_minus_one = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((three = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (BN_is_word(n, 2) || BN_is_word(n, 3)) {
|
||||
*is_pseudoprime = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (BN_cmp(n, BN_value_one()) <= 0 || !BN_is_odd(n)) {
|
||||
*is_pseudoprime = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!BN_sub(n_minus_one, n, BN_value_one()))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Factorize n - 1 = k * 2^s.
|
||||
*/
|
||||
|
||||
s = 0;
|
||||
while (!BN_is_bit_set(n_minus_one, s))
|
||||
s++;
|
||||
if (!BN_rshift(k, n_minus_one, s))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Montgomery setup for n.
|
||||
*/
|
||||
|
||||
if ((mctx = BN_MONT_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_MONT_CTX_set(mctx, n, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Perform a Miller-Rabin test for base 2 as required by BPSW.
|
||||
*/
|
||||
|
||||
if (!BN_set_word(base, 2))
|
||||
goto err;
|
||||
|
||||
if (!bn_fermat(is_pseudoprime, n, n_minus_one, k, s, base, ctx, mctx))
|
||||
goto err;
|
||||
if (!*is_pseudoprime)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Perform Miller-Rabin tests with random 3 <= base < n - 1 to reduce
|
||||
* risk of false positives in BPSW.
|
||||
*/
|
||||
|
||||
if (!BN_set_word(three, 3))
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < rounds; i++) {
|
||||
if (!bn_rand_interval(base, three, n_minus_one))
|
||||
goto err;
|
||||
|
||||
if (!bn_fermat(is_pseudoprime, n, n_minus_one, k, s, base, ctx,
|
||||
mctx))
|
||||
goto err;
|
||||
if (!*is_pseudoprime)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we got here, we have a Miller-Rabin pseudoprime.
|
||||
*/
|
||||
|
||||
*is_pseudoprime = 1;
|
||||
|
||||
done:
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_MONT_CTX_free(mctx);
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Baillie-Pomerance-Selfridge-Wagstaff algorithm combines a Miller-Rabin
|
||||
* test for base 2 with a Strong Lucas pseudoprime test.
|
||||
*/
|
||||
|
||||
int
|
||||
bn_is_prime_bpsw(int *is_pseudoprime, const BIGNUM *n, BN_CTX *in_ctx,
|
||||
size_t rounds)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BN_ULONG mod;
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if (BN_is_word(n, 2)) {
|
||||
*is_pseudoprime = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (BN_cmp(n, BN_value_one()) <= 0 || !BN_is_odd(n)) {
|
||||
*is_pseudoprime = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Trial divisions with the first 2048 primes. */
|
||||
for (i = 0; i < NUMPRIMES; i++) {
|
||||
if ((mod = BN_mod_word(n, primes[i])) == (BN_ULONG)-1)
|
||||
goto err;
|
||||
if (mod == 0) {
|
||||
*is_pseudoprime = BN_is_word(n, primes[i]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ctx = in_ctx) == NULL)
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
if (!bn_miller_rabin(is_pseudoprime, n, ctx, rounds))
|
||||
goto err;
|
||||
if (!*is_pseudoprime)
|
||||
goto done;
|
||||
|
||||
if (!bn_strong_lucas_selfridge(is_pseudoprime, n, ctx))
|
||||
goto err;
|
||||
|
||||
done:
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != in_ctx)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
457
externals/libressl/crypto/bn/bn_const.c
vendored
Normal file
457
externals/libressl/crypto/bn/bn_const.c
vendored
Normal file
@@ -0,0 +1,457 @@
|
||||
/* $OpenBSD: bn_const.c,v 1.5 2018/02/20 17:02:30 jsing Exp $ */
|
||||
/* Insert boilerplate */
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/* "First Oakley Default Group" from RFC2409, section 6.1.
|
||||
*
|
||||
* The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
|
||||
*
|
||||
* RFC2409 specifies a generator of 2.
|
||||
* RFC2412 specifies a generator of of 22.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc2409_prime_768(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC2409_PRIME_768[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x3A, 0x36, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc2409_prime_768(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc2409_prime_768(bn);
|
||||
}
|
||||
|
||||
/* "Second Oakley Default Group" from RFC2409, section 6.2.
|
||||
*
|
||||
* The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
|
||||
*
|
||||
* RFC2409 specifies a generator of 2.
|
||||
* RFC2412 specifies a generator of 22.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc2409_prime_1024(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC2409_PRIME_1024[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
|
||||
0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc2409_prime_1024(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc2409_prime_1024(bn);
|
||||
}
|
||||
|
||||
/* "1536-bit MODP Group" from RFC3526, Section 2.
|
||||
*
|
||||
* The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
* RFC2312 specifies a generator of 22.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc3526_prime_1536(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC3526_PRIME_1536[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
|
||||
0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
|
||||
0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
|
||||
0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
|
||||
0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc3526_prime_1536(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc3526_prime_1536(bn);
|
||||
}
|
||||
|
||||
/* "2048-bit MODP Group" from RFC3526, Section 3.
|
||||
*
|
||||
* The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc3526_prime_2048(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC3526_PRIME_2048[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
|
||||
0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
|
||||
0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
|
||||
0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
|
||||
0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
|
||||
0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
|
||||
0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc3526_prime_2048(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc3526_prime_2048(bn);
|
||||
}
|
||||
|
||||
/* "3072-bit MODP Group" from RFC3526, Section 4.
|
||||
*
|
||||
* The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc3526_prime_3072(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC3526_PRIME_3072[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
|
||||
0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
|
||||
0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
|
||||
0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
|
||||
0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
|
||||
0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
|
||||
0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
|
||||
0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
|
||||
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
|
||||
0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
|
||||
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
|
||||
0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
|
||||
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
|
||||
0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
|
||||
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
|
||||
0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
|
||||
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
|
||||
0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc3526_prime_3072(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc3526_prime_3072(bn);
|
||||
}
|
||||
|
||||
/* "4096-bit MODP Group" from RFC3526, Section 5.
|
||||
*
|
||||
* The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc3526_prime_4096(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC3526_PRIME_4096[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
|
||||
0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
|
||||
0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
|
||||
0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
|
||||
0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
|
||||
0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
|
||||
0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
|
||||
0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
|
||||
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
|
||||
0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
|
||||
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
|
||||
0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
|
||||
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
|
||||
0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
|
||||
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
|
||||
0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
|
||||
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
|
||||
0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
|
||||
0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
|
||||
0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
|
||||
0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
|
||||
0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
|
||||
0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
|
||||
0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
|
||||
0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
|
||||
0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
|
||||
0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
|
||||
0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc3526_prime_4096(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc3526_prime_4096(bn);
|
||||
}
|
||||
|
||||
/* "6144-bit MODP Group" from RFC3526, Section 6.
|
||||
*
|
||||
* The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc3526_prime_6144(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC3526_PRIME_6144[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
|
||||
0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
|
||||
0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
|
||||
0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
|
||||
0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
|
||||
0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
|
||||
0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
|
||||
0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
|
||||
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
|
||||
0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
|
||||
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
|
||||
0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
|
||||
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
|
||||
0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
|
||||
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
|
||||
0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
|
||||
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
|
||||
0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
|
||||
0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
|
||||
0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
|
||||
0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
|
||||
0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
|
||||
0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
|
||||
0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
|
||||
0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
|
||||
0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
|
||||
0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
|
||||
0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
|
||||
0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2,
|
||||
0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
|
||||
0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F,
|
||||
0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
|
||||
0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB,
|
||||
0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
|
||||
0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51,
|
||||
0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
|
||||
0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15,
|
||||
0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
|
||||
0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31,
|
||||
0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
|
||||
0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7,
|
||||
0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
|
||||
0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2,
|
||||
0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
|
||||
0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D,
|
||||
0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
|
||||
0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7,
|
||||
0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
|
||||
0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E,
|
||||
0x6D, 0xCC, 0x40, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc3526_prime_6144(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc3526_prime_6144(bn);
|
||||
}
|
||||
|
||||
/* "8192-bit MODP Group" from RFC3526, Section 7.
|
||||
*
|
||||
* The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
*/
|
||||
|
||||
BIGNUM *
|
||||
get_rfc3526_prime_8192(BIGNUM *bn)
|
||||
{
|
||||
static const unsigned char RFC3526_PRIME_8192[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
|
||||
0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
|
||||
0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
|
||||
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
|
||||
0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
|
||||
0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
|
||||
0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
|
||||
0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
|
||||
0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
|
||||
0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
|
||||
0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
|
||||
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
|
||||
0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
|
||||
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
|
||||
0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
|
||||
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
|
||||
0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
|
||||
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
|
||||
0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
|
||||
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
|
||||
0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
|
||||
0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
|
||||
0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
|
||||
0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
|
||||
0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
|
||||
0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
|
||||
0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
|
||||
0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
|
||||
0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
|
||||
0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
|
||||
0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
|
||||
0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2,
|
||||
0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
|
||||
0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F,
|
||||
0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
|
||||
0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB,
|
||||
0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
|
||||
0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51,
|
||||
0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
|
||||
0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15,
|
||||
0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
|
||||
0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31,
|
||||
0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
|
||||
0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7,
|
||||
0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
|
||||
0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2,
|
||||
0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
|
||||
0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D,
|
||||
0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
|
||||
0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7,
|
||||
0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
|
||||
0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E,
|
||||
0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
|
||||
0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0,
|
||||
0x73, 0xB9, 0x31, 0xBA, 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
|
||||
0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, 0x25, 0x76, 0xF6, 0x93,
|
||||
0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
|
||||
0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB,
|
||||
0xE3, 0x9D, 0x65, 0x2D, 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
|
||||
0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, 0x13, 0xEB, 0x57, 0xA8,
|
||||
0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
|
||||
0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F,
|
||||
0xA2, 0xC0, 0x87, 0xE8, 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
|
||||
0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, 0x6D, 0x2A, 0x13, 0xF8,
|
||||
0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
|
||||
0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5,
|
||||
0x08, 0x46, 0x85, 0x1D, 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
|
||||
0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, 0xFA, 0xF3, 0x6B, 0xC3,
|
||||
0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
|
||||
0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E,
|
||||
0xD5, 0xEE, 0x38, 0x2B, 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
|
||||
0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, 0x9E, 0x30, 0x50, 0xE2,
|
||||
0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
|
||||
0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_get_rfc3526_prime_8192(BIGNUM *bn)
|
||||
{
|
||||
return get_rfc3526_prime_8192(bn);
|
||||
}
|
||||
656
externals/libressl/crypto/bn/bn_convert.c
vendored
Normal file
656
externals/libressl/crypto/bn/bn_convert.c
vendored
Normal file
@@ -0,0 +1,656 @@
|
||||
/* $OpenBSD: bn_convert.c,v 1.8 2023/05/09 05:15:55 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
#include "bytestring.h"
|
||||
|
||||
static const char hex_digits[] = "0123456789ABCDEF";
|
||||
|
||||
typedef enum {
|
||||
big,
|
||||
little,
|
||||
} endianness_t;
|
||||
|
||||
/* ignore negative */
|
||||
static int
|
||||
bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness)
|
||||
{
|
||||
int n;
|
||||
size_t i, lasti, j, atop, mask;
|
||||
BN_ULONG l;
|
||||
|
||||
/*
|
||||
* In case |a| is fixed-top, BN_num_bytes can return bogus length,
|
||||
* but it's assumed that fixed-top inputs ought to be "nominated"
|
||||
* even for padded output, so it works out...
|
||||
*/
|
||||
n = BN_num_bytes(a);
|
||||
if (tolen == -1)
|
||||
tolen = n;
|
||||
else if (tolen < n) { /* uncommon/unlike case */
|
||||
BIGNUM temp = *a;
|
||||
|
||||
bn_correct_top(&temp);
|
||||
|
||||
n = BN_num_bytes(&temp);
|
||||
if (tolen < n)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Swipe through whole available data and don't give away padded zero. */
|
||||
atop = a->dmax * BN_BYTES;
|
||||
if (atop == 0) {
|
||||
explicit_bzero(to, tolen);
|
||||
return tolen;
|
||||
}
|
||||
|
||||
lasti = atop - 1;
|
||||
atop = a->top * BN_BYTES;
|
||||
|
||||
if (endianness == big)
|
||||
to += tolen; /* start from the end of the buffer */
|
||||
|
||||
for (i = 0, j = 0; j < (size_t)tolen; j++) {
|
||||
unsigned char val;
|
||||
|
||||
l = a->d[i / BN_BYTES];
|
||||
mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
|
||||
val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
|
||||
|
||||
if (endianness == big)
|
||||
*--to = val;
|
||||
else
|
||||
*to++ = val;
|
||||
|
||||
i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
|
||||
}
|
||||
|
||||
return tolen;
|
||||
}
|
||||
|
||||
int
|
||||
BN_bn2bin(const BIGNUM *a, unsigned char *to)
|
||||
{
|
||||
return bn2binpad(a, to, -1, big);
|
||||
}
|
||||
|
||||
int
|
||||
BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
|
||||
{
|
||||
if (tolen < 0)
|
||||
return -1;
|
||||
return bn2binpad(a, to, tolen, big);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
|
||||
{
|
||||
unsigned int i, m;
|
||||
unsigned int n;
|
||||
BN_ULONG l;
|
||||
BIGNUM *bn = NULL;
|
||||
|
||||
if (len < 0)
|
||||
return (NULL);
|
||||
if (ret == NULL)
|
||||
ret = bn = BN_new();
|
||||
if (ret == NULL)
|
||||
return (NULL);
|
||||
l = 0;
|
||||
n = len;
|
||||
if (n == 0) {
|
||||
ret->top = 0;
|
||||
return (ret);
|
||||
}
|
||||
i = ((n - 1) / BN_BYTES) + 1;
|
||||
m = ((n - 1) % (BN_BYTES));
|
||||
if (!bn_wexpand(ret, (int)i)) {
|
||||
BN_free(bn);
|
||||
return NULL;
|
||||
}
|
||||
ret->top = i;
|
||||
ret->neg = 0;
|
||||
while (n--) {
|
||||
l = (l << 8L) | *(s++);
|
||||
if (m-- == 0) {
|
||||
ret->d[--i] = l;
|
||||
l = 0;
|
||||
m = BN_BYTES - 1;
|
||||
}
|
||||
}
|
||||
/* need to call this due to clear byte at top if avoiding
|
||||
* having the top bit set (-ve number) */
|
||||
bn_correct_top(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
|
||||
{
|
||||
if (tolen < 0)
|
||||
return -1;
|
||||
|
||||
return bn2binpad(a, to, tolen, little);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
|
||||
{
|
||||
unsigned int i, m, n;
|
||||
BN_ULONG l;
|
||||
BIGNUM *bn = NULL;
|
||||
|
||||
if (ret == NULL)
|
||||
ret = bn = BN_new();
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
s += len;
|
||||
/* Skip trailing zeroes. */
|
||||
for (; len > 0 && s[-1] == 0; s--, len--)
|
||||
continue;
|
||||
|
||||
n = len;
|
||||
if (n == 0) {
|
||||
ret->top = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
i = ((n - 1) / BN_BYTES) + 1;
|
||||
m = (n - 1) % BN_BYTES;
|
||||
if (!bn_wexpand(ret, (int)i)) {
|
||||
BN_free(bn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->top = i;
|
||||
ret->neg = 0;
|
||||
l = 0;
|
||||
while (n-- > 0) {
|
||||
s--;
|
||||
l = (l << 8L) | *s;
|
||||
if (m-- == 0) {
|
||||
ret->d[--i] = l;
|
||||
l = 0;
|
||||
m = BN_BYTES - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* need to call this due to clear byte at top if avoiding having the
|
||||
* top bit set (-ve number)
|
||||
*/
|
||||
bn_correct_top(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
BN_asc2bn(BIGNUM **bn, const char *a)
|
||||
{
|
||||
const char *p = a;
|
||||
if (*p == '-')
|
||||
p++;
|
||||
|
||||
if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) {
|
||||
if (!BN_hex2bn(bn, p + 2))
|
||||
return 0;
|
||||
} else {
|
||||
if (!BN_dec2bn(bn, p))
|
||||
return 0;
|
||||
}
|
||||
if (*a == '-')
|
||||
BN_set_negative(*bn, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *
|
||||
BN_bn2dec(const BIGNUM *bn)
|
||||
{
|
||||
int started = 0;
|
||||
BIGNUM *tmp = NULL;
|
||||
uint8_t *data = NULL;
|
||||
size_t data_len = 0;
|
||||
uint8_t *s = NULL;
|
||||
size_t s_len;
|
||||
BN_ULONG v, w;
|
||||
uint8_t c;
|
||||
CBB cbb;
|
||||
CBS cbs;
|
||||
int i;
|
||||
|
||||
if (!CBB_init(&cbb, 0))
|
||||
goto err;
|
||||
|
||||
if ((tmp = BN_dup(bn)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Divide the BIGNUM by a large multiple of 10, then break the remainder
|
||||
* into decimal digits. This produces a reversed string of digits,
|
||||
* potentially with leading zeroes.
|
||||
*/
|
||||
while (!BN_is_zero(tmp)) {
|
||||
if ((w = BN_div_word(tmp, BN_DEC_CONV)) == -1)
|
||||
goto err;
|
||||
for (i = 0; i < BN_DEC_NUM; i++) {
|
||||
v = w % 10;
|
||||
if (!CBB_add_u8(&cbb, '0' + v))
|
||||
goto err;
|
||||
w /= 10;
|
||||
}
|
||||
}
|
||||
if (!CBB_finish(&cbb, &data, &data_len))
|
||||
goto err;
|
||||
|
||||
if (data_len > SIZE_MAX - 3)
|
||||
goto err;
|
||||
if (!CBB_init(&cbb, data_len + 3))
|
||||
goto err;
|
||||
|
||||
if (BN_is_negative(bn)) {
|
||||
if (!CBB_add_u8(&cbb, '-'))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Reverse digits and trim leading zeroes. */
|
||||
CBS_init(&cbs, data, data_len);
|
||||
while (CBS_len(&cbs) > 0) {
|
||||
if (!CBS_get_last_u8(&cbs, &c))
|
||||
goto err;
|
||||
if (!started && c == '0')
|
||||
continue;
|
||||
if (!CBB_add_u8(&cbb, c))
|
||||
goto err;
|
||||
started = 1;
|
||||
}
|
||||
|
||||
if (!started) {
|
||||
if (!CBB_add_u8(&cbb, '0'))
|
||||
goto err;
|
||||
}
|
||||
if (!CBB_add_u8(&cbb, '\0'))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, &s, &s_len))
|
||||
goto err;
|
||||
|
||||
err:
|
||||
BN_free(tmp);
|
||||
CBB_cleanup(&cbb);
|
||||
freezero(data, data_len);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
BN_dec2bn(BIGNUM **bn, const char *a)
|
||||
{
|
||||
BIGNUM *ret = NULL;
|
||||
BN_ULONG l = 0;
|
||||
int neg = 0, i, j;
|
||||
int num;
|
||||
|
||||
if ((a == NULL) || (*a == '\0'))
|
||||
return (0);
|
||||
if (*a == '-') {
|
||||
neg = 1;
|
||||
a++;
|
||||
}
|
||||
|
||||
for (i = 0; i <= (INT_MAX / 4) && isdigit((unsigned char)a[i]); i++)
|
||||
;
|
||||
if (i > INT_MAX / 4)
|
||||
return (0);
|
||||
|
||||
num = i + neg;
|
||||
if (bn == NULL)
|
||||
return (num);
|
||||
|
||||
/* a is the start of the digits, and it is 'i' long.
|
||||
* We chop it into BN_DEC_NUM digits at a time */
|
||||
if (*bn == NULL) {
|
||||
if ((ret = BN_new()) == NULL)
|
||||
return (0);
|
||||
} else {
|
||||
ret = *bn;
|
||||
BN_zero(ret);
|
||||
}
|
||||
|
||||
/* i is the number of digits, a bit of an over expand */
|
||||
if (!bn_expand(ret, i * 4))
|
||||
goto err;
|
||||
|
||||
j = BN_DEC_NUM - (i % BN_DEC_NUM);
|
||||
if (j == BN_DEC_NUM)
|
||||
j = 0;
|
||||
l = 0;
|
||||
while (*a) {
|
||||
l *= 10;
|
||||
l += *a - '0';
|
||||
a++;
|
||||
if (++j == BN_DEC_NUM) {
|
||||
if (!BN_mul_word(ret, BN_DEC_CONV))
|
||||
goto err;
|
||||
if (!BN_add_word(ret, l))
|
||||
goto err;
|
||||
l = 0;
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bn_correct_top(ret);
|
||||
|
||||
BN_set_negative(ret, neg);
|
||||
|
||||
*bn = ret;
|
||||
return (num);
|
||||
|
||||
err:
|
||||
if (*bn == NULL)
|
||||
BN_free(ret);
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
BN_bn2hex(const BIGNUM *bn)
|
||||
{
|
||||
int started = 0;
|
||||
uint8_t *s = NULL;
|
||||
size_t s_len;
|
||||
BN_ULONG v, w;
|
||||
int i, j;
|
||||
CBB cbb;
|
||||
|
||||
if (!CBB_init(&cbb, 0))
|
||||
goto err;
|
||||
|
||||
if (BN_is_negative(bn)) {
|
||||
if (!CBB_add_u8(&cbb, '-'))
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_zero(bn)) {
|
||||
if (!CBB_add_u8(&cbb, '0'))
|
||||
goto err;
|
||||
}
|
||||
for (i = bn->top - 1; i >= 0; i--) {
|
||||
w = bn->d[i];
|
||||
for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
|
||||
v = (w >> j) & 0xff;
|
||||
if (!started && v == 0)
|
||||
continue;
|
||||
if (!CBB_add_u8(&cbb, hex_digits[v >> 4]))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&cbb, hex_digits[v & 0xf]))
|
||||
goto err;
|
||||
started = 1;
|
||||
}
|
||||
}
|
||||
if (!CBB_add_u8(&cbb, '\0'))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, &s, &s_len))
|
||||
goto err;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
BN_hex2bn(BIGNUM **bn, const char *a)
|
||||
{
|
||||
BIGNUM *ret = NULL;
|
||||
BN_ULONG l = 0;
|
||||
int neg = 0, h, m, i,j, k, c;
|
||||
int num;
|
||||
|
||||
if ((a == NULL) || (*a == '\0'))
|
||||
return (0);
|
||||
|
||||
if (*a == '-') {
|
||||
neg = 1;
|
||||
a++;
|
||||
}
|
||||
|
||||
for (i = 0; i <= (INT_MAX / 4) && isxdigit((unsigned char)a[i]); i++)
|
||||
;
|
||||
if (i > INT_MAX / 4)
|
||||
return (0);
|
||||
|
||||
num = i + neg;
|
||||
if (bn == NULL)
|
||||
return (num);
|
||||
|
||||
/* a is the start of the hex digits, and it is 'i' long */
|
||||
if (*bn == NULL) {
|
||||
if ((ret = BN_new()) == NULL)
|
||||
return (0);
|
||||
} else {
|
||||
ret = *bn;
|
||||
BN_zero(ret);
|
||||
}
|
||||
|
||||
/* i is the number of hex digits */
|
||||
if (!bn_expand(ret, i * 4))
|
||||
goto err;
|
||||
|
||||
j = i; /* least significant 'hex' */
|
||||
m = 0;
|
||||
h = 0;
|
||||
while (j > 0) {
|
||||
m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
|
||||
l = 0;
|
||||
for (;;) {
|
||||
c = a[j - m];
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
k = c - '0';
|
||||
else if ((c >= 'a') && (c <= 'f'))
|
||||
k = c - 'a' + 10;
|
||||
else if ((c >= 'A') && (c <= 'F'))
|
||||
k = c - 'A' + 10;
|
||||
else
|
||||
k = 0; /* paranoia */
|
||||
l = (l << 4) | k;
|
||||
|
||||
if (--m <= 0) {
|
||||
ret->d[h++] = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
j -= (BN_BYTES * 2);
|
||||
}
|
||||
ret->top = h;
|
||||
bn_correct_top(ret);
|
||||
|
||||
BN_set_negative(ret, neg);
|
||||
|
||||
*bn = ret;
|
||||
return (num);
|
||||
|
||||
err:
|
||||
if (*bn == NULL)
|
||||
BN_free(ret);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
BN_bn2mpi(const BIGNUM *a, unsigned char *d)
|
||||
{
|
||||
int bits;
|
||||
int num = 0;
|
||||
int ext = 0;
|
||||
long l;
|
||||
|
||||
bits = BN_num_bits(a);
|
||||
num = (bits + 7) / 8;
|
||||
if (bits > 0) {
|
||||
ext = ((bits & 0x07) == 0);
|
||||
}
|
||||
if (d == NULL)
|
||||
return (num + 4 + ext);
|
||||
|
||||
l = num + ext;
|
||||
d[0] = (unsigned char)(l >> 24) & 0xff;
|
||||
d[1] = (unsigned char)(l >> 16) & 0xff;
|
||||
d[2] = (unsigned char)(l >> 8) & 0xff;
|
||||
d[3] = (unsigned char)(l) & 0xff;
|
||||
if (ext)
|
||||
d[4] = 0;
|
||||
num = BN_bn2bin(a, &(d[4 + ext]));
|
||||
if (a->neg)
|
||||
d[4] |= 0x80;
|
||||
return (num + 4 + ext);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain)
|
||||
{
|
||||
BIGNUM *a = ain;
|
||||
long len;
|
||||
int neg = 0;
|
||||
|
||||
if (n < 4) {
|
||||
BNerror(BN_R_INVALID_LENGTH);
|
||||
return (NULL);
|
||||
}
|
||||
len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) |
|
||||
(int)d[3];
|
||||
if ((len + 4) != n) {
|
||||
BNerror(BN_R_ENCODING_ERROR);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (a == NULL)
|
||||
a = BN_new();
|
||||
if (a == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (len == 0) {
|
||||
a->neg = 0;
|
||||
a->top = 0;
|
||||
return (a);
|
||||
}
|
||||
d += 4;
|
||||
if ((*d) & 0x80)
|
||||
neg = 1;
|
||||
if (BN_bin2bn(d, (int)len, a) == NULL) {
|
||||
if (ain == NULL)
|
||||
BN_free(a);
|
||||
return (NULL);
|
||||
}
|
||||
BN_set_negative(a, neg);
|
||||
if (neg) {
|
||||
BN_clear_bit(a, BN_num_bits(a) - 1);
|
||||
}
|
||||
return (a);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_BIO
|
||||
int
|
||||
BN_print_fp(FILE *fp, const BIGNUM *a)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL)
|
||||
return (0);
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = BN_print(b, a);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_print(BIO *bp, const BIGNUM *a)
|
||||
{
|
||||
int i, j, v, z = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((a->neg) && (BIO_write(bp, "-", 1) != 1))
|
||||
goto end;
|
||||
if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))
|
||||
goto end;
|
||||
for (i = a->top - 1; i >= 0; i--) {
|
||||
for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
|
||||
/* strip leading zeros */
|
||||
v = ((int)(a->d[i] >> (long)j)) & 0x0f;
|
||||
if (z || (v != 0)) {
|
||||
if (BIO_write(bp, &hex_digits[v], 1) != 1)
|
||||
goto end;
|
||||
z = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
end:
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
156
externals/libressl/crypto/bn/bn_ctx.c
vendored
Normal file
156
externals/libressl/crypto/bn/bn_ctx.c
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/* $OpenBSD: bn_ctx.c,v 1.21 2023/04/25 16:41:29 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
#define BN_CTX_INITIAL_LEN 8
|
||||
|
||||
struct bignum_ctx {
|
||||
BIGNUM **bignums;
|
||||
uint8_t *groups;
|
||||
uint8_t group;
|
||||
size_t index;
|
||||
size_t len;
|
||||
|
||||
int error;
|
||||
};
|
||||
|
||||
static int
|
||||
bn_ctx_grow(BN_CTX *bctx)
|
||||
{
|
||||
BIGNUM **bignums = NULL;
|
||||
uint8_t *groups = NULL;
|
||||
size_t len;
|
||||
|
||||
if ((len = bctx->len) == 0) {
|
||||
len = BN_CTX_INITIAL_LEN;
|
||||
} else {
|
||||
if (SIZE_MAX - len < len)
|
||||
return 0;
|
||||
len *= 2;
|
||||
}
|
||||
|
||||
if ((bignums = recallocarray(bctx->bignums, bctx->len, len,
|
||||
sizeof(bctx->bignums[0]))) == NULL)
|
||||
return 0;
|
||||
bctx->bignums = bignums;
|
||||
|
||||
if ((groups = reallocarray(bctx->groups, len,
|
||||
sizeof(bctx->groups[0]))) == NULL)
|
||||
return 0;
|
||||
bctx->groups = groups;
|
||||
|
||||
bctx->len = len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BN_CTX *
|
||||
BN_CTX_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(struct bignum_ctx));
|
||||
}
|
||||
|
||||
void
|
||||
BN_CTX_free(BN_CTX *bctx)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (bctx == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < bctx->len; i++) {
|
||||
BN_free(bctx->bignums[i]);
|
||||
bctx->bignums[i] = NULL;
|
||||
}
|
||||
|
||||
free(bctx->bignums);
|
||||
free(bctx->groups);
|
||||
|
||||
freezero(bctx, sizeof(*bctx));
|
||||
}
|
||||
|
||||
void
|
||||
BN_CTX_start(BN_CTX *bctx)
|
||||
{
|
||||
bctx->group++;
|
||||
|
||||
if (bctx->group == 0) {
|
||||
BNerror(BN_R_TOO_MANY_TEMPORARY_VARIABLES);
|
||||
bctx->error = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_CTX_get(BN_CTX *bctx)
|
||||
{
|
||||
BIGNUM *bn = NULL;
|
||||
|
||||
if (bctx->error)
|
||||
return NULL;
|
||||
|
||||
if (bctx->group == 0) {
|
||||
BNerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
bctx->error = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bctx->index == bctx->len) {
|
||||
if (!bn_ctx_grow(bctx)) {
|
||||
BNerror(BN_R_TOO_MANY_TEMPORARY_VARIABLES);
|
||||
bctx->error = 1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((bn = bctx->bignums[bctx->index]) == NULL) {
|
||||
if ((bn = BN_new()) == NULL) {
|
||||
BNerror(BN_R_TOO_MANY_TEMPORARY_VARIABLES);
|
||||
bctx->error = 1;
|
||||
return NULL;
|
||||
}
|
||||
bctx->bignums[bctx->index] = bn;
|
||||
}
|
||||
bctx->groups[bctx->index] = bctx->group;
|
||||
bctx->index++;
|
||||
|
||||
BN_zero(bn);
|
||||
|
||||
return bn;
|
||||
}
|
||||
|
||||
void
|
||||
BN_CTX_end(BN_CTX *bctx)
|
||||
{
|
||||
if (bctx == NULL || bctx->error || bctx->group == 0)
|
||||
return;
|
||||
|
||||
while (bctx->index > 0 && bctx->groups[bctx->index - 1] == bctx->group) {
|
||||
BN_zero(bctx->bignums[bctx->index - 1]);
|
||||
bctx->groups[bctx->index - 1] = 0;
|
||||
bctx->index--;
|
||||
}
|
||||
|
||||
bctx->group--;
|
||||
}
|
||||
457
externals/libressl/crypto/bn/bn_div.c
vendored
Normal file
457
externals/libressl/crypto/bn/bn_div.c
vendored
Normal file
@@ -0,0 +1,457 @@
|
||||
/* $OpenBSD: bn_div.c,v 1.40 2023/03/27 10:21:23 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_arch.h"
|
||||
#include "bn_local.h"
|
||||
#include "bn_internal.h"
|
||||
|
||||
BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0);
|
||||
|
||||
#ifndef HAVE_BN_DIV_WORDS
|
||||
#if defined(BN_LLONG) && defined(BN_DIV2W)
|
||||
|
||||
BN_ULONG
|
||||
bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
|
||||
{
|
||||
return ((BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2)|l)/(BN_ULLONG)d));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Divide h,l by d and return the result. */
|
||||
/* I need to test this some more :-( */
|
||||
BN_ULONG
|
||||
bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
|
||||
{
|
||||
BN_ULONG dh, dl, q,ret = 0, th, tl, t;
|
||||
int i, count = 2;
|
||||
|
||||
if (d == 0)
|
||||
return (BN_MASK2);
|
||||
|
||||
i = BN_num_bits_word(d);
|
||||
assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
|
||||
|
||||
i = BN_BITS2 - i;
|
||||
if (h >= d)
|
||||
h -= d;
|
||||
|
||||
if (i) {
|
||||
d <<= i;
|
||||
h = (h << i) | (l >> (BN_BITS2 - i));
|
||||
l <<= i;
|
||||
}
|
||||
dh = (d & BN_MASK2h) >> BN_BITS4;
|
||||
dl = (d & BN_MASK2l);
|
||||
for (;;) {
|
||||
if ((h >> BN_BITS4) == dh)
|
||||
q = BN_MASK2l;
|
||||
else
|
||||
q = h / dh;
|
||||
|
||||
th = q * dh;
|
||||
tl = dl * q;
|
||||
for (;;) {
|
||||
t = h - th;
|
||||
if ((t & BN_MASK2h) ||
|
||||
((tl) <= (
|
||||
(t << BN_BITS4) |
|
||||
((l & BN_MASK2h) >> BN_BITS4))))
|
||||
break;
|
||||
q--;
|
||||
th -= dh;
|
||||
tl -= dl;
|
||||
}
|
||||
t = (tl >> BN_BITS4);
|
||||
tl = (tl << BN_BITS4) & BN_MASK2h;
|
||||
th += t;
|
||||
|
||||
if (l < tl)
|
||||
th++;
|
||||
l -= tl;
|
||||
if (h < th) {
|
||||
h += d;
|
||||
q--;
|
||||
}
|
||||
h -= th;
|
||||
|
||||
if (--count == 0)
|
||||
break;
|
||||
|
||||
ret = q << BN_BITS4;
|
||||
h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
|
||||
l = (l & BN_MASK2l) << BN_BITS4;
|
||||
}
|
||||
ret |= q;
|
||||
return (ret);
|
||||
}
|
||||
#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Divide a double word (h:l) by d, returning the quotient q and the remainder
|
||||
* r, such that q * d + r is equal to the numerator.
|
||||
*/
|
||||
#ifndef HAVE_BN_DIV_REM_WORDS
|
||||
#ifndef HAVE_BN_DIV_REM_WORDS_INLINE
|
||||
static inline void
|
||||
bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
|
||||
BN_ULONG *out_r)
|
||||
{
|
||||
BN_ULONG q, r;
|
||||
|
||||
q = bn_div_words(h, l, d);
|
||||
r = (l - q * d) & BN_MASK2;
|
||||
|
||||
*out_q = q;
|
||||
*out_r = r;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
|
||||
BN_ULONG *out_r)
|
||||
{
|
||||
bn_div_rem_words_inline(h, l, d, out_q, out_r);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_DIV_3_WORDS
|
||||
|
||||
/*
|
||||
* Interface is somewhat quirky, |m| is pointer to most significant limb,
|
||||
* and less significant limb is referred at |m[-1]|. This means that caller
|
||||
* is responsible for ensuring that |m[-1]| is valid. Second condition that
|
||||
* has to be met is that |d0|'s most significant bit has to be set. Or in
|
||||
* other words divisor has to be "bit-aligned to the left." The subroutine
|
||||
* considers four limbs, two of which are "overlapping," hence the name...
|
||||
*/
|
||||
BN_ULONG
|
||||
bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0)
|
||||
{
|
||||
BN_ULONG n0, n1, q, t2h, t2l;
|
||||
BN_ULONG rem = 0;
|
||||
|
||||
n0 = m[0];
|
||||
n1 = m[-1];
|
||||
|
||||
if (n0 == d0)
|
||||
return BN_MASK2;
|
||||
|
||||
/* n0 < d0 */
|
||||
bn_div_rem_words(n0, n1, d0, &q, &rem);
|
||||
|
||||
bn_mulw(d1, q, &t2h, &t2l);
|
||||
|
||||
for (;;) {
|
||||
if (t2h < rem || (t2h == rem && t2l <= m[-2]))
|
||||
break;
|
||||
q--;
|
||||
rem += d0;
|
||||
if (rem < d0)
|
||||
break; /* don't let rem overflow */
|
||||
if (t2l < d1)
|
||||
t2h--;
|
||||
t2l -= d1;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
#endif /* !HAVE_BN_DIV_3_WORDS */
|
||||
|
||||
/*
|
||||
* BN_div_internal computes quotient := numerator / divisor, rounding towards
|
||||
* zero and setting remainder such that quotient * divisor + remainder equals
|
||||
* the numerator. Thus:
|
||||
*
|
||||
* quotient->neg == numerator->neg ^ divisor->neg (unless result is zero)
|
||||
* remainder->neg == numerator->neg (unless the remainder is zero)
|
||||
*
|
||||
* If either the quotient or remainder is NULL, the respective value is not
|
||||
* returned.
|
||||
*/
|
||||
static int
|
||||
BN_div_internal(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator,
|
||||
const BIGNUM *divisor, BN_CTX *ctx, int ct)
|
||||
{
|
||||
int norm_shift, i, loop, r_neg;
|
||||
BIGNUM *tmp, wnum, *snum, *sdiv, *res;
|
||||
BN_ULONG *resp, *wnump;
|
||||
BN_ULONG d0, d1;
|
||||
int num_n, div_n;
|
||||
int no_branch = 0;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
/* Invalid zero-padding would have particularly bad consequences. */
|
||||
if (numerator->top > 0 && numerator->d[numerator->top - 1] == 0) {
|
||||
BNerror(BN_R_NOT_INITIALIZED);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ct)
|
||||
no_branch = 1;
|
||||
|
||||
if (BN_is_zero(divisor)) {
|
||||
BNerror(BN_R_DIV_BY_ZERO);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!no_branch) {
|
||||
if (BN_ucmp(numerator, divisor) < 0) {
|
||||
if (remainder != NULL) {
|
||||
if (!bn_copy(remainder, numerator))
|
||||
goto err;
|
||||
}
|
||||
if (quotient != NULL)
|
||||
BN_zero(quotient);
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((snum = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((sdiv = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((res = quotient) == NULL) {
|
||||
if ((res = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* First we normalise the numbers. */
|
||||
norm_shift = BN_BITS2 - BN_num_bits(divisor) % BN_BITS2;
|
||||
if (!BN_lshift(sdiv, divisor, norm_shift))
|
||||
goto err;
|
||||
sdiv->neg = 0;
|
||||
norm_shift += BN_BITS2;
|
||||
if (!BN_lshift(snum, numerator, norm_shift))
|
||||
goto err;
|
||||
snum->neg = 0;
|
||||
|
||||
if (no_branch) {
|
||||
/*
|
||||
* Since we don't know whether snum is larger than sdiv, we pad
|
||||
* snum with enough zeroes without changing its value.
|
||||
*/
|
||||
if (snum->top <= sdiv->top + 1) {
|
||||
if (!bn_wexpand(snum, sdiv->top + 2))
|
||||
goto err;
|
||||
for (i = snum->top; i < sdiv->top + 2; i++)
|
||||
snum->d[i] = 0;
|
||||
snum->top = sdiv->top + 2;
|
||||
} else {
|
||||
if (!bn_wexpand(snum, snum->top + 1))
|
||||
goto err;
|
||||
snum->d[snum->top] = 0;
|
||||
snum->top++;
|
||||
}
|
||||
}
|
||||
|
||||
div_n = sdiv->top;
|
||||
num_n = snum->top;
|
||||
loop = num_n - div_n;
|
||||
|
||||
/*
|
||||
* Setup a 'window' into snum - this is the part that corresponds to the
|
||||
* current 'area' being divided.
|
||||
*/
|
||||
wnum.neg = 0;
|
||||
wnum.d = &(snum->d[loop]);
|
||||
wnum.top = div_n;
|
||||
/* only needed when BN_ucmp messes up the values between top and max */
|
||||
wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
|
||||
wnum.flags = snum->flags | BN_FLG_STATIC_DATA;
|
||||
|
||||
/* Get the top 2 words of sdiv */
|
||||
/* div_n=sdiv->top; */
|
||||
d0 = sdiv->d[div_n - 1];
|
||||
d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
|
||||
|
||||
/* pointer to the 'top' of snum */
|
||||
wnump = &(snum->d[num_n - 1]);
|
||||
|
||||
/* Setup to 'res' */
|
||||
if (!bn_wexpand(res, (loop + 1)))
|
||||
goto err;
|
||||
res->top = loop - no_branch;
|
||||
r_neg = numerator->neg ^ divisor->neg;
|
||||
resp = &(res->d[loop - 1]);
|
||||
|
||||
/* space for temp */
|
||||
if (!bn_wexpand(tmp, (div_n + 1)))
|
||||
goto err;
|
||||
|
||||
if (!no_branch) {
|
||||
if (BN_ucmp(&wnum, sdiv) >= 0) {
|
||||
bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
|
||||
*resp = 1;
|
||||
} else
|
||||
res->top--;
|
||||
}
|
||||
|
||||
/*
|
||||
* If res->top == 0 then clear the neg value otherwise decrease the resp
|
||||
* pointer.
|
||||
*/
|
||||
if (res->top == 0)
|
||||
res->neg = 0;
|
||||
else
|
||||
resp--;
|
||||
|
||||
for (i = 0; i < loop - 1; i++, wnump--, resp--) {
|
||||
BN_ULONG q, l0;
|
||||
|
||||
/*
|
||||
* The first part of the loop uses the top two words of snum and
|
||||
* sdiv to calculate a BN_ULONG q such that:
|
||||
*
|
||||
* | wnum - sdiv * q | < sdiv
|
||||
*/
|
||||
q = bn_div_3_words(wnump, d1, d0);
|
||||
l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
|
||||
tmp->d[div_n] = l0;
|
||||
wnum.d--;
|
||||
|
||||
/*
|
||||
* Ignore top values of the bignums just sub the two BN_ULONG
|
||||
* arrays with bn_sub_words.
|
||||
*/
|
||||
if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) {
|
||||
/*
|
||||
* Note: As we have considered only the leading two
|
||||
* BN_ULONGs in the calculation of q, sdiv * q might be
|
||||
* greater than wnum (but then (q-1) * sdiv is less or
|
||||
* equal than wnum).
|
||||
*/
|
||||
q--;
|
||||
if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) {
|
||||
/*
|
||||
* We can't have an overflow here (assuming
|
||||
* that q != 0, but if q == 0 then tmp is
|
||||
* zero anyway).
|
||||
*/
|
||||
(*wnump)++;
|
||||
}
|
||||
}
|
||||
/* store part of the result */
|
||||
*resp = q;
|
||||
}
|
||||
|
||||
bn_correct_top(snum);
|
||||
|
||||
if (remainder != NULL) {
|
||||
/*
|
||||
* Keep a copy of the neg flag in numerator because if
|
||||
* remainder == numerator, BN_rshift() will overwrite it.
|
||||
*/
|
||||
int neg = numerator->neg;
|
||||
|
||||
BN_rshift(remainder, snum, norm_shift);
|
||||
BN_set_negative(remainder, neg);
|
||||
}
|
||||
|
||||
if (no_branch)
|
||||
bn_correct_top(res);
|
||||
|
||||
BN_set_negative(res, r_neg);
|
||||
|
||||
done:
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
BN_div(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator,
|
||||
const BIGNUM *divisor, BN_CTX *ctx)
|
||||
{
|
||||
int ct;
|
||||
|
||||
ct = BN_get_flags(numerator, BN_FLG_CONSTTIME) != 0 ||
|
||||
BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0;
|
||||
|
||||
return BN_div_internal(quotient, remainder, numerator, divisor, ctx, ct);
|
||||
}
|
||||
|
||||
int
|
||||
BN_div_nonct(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator,
|
||||
const BIGNUM *divisor, BN_CTX *ctx)
|
||||
{
|
||||
return BN_div_internal(quotient, remainder, numerator, divisor, ctx, 0);
|
||||
}
|
||||
|
||||
int
|
||||
BN_div_ct(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator,
|
||||
const BIGNUM *divisor, BN_CTX *ctx)
|
||||
{
|
||||
return BN_div_internal(quotient, remainder, numerator, divisor, ctx, 1);
|
||||
}
|
||||
106
externals/libressl/crypto/bn/bn_err.c
vendored
Normal file
106
externals/libressl/crypto/bn/bn_err.c
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/* $OpenBSD: bn_err.c,v 1.15 2022/07/12 14:42:48 kn Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
|
||||
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
|
||||
|
||||
static ERR_STRING_DATA BN_str_functs[]= {
|
||||
{ERR_FUNC(0xfff), "CRYPTO_internal"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA BN_str_reasons[]= {
|
||||
{ERR_REASON(BN_R_ARG2_LT_ARG3) , "arg2 lt arg3"},
|
||||
{ERR_REASON(BN_R_BAD_RECIPROCAL) , "bad reciprocal"},
|
||||
{ERR_REASON(BN_R_BIGNUM_TOO_LONG) , "bignum too long"},
|
||||
{ERR_REASON(BN_R_BITS_TOO_SMALL) , "bits too small"},
|
||||
{ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"},
|
||||
{ERR_REASON(BN_R_DIV_BY_ZERO) , "div by zero"},
|
||||
{ERR_REASON(BN_R_ENCODING_ERROR) , "encoding error"},
|
||||
{ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), "expand on static bignum data"},
|
||||
{ERR_REASON(BN_R_INPUT_NOT_REDUCED) , "input not reduced"},
|
||||
{ERR_REASON(BN_R_INVALID_LENGTH) , "invalid length"},
|
||||
{ERR_REASON(BN_R_INVALID_RANGE) , "invalid range"},
|
||||
{ERR_REASON(BN_R_NOT_A_SQUARE) , "not a square"},
|
||||
{ERR_REASON(BN_R_NOT_INITIALIZED) , "not initialized"},
|
||||
{ERR_REASON(BN_R_NO_INVERSE) , "no inverse"},
|
||||
{ERR_REASON(BN_R_NO_SOLUTION) , "no solution"},
|
||||
{ERR_REASON(BN_R_P_IS_NOT_PRIME) , "p is not prime"},
|
||||
{ERR_REASON(BN_R_TOO_MANY_ITERATIONS) , "too many iterations"},
|
||||
{ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES), "too many temporary variables"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
ERR_load_BN_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
if (ERR_func_error_string(BN_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, BN_str_functs);
|
||||
ERR_load_strings(0, BN_str_reasons);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
1333
externals/libressl/crypto/bn/bn_exp.c
vendored
Normal file
1333
externals/libressl/crypto/bn/bn_exp.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
828
externals/libressl/crypto/bn/bn_gcd.c
vendored
Normal file
828
externals/libressl/crypto/bn/bn_gcd.c
vendored
Normal file
@@ -0,0 +1,828 @@
|
||||
/* $OpenBSD: bn_gcd.c,v 1.27 2023/04/09 18:38:59 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
static BIGNUM *
|
||||
euclid(BIGNUM *a, BIGNUM *b)
|
||||
{
|
||||
BIGNUM *t;
|
||||
int shifts = 0;
|
||||
|
||||
/* Loop invariant: 0 <= b <= a. */
|
||||
while (!BN_is_zero(b)) {
|
||||
if (BN_is_odd(a) && BN_is_odd(b)) {
|
||||
if (!BN_sub(a, a, b))
|
||||
goto err;
|
||||
if (!BN_rshift1(a, a))
|
||||
goto err;
|
||||
} else if (BN_is_odd(a) && !BN_is_odd(b)) {
|
||||
if (!BN_rshift1(b, b))
|
||||
goto err;
|
||||
} else if (!BN_is_odd(a) && BN_is_odd(b)) {
|
||||
if (!BN_rshift1(a, a))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_rshift1(a, a))
|
||||
goto err;
|
||||
if (!BN_rshift1(b, b))
|
||||
goto err;
|
||||
shifts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BN_cmp(a, b) < 0) {
|
||||
t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
}
|
||||
|
||||
if (shifts) {
|
||||
if (!BN_lshift(a, a, shifts))
|
||||
goto err;
|
||||
}
|
||||
|
||||
return a;
|
||||
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *a, *b, *t;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((a = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((b = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!bn_copy(a, in_a))
|
||||
goto err;
|
||||
if (!bn_copy(b, in_b))
|
||||
goto err;
|
||||
a->neg = 0;
|
||||
b->neg = 0;
|
||||
|
||||
if (BN_cmp(a, b) < 0) {
|
||||
t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
t = euclid(a, b);
|
||||
if (t == NULL)
|
||||
goto err;
|
||||
|
||||
if (!bn_copy(r, t))
|
||||
goto err;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_gcd_nonct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
|
||||
{
|
||||
return BN_gcd(r, in_a, in_b, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_gcd_no_branch is a special version of BN_mod_inverse_no_branch.
|
||||
* that returns the GCD.
|
||||
*/
|
||||
static BIGNUM *
|
||||
BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
|
||||
BIGNUM local_A, local_B;
|
||||
BIGNUM *pA, *pB;
|
||||
BIGNUM *ret = NULL;
|
||||
int sign;
|
||||
|
||||
if (in == NULL)
|
||||
goto err;
|
||||
R = in;
|
||||
|
||||
BN_init(&local_A);
|
||||
BN_init(&local_B);
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((A = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((B = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((X = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((D = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((M = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((Y = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((T = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_one(X))
|
||||
goto err;
|
||||
BN_zero(Y);
|
||||
if (!bn_copy(B, a))
|
||||
goto err;
|
||||
if (!bn_copy(A, n))
|
||||
goto err;
|
||||
A->neg = 0;
|
||||
|
||||
if (B->neg || (BN_ucmp(B, A) >= 0)) {
|
||||
/*
|
||||
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
* BN_div_no_branch will be called eventually.
|
||||
*/
|
||||
pB = &local_B;
|
||||
/* BN_init() done at the top of the function. */
|
||||
BN_with_flags(pB, B, BN_FLG_CONSTTIME);
|
||||
if (!BN_nnmod(B, pB, A, ctx))
|
||||
goto err;
|
||||
}
|
||||
sign = -1;
|
||||
/* From B = a mod |n|, A = |n| it follows that
|
||||
*
|
||||
* 0 <= B < A,
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
*/
|
||||
|
||||
while (!BN_is_zero(B)) {
|
||||
BIGNUM *tmp;
|
||||
|
||||
/*
|
||||
* 0 < B < A,
|
||||
* (*) -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
* BN_div_no_branch will be called eventually.
|
||||
*/
|
||||
pA = &local_A;
|
||||
/* BN_init() done at the top of the function. */
|
||||
BN_with_flags(pA, A, BN_FLG_CONSTTIME);
|
||||
|
||||
/* (D, M) := (A/B, A%B) ... */
|
||||
if (!BN_div_ct(D, M, pA, B, ctx))
|
||||
goto err;
|
||||
|
||||
/* Now
|
||||
* A = D*B + M;
|
||||
* thus we have
|
||||
* (**) sign*Y*a == D*B + M (mod |n|).
|
||||
*/
|
||||
tmp = A; /* keep the BIGNUM object, the value does not matter */
|
||||
|
||||
/* (A, B) := (B, A mod B) ... */
|
||||
A = B;
|
||||
B = M;
|
||||
/* ... so we have 0 <= B < A again */
|
||||
|
||||
/* Since the former M is now B and the former B is now A,
|
||||
* (**) translates into
|
||||
* sign*Y*a == D*A + B (mod |n|),
|
||||
* i.e.
|
||||
* sign*Y*a - D*A == B (mod |n|).
|
||||
* Similarly, (*) translates into
|
||||
* -sign*X*a == A (mod |n|).
|
||||
*
|
||||
* Thus,
|
||||
* sign*Y*a + D*sign*X*a == B (mod |n|),
|
||||
* i.e.
|
||||
* sign*(Y + D*X)*a == B (mod |n|).
|
||||
*
|
||||
* So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
* Note that X and Y stay non-negative all the time.
|
||||
*/
|
||||
|
||||
if (!BN_mul(tmp, D, X, ctx))
|
||||
goto err;
|
||||
if (!BN_add(tmp, tmp, Y))
|
||||
goto err;
|
||||
|
||||
M = Y; /* keep the BIGNUM object, the value does not matter */
|
||||
Y = X;
|
||||
X = tmp;
|
||||
sign = -sign;
|
||||
}
|
||||
|
||||
/*
|
||||
* The while loop (Euclid's algorithm) ends when
|
||||
* A == gcd(a,n);
|
||||
*/
|
||||
|
||||
if (!bn_copy(R, A))
|
||||
goto err;
|
||||
ret = R;
|
||||
err:
|
||||
if ((ret == NULL) && (in == NULL))
|
||||
BN_free(R);
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_gcd_ct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
|
||||
{
|
||||
if (BN_gcd_no_branch(r, in_a, in_b, ctx) == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
|
||||
* It does not contain branches that may leak sensitive information.
|
||||
*/
|
||||
static BIGNUM *
|
||||
BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
|
||||
BIGNUM local_A, local_B;
|
||||
BIGNUM *pA, *pB;
|
||||
BIGNUM *ret = NULL;
|
||||
int sign;
|
||||
|
||||
BN_init(&local_A);
|
||||
BN_init(&local_B);
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((A = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((B = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((X = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((D = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((M = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((Y = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((T = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (in == NULL)
|
||||
R = BN_new();
|
||||
else
|
||||
R = in;
|
||||
if (R == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_one(X))
|
||||
goto err;
|
||||
BN_zero(Y);
|
||||
if (!bn_copy(B, a))
|
||||
goto err;
|
||||
if (!bn_copy(A, n))
|
||||
goto err;
|
||||
A->neg = 0;
|
||||
|
||||
if (B->neg || (BN_ucmp(B, A) >= 0)) {
|
||||
/*
|
||||
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
* BN_div_no_branch will be called eventually.
|
||||
*/
|
||||
pB = &local_B;
|
||||
/* BN_init() done at the top of the function. */
|
||||
BN_with_flags(pB, B, BN_FLG_CONSTTIME);
|
||||
if (!BN_nnmod(B, pB, A, ctx))
|
||||
goto err;
|
||||
}
|
||||
sign = -1;
|
||||
/* From B = a mod |n|, A = |n| it follows that
|
||||
*
|
||||
* 0 <= B < A,
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
*/
|
||||
|
||||
while (!BN_is_zero(B)) {
|
||||
BIGNUM *tmp;
|
||||
|
||||
/*
|
||||
* 0 < B < A,
|
||||
* (*) -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
* BN_div_no_branch will be called eventually.
|
||||
*/
|
||||
pA = &local_A;
|
||||
/* BN_init() done at the top of the function. */
|
||||
BN_with_flags(pA, A, BN_FLG_CONSTTIME);
|
||||
|
||||
/* (D, M) := (A/B, A%B) ... */
|
||||
if (!BN_div_ct(D, M, pA, B, ctx))
|
||||
goto err;
|
||||
|
||||
/* Now
|
||||
* A = D*B + M;
|
||||
* thus we have
|
||||
* (**) sign*Y*a == D*B + M (mod |n|).
|
||||
*/
|
||||
tmp = A; /* keep the BIGNUM object, the value does not matter */
|
||||
|
||||
/* (A, B) := (B, A mod B) ... */
|
||||
A = B;
|
||||
B = M;
|
||||
/* ... so we have 0 <= B < A again */
|
||||
|
||||
/* Since the former M is now B and the former B is now A,
|
||||
* (**) translates into
|
||||
* sign*Y*a == D*A + B (mod |n|),
|
||||
* i.e.
|
||||
* sign*Y*a - D*A == B (mod |n|).
|
||||
* Similarly, (*) translates into
|
||||
* -sign*X*a == A (mod |n|).
|
||||
*
|
||||
* Thus,
|
||||
* sign*Y*a + D*sign*X*a == B (mod |n|),
|
||||
* i.e.
|
||||
* sign*(Y + D*X)*a == B (mod |n|).
|
||||
*
|
||||
* So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
* Note that X and Y stay non-negative all the time.
|
||||
*/
|
||||
|
||||
if (!BN_mul(tmp, D, X, ctx))
|
||||
goto err;
|
||||
if (!BN_add(tmp, tmp, Y))
|
||||
goto err;
|
||||
|
||||
M = Y; /* keep the BIGNUM object, the value does not matter */
|
||||
Y = X;
|
||||
X = tmp;
|
||||
sign = -sign;
|
||||
}
|
||||
|
||||
/*
|
||||
* The while loop (Euclid's algorithm) ends when
|
||||
* A == gcd(a,n);
|
||||
* we have
|
||||
* sign*Y*a == A (mod |n|),
|
||||
* where Y is non-negative.
|
||||
*/
|
||||
|
||||
if (sign < 0) {
|
||||
if (!BN_sub(Y, n, Y))
|
||||
goto err;
|
||||
}
|
||||
/* Now Y*a == A (mod |n|). */
|
||||
|
||||
if (BN_is_one(A)) {
|
||||
/* Y*a == 1 (mod |n|) */
|
||||
if (!Y->neg && BN_ucmp(Y, n) < 0) {
|
||||
if (!bn_copy(R, Y))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_nnmod(R, Y, n, ctx))
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
BNerror(BN_R_NO_INVERSE);
|
||||
goto err;
|
||||
}
|
||||
ret = R;
|
||||
|
||||
err:
|
||||
if ((ret == NULL) && (in == NULL))
|
||||
BN_free(R);
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* solves ax == 1 (mod n) */
|
||||
static BIGNUM *
|
||||
BN_mod_inverse_internal(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
|
||||
int ct)
|
||||
{
|
||||
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
|
||||
BIGNUM *ret = NULL;
|
||||
int sign;
|
||||
|
||||
if (ct)
|
||||
return BN_mod_inverse_no_branch(in, a, n, ctx);
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((A = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((B = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((X = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((D = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((M = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((Y = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((T = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (in == NULL)
|
||||
R = BN_new();
|
||||
else
|
||||
R = in;
|
||||
if (R == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_one(X))
|
||||
goto err;
|
||||
BN_zero(Y);
|
||||
if (!bn_copy(B, a))
|
||||
goto err;
|
||||
if (!bn_copy(A, n))
|
||||
goto err;
|
||||
A->neg = 0;
|
||||
if (B->neg || (BN_ucmp(B, A) >= 0)) {
|
||||
if (!BN_nnmod(B, B, A, ctx))
|
||||
goto err;
|
||||
}
|
||||
sign = -1;
|
||||
/* From B = a mod |n|, A = |n| it follows that
|
||||
*
|
||||
* 0 <= B < A,
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
*/
|
||||
|
||||
if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
|
||||
/* Binary inversion algorithm; requires odd modulus.
|
||||
* This is faster than the general algorithm if the modulus
|
||||
* is sufficiently small (about 400 .. 500 bits on 32-bit
|
||||
* systems, but much more on 64-bit systems) */
|
||||
int shift;
|
||||
|
||||
while (!BN_is_zero(B)) {
|
||||
/*
|
||||
* 0 < B < |n|,
|
||||
* 0 < A <= |n|,
|
||||
* (1) -sign*X*a == B (mod |n|),
|
||||
* (2) sign*Y*a == A (mod |n|)
|
||||
*/
|
||||
|
||||
/* Now divide B by the maximum possible power of two in the integers,
|
||||
* and divide X by the same value mod |n|.
|
||||
* When we're done, (1) still holds. */
|
||||
shift = 0;
|
||||
while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
|
||||
{
|
||||
shift++;
|
||||
|
||||
if (BN_is_odd(X)) {
|
||||
if (!BN_uadd(X, X, n))
|
||||
goto err;
|
||||
}
|
||||
/* now X is even, so we can easily divide it by two */
|
||||
if (!BN_rshift1(X, X))
|
||||
goto err;
|
||||
}
|
||||
if (shift > 0) {
|
||||
if (!BN_rshift(B, B, shift))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Same for A and Y. Afterwards, (2) still holds. */
|
||||
shift = 0;
|
||||
while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
|
||||
{
|
||||
shift++;
|
||||
|
||||
if (BN_is_odd(Y)) {
|
||||
if (!BN_uadd(Y, Y, n))
|
||||
goto err;
|
||||
}
|
||||
/* now Y is even */
|
||||
if (!BN_rshift1(Y, Y))
|
||||
goto err;
|
||||
}
|
||||
if (shift > 0) {
|
||||
if (!BN_rshift(A, A, shift))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We still have (1) and (2).
|
||||
* Both A and B are odd.
|
||||
* The following computations ensure that
|
||||
*
|
||||
* 0 <= B < |n|,
|
||||
* 0 < A < |n|,
|
||||
* (1) -sign*X*a == B (mod |n|),
|
||||
* (2) sign*Y*a == A (mod |n|),
|
||||
*
|
||||
* and that either A or B is even in the next iteration.
|
||||
*/
|
||||
if (BN_ucmp(B, A) >= 0) {
|
||||
/* -sign*(X + Y)*a == B - A (mod |n|) */
|
||||
if (!BN_uadd(X, X, Y))
|
||||
goto err;
|
||||
/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
|
||||
* actually makes the algorithm slower */
|
||||
if (!BN_usub(B, B, A))
|
||||
goto err;
|
||||
} else {
|
||||
/* sign*(X + Y)*a == A - B (mod |n|) */
|
||||
if (!BN_uadd(Y, Y, X))
|
||||
goto err;
|
||||
/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
|
||||
if (!BN_usub(A, A, B))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* general inversion algorithm */
|
||||
|
||||
while (!BN_is_zero(B)) {
|
||||
BIGNUM *tmp;
|
||||
|
||||
/*
|
||||
* 0 < B < A,
|
||||
* (*) -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|)
|
||||
*/
|
||||
|
||||
/* (D, M) := (A/B, A%B) ... */
|
||||
if (BN_num_bits(A) == BN_num_bits(B)) {
|
||||
if (!BN_one(D))
|
||||
goto err;
|
||||
if (!BN_sub(M, A, B))
|
||||
goto err;
|
||||
} else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
|
||||
/* A/B is 1, 2, or 3 */
|
||||
if (!BN_lshift1(T, B))
|
||||
goto err;
|
||||
if (BN_ucmp(A, T) < 0) {
|
||||
/* A < 2*B, so D=1 */
|
||||
if (!BN_one(D))
|
||||
goto err;
|
||||
if (!BN_sub(M, A, B))
|
||||
goto err;
|
||||
} else {
|
||||
/* A >= 2*B, so D=2 or D=3 */
|
||||
if (!BN_sub(M, A, T))
|
||||
goto err;
|
||||
if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
|
||||
if (BN_ucmp(A, D) < 0) {
|
||||
/* A < 3*B, so D=2 */
|
||||
if (!BN_set_word(D, 2))
|
||||
goto err;
|
||||
/* M (= A - 2*B) already has the correct value */
|
||||
} else {
|
||||
/* only D=3 remains */
|
||||
if (!BN_set_word(D, 3))
|
||||
goto err;
|
||||
/* currently M = A - 2*B, but we need M = A - 3*B */
|
||||
if (!BN_sub(M, M, B))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!BN_div_nonct(D, M, A, B, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Now
|
||||
* A = D*B + M;
|
||||
* thus we have
|
||||
* (**) sign*Y*a == D*B + M (mod |n|).
|
||||
*/
|
||||
tmp = A; /* keep the BIGNUM object, the value does not matter */
|
||||
|
||||
/* (A, B) := (B, A mod B) ... */
|
||||
A = B;
|
||||
B = M;
|
||||
/* ... so we have 0 <= B < A again */
|
||||
|
||||
/* Since the former M is now B and the former B is now A,
|
||||
* (**) translates into
|
||||
* sign*Y*a == D*A + B (mod |n|),
|
||||
* i.e.
|
||||
* sign*Y*a - D*A == B (mod |n|).
|
||||
* Similarly, (*) translates into
|
||||
* -sign*X*a == A (mod |n|).
|
||||
*
|
||||
* Thus,
|
||||
* sign*Y*a + D*sign*X*a == B (mod |n|),
|
||||
* i.e.
|
||||
* sign*(Y + D*X)*a == B (mod |n|).
|
||||
*
|
||||
* So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
* Note that X and Y stay non-negative all the time.
|
||||
*/
|
||||
|
||||
/* most of the time D is very small, so we can optimize tmp := D*X+Y */
|
||||
if (BN_is_one(D)) {
|
||||
if (!BN_add(tmp, X, Y))
|
||||
goto err;
|
||||
} else {
|
||||
if (BN_is_word(D, 2)) {
|
||||
if (!BN_lshift1(tmp, X))
|
||||
goto err;
|
||||
} else if (BN_is_word(D, 4)) {
|
||||
if (!BN_lshift(tmp, X, 2))
|
||||
goto err;
|
||||
} else if (D->top == 1) {
|
||||
if (!bn_copy(tmp, X))
|
||||
goto err;
|
||||
if (!BN_mul_word(tmp, D->d[0]))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mul(tmp, D,X, ctx))
|
||||
goto err;
|
||||
}
|
||||
if (!BN_add(tmp, tmp, Y))
|
||||
goto err;
|
||||
}
|
||||
|
||||
M = Y; /* keep the BIGNUM object, the value does not matter */
|
||||
Y = X;
|
||||
X = tmp;
|
||||
sign = -sign;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The while loop (Euclid's algorithm) ends when
|
||||
* A == gcd(a,n);
|
||||
* we have
|
||||
* sign*Y*a == A (mod |n|),
|
||||
* where Y is non-negative.
|
||||
*/
|
||||
|
||||
if (sign < 0) {
|
||||
if (!BN_sub(Y, n, Y))
|
||||
goto err;
|
||||
}
|
||||
/* Now Y*a == A (mod |n|). */
|
||||
|
||||
if (BN_is_one(A)) {
|
||||
/* Y*a == 1 (mod |n|) */
|
||||
if (!Y->neg && BN_ucmp(Y, n) < 0) {
|
||||
if (!bn_copy(R, Y))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_nnmod(R, Y,n, ctx))
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
BNerror(BN_R_NO_INVERSE);
|
||||
goto err;
|
||||
}
|
||||
ret = R;
|
||||
|
||||
err:
|
||||
if ((ret == NULL) && (in == NULL))
|
||||
BN_free(R);
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
int ct = ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) ||
|
||||
(BN_get_flags(n, BN_FLG_CONSTTIME) != 0));
|
||||
return BN_mod_inverse_internal(in, a, n, ctx, ct);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_mod_inverse_nonct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
return BN_mod_inverse_internal(in, a, n, ctx, 0);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_mod_inverse_ct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
return BN_mod_inverse_internal(in, a, n, ctx, 1);
|
||||
}
|
||||
390
externals/libressl/crypto/bn/bn_internal.h
vendored
Normal file
390
externals/libressl/crypto/bn/bn_internal.h
vendored
Normal file
@@ -0,0 +1,390 @@
|
||||
/* $OpenBSD: bn_internal.h,v 1.11 2023/03/07 09:35:55 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "bn_arch.h"
|
||||
|
||||
#ifndef HEADER_BN_INTERNAL_H
|
||||
#define HEADER_BN_INTERNAL_H
|
||||
|
||||
#ifndef HAVE_BN_CT_NE_ZERO
|
||||
static inline int
|
||||
bn_ct_ne_zero(BN_ULONG w)
|
||||
{
|
||||
return (w | ~(w - 1)) >> (BN_BITS2 - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_CT_NE_ZERO_MASK
|
||||
static inline BN_ULONG
|
||||
bn_ct_ne_zero_mask(BN_ULONG w)
|
||||
{
|
||||
return 0 - bn_ct_ne_zero(w);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_CT_EQ_ZERO
|
||||
static inline int
|
||||
bn_ct_eq_zero(BN_ULONG w)
|
||||
{
|
||||
return 1 - bn_ct_ne_zero(w);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_CT_EQ_ZERO_MASK
|
||||
static inline BN_ULONG
|
||||
bn_ct_eq_zero_mask(BN_ULONG w)
|
||||
{
|
||||
return 0 - bn_ct_eq_zero(w);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Big number primitives are named as the operation followed by a suffix
|
||||
* that indicates the number of words that it operates on, where 'w' means
|
||||
* single word, 'dw' means double word, 'tw' means triple word and 'qw' means
|
||||
* quadruple word. Unless otherwise noted, the size of the output is implied
|
||||
* based on its inputs, for example bn_mulw() takes two single word inputs
|
||||
* and is going to produce a double word result.
|
||||
*
|
||||
* Where a function implements multiple operations, these are listed in order.
|
||||
* For example, a function that computes (r1:r0) = a * b + c is named
|
||||
* bn_mulw_addw(), producing a double word result.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bn_addw() computes (r1:r0) = a + b, where both inputs are single words,
|
||||
* producing a double word result. The value of r1 is the carry from the
|
||||
* addition.
|
||||
*/
|
||||
#ifndef HAVE_BN_ADDW
|
||||
#ifdef BN_LLONG
|
||||
static inline void
|
||||
bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULLONG r;
|
||||
|
||||
r = (BN_ULLONG)a + (BN_ULLONG)b;
|
||||
|
||||
*out_r1 = r >> BN_BITS2;
|
||||
*out_r0 = r & BN_MASK2;
|
||||
}
|
||||
#else
|
||||
|
||||
static inline void
|
||||
bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG r1, r0, c1, c2;
|
||||
|
||||
c1 = a | b;
|
||||
c2 = a & b;
|
||||
r0 = a + b;
|
||||
r1 = ((c1 & ~r0) | c2) >> (BN_BITS2 - 1); /* carry */
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_addw_addw() computes (r1:r0) = a + b + c, where all inputs are single
|
||||
* words, producing a double word result.
|
||||
*/
|
||||
#ifndef HAVE_BN_ADDW_ADDW
|
||||
static inline void
|
||||
bn_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1,
|
||||
BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG carry, r1, r0;
|
||||
|
||||
bn_addw(a, b, &r1, &r0);
|
||||
bn_addw(r0, c, &carry, &r0);
|
||||
r1 += carry;
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_subw() computes r0 = a - b, where both inputs are single words,
|
||||
* producing a single word result and borrow.
|
||||
*/
|
||||
#ifndef HAVE_BN_SUBW
|
||||
static inline void
|
||||
bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG borrow, r0;
|
||||
|
||||
r0 = a - b;
|
||||
borrow = ((r0 | (b & ~a)) & (b | ~a)) >> (BN_BITS2 - 1);
|
||||
|
||||
*out_borrow = borrow;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_subw_subw() computes r0 = a - b - c, where all inputs are single words,
|
||||
* producing a single word result and borrow.
|
||||
*/
|
||||
#ifndef HAVE_BN_SUBW_SUBW
|
||||
static inline void
|
||||
bn_subw_subw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_borrow,
|
||||
BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG b1, b2, r0;
|
||||
|
||||
bn_subw(a, b, &b1, &r0);
|
||||
bn_subw(r0, c, &b2, &r0);
|
||||
|
||||
*out_borrow = b1 + b2;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mulw() computes (r1:r0) = a * b, where both inputs are single words,
|
||||
* producing a double word result.
|
||||
*/
|
||||
#ifndef HAVE_BN_MULW
|
||||
#ifdef BN_LLONG
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULLONG r;
|
||||
|
||||
r = (BN_ULLONG)a * (BN_ULLONG)b;
|
||||
|
||||
*out_r1 = r >> BN_BITS2;
|
||||
*out_r0 = r & BN_MASK2;
|
||||
}
|
||||
|
||||
#else /* !BN_LLONG */
|
||||
/*
|
||||
* Multiply two words (a * b) producing a double word result (h:l).
|
||||
*
|
||||
* This can be rewritten as:
|
||||
*
|
||||
* a * b = (hi32(a) * 2^32 + lo32(a)) * (hi32(b) * 2^32 + lo32(b))
|
||||
* = hi32(a) * hi32(b) * 2^64 +
|
||||
* hi32(a) * lo32(b) * 2^32 +
|
||||
* hi32(b) * lo32(a) * 2^32 +
|
||||
* lo32(a) * lo32(b)
|
||||
*
|
||||
* The multiplication for each part of a and b can be calculated for each of
|
||||
* these four terms without overflowing a BN_ULONG, as the maximum value of a
|
||||
* 32 bit x 32 bit multiplication is 32 + 32 = 64 bits. Once these
|
||||
* multiplications have been performed the result can be partitioned and summed
|
||||
* into a double word (h:l). The same applies on a 32 bit system, substituting
|
||||
* 16 for 32 and 32 for 64.
|
||||
*/
|
||||
#if 1
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG a1, a0, b1, b0, r1, r0;
|
||||
BN_ULONG carry, x;
|
||||
|
||||
a1 = a >> BN_BITS4;
|
||||
a0 = a & BN_MASK2l;
|
||||
b1 = b >> BN_BITS4;
|
||||
b0 = b & BN_MASK2l;
|
||||
|
||||
r1 = a1 * b1;
|
||||
r0 = a0 * b0;
|
||||
|
||||
/* (a1 * b0) << BN_BITS4, partition the result across r1:r0 with carry. */
|
||||
x = a1 * b0;
|
||||
r1 += x >> BN_BITS4;
|
||||
bn_addw(r0, x << BN_BITS4, &carry, &r0);
|
||||
r1 += carry;
|
||||
|
||||
/* (b1 * a0) << BN_BITS4, partition the result across r1:r0 with carry. */
|
||||
x = b1 * a0;
|
||||
r1 += x >> BN_BITS4;
|
||||
bn_addw(r0, x << BN_BITS4, &carry, &r0);
|
||||
r1 += carry;
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* XXX - this accumulator based version uses fewer instructions, however
|
||||
* requires more variables/registers. It seems to be slower on at least amd64
|
||||
* and i386, however may be faster on other architectures that have more
|
||||
* registers available. Further testing is required and one of the two
|
||||
* implementations should eventually be removed.
|
||||
*/
|
||||
static inline void
|
||||
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG a1, a0, b1, b0, r1, r0, x;
|
||||
BN_ULONG acc0, acc1, acc2, acc3;
|
||||
|
||||
a1 = a >> BN_BITS4;
|
||||
b1 = b >> BN_BITS4;
|
||||
a0 = a & BN_MASK2l;
|
||||
b0 = b & BN_MASK2l;
|
||||
|
||||
r1 = a1 * b1;
|
||||
r0 = a0 * b0;
|
||||
|
||||
acc0 = r0 & BN_MASK2l;
|
||||
acc1 = r0 >> BN_BITS4;
|
||||
acc2 = r1 & BN_MASK2l;
|
||||
acc3 = r1 >> BN_BITS4;
|
||||
|
||||
/* (a1 * b0) << BN_BITS4, partition the result across r1:r0. */
|
||||
x = a1 * b0;
|
||||
acc1 += x & BN_MASK2l;
|
||||
acc2 += (acc1 >> BN_BITS4) + (x >> BN_BITS4);
|
||||
acc1 &= BN_MASK2l;
|
||||
acc3 += acc2 >> BN_BITS4;
|
||||
acc2 &= BN_MASK2l;
|
||||
|
||||
/* (b1 * a0) << BN_BITS4, partition the result across r1:r0. */
|
||||
x = b1 * a0;
|
||||
acc1 += x & BN_MASK2l;
|
||||
acc2 += (acc1 >> BN_BITS4) + (x >> BN_BITS4);
|
||||
acc1 &= BN_MASK2l;
|
||||
acc3 += acc2 >> BN_BITS4;
|
||||
acc2 &= BN_MASK2l;
|
||||
|
||||
*out_r1 = (acc3 << BN_BITS4) | acc2;
|
||||
*out_r0 = (acc1 << BN_BITS4) | acc0;
|
||||
}
|
||||
#endif
|
||||
#endif /* !BN_LLONG */
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_MULW_LO
|
||||
static inline BN_ULONG
|
||||
bn_mulw_lo(BN_ULONG a, BN_ULONG b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_MULW_HI
|
||||
static inline BN_ULONG
|
||||
bn_mulw_hi(BN_ULONG a, BN_ULONG b)
|
||||
{
|
||||
BN_ULONG h, l;
|
||||
|
||||
bn_mulw(a, b, &h, &l);
|
||||
|
||||
return h;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mulw_addw() computes (r1:r0) = a * b + c with all inputs being single
|
||||
* words, producing a double word result.
|
||||
*/
|
||||
#ifndef HAVE_BN_MULW_ADDW
|
||||
static inline void
|
||||
bn_mulw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1,
|
||||
BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG carry, r1, r0;
|
||||
|
||||
bn_mulw(a, b, &r1, &r0);
|
||||
bn_addw(r0, c, &carry, &r0);
|
||||
r1 += carry;
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mulw_addw_addw() computes (r1:r0) = a * b + c + d with all inputs being
|
||||
* single words, producing a double word result.
|
||||
*/
|
||||
#ifndef HAVE_BN_MULW_ADDW_ADDW
|
||||
static inline void
|
||||
bn_mulw_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG d,
|
||||
BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG carry, r1, r0;
|
||||
|
||||
bn_mulw_addw(a, b, c, &r1, &r0);
|
||||
bn_addw(r0, d, &carry, &r0);
|
||||
r1 += carry;
|
||||
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mulw_addtw() computes (r2:r1:r0) = a * b + (c2:c1:c0), where a and b are
|
||||
* single words and (c2:c1:c0) is a triple word, producing a triple word result.
|
||||
* The caller must ensure that the inputs provided do not result in c2
|
||||
* overflowing.
|
||||
*/
|
||||
#ifndef HAVE_BN_MULW_ADDTW
|
||||
static inline void
|
||||
bn_mulw_addtw(BN_ULONG a, BN_ULONG b, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0,
|
||||
BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG carry, r2, r1, r0, x1;
|
||||
|
||||
bn_mulw_addw(a, b, c0, &x1, &r0);
|
||||
bn_addw(c1, x1, &carry, &r1);
|
||||
r2 = c2 + carry;
|
||||
|
||||
*out_r2 = r2;
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mul2_mulw_addtw() computes (r2:r1:r0) = 2 * a * b + (c2:c1:c0), where a
|
||||
* and b are single words and (c2:c1:c0) is a triple word, producing a triple
|
||||
* word result. The caller must ensure that the inputs provided do not result
|
||||
* in c2 overflowing.
|
||||
*/
|
||||
#ifndef HAVE_BN_MUL2_MULW_ADDTW
|
||||
static inline void
|
||||
bn_mul2_mulw_addtw(BN_ULONG a, BN_ULONG b, BN_ULONG c2, BN_ULONG c1, BN_ULONG c0,
|
||||
BN_ULONG *out_r2, BN_ULONG *out_r1, BN_ULONG *out_r0)
|
||||
{
|
||||
BN_ULONG r2, r1, r0, x1, x0;
|
||||
BN_ULONG carry;
|
||||
|
||||
bn_mulw(a, b, &x1, &x0);
|
||||
bn_addw(c0, x0, &carry, &r0);
|
||||
bn_addw(c1, x1 + carry, &r2, &r1);
|
||||
bn_addw(c2, r2, &carry, &r2);
|
||||
bn_addw(r0, x0, &carry, &r0);
|
||||
bn_addw(r1, x1 + carry, &carry, &r1);
|
||||
r2 += carry;
|
||||
|
||||
*out_r2 = r2;
|
||||
*out_r1 = r1;
|
||||
*out_r0 = r0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
236
externals/libressl/crypto/bn/bn_isqrt.c
vendored
Normal file
236
externals/libressl/crypto/bn/bn_isqrt.c
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/* $OpenBSD: bn_isqrt.c,v 1.9 2023/05/19 00:54:28 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
#define CTASSERT(x) extern char _ctassert[(x) ? 1 : -1 ] \
|
||||
__attribute__((__unused__))
|
||||
|
||||
/*
|
||||
* Calculate integer square root of |n| using a variant of Newton's method.
|
||||
*
|
||||
* Returns the integer square root of |n| in the caller-provided |out_sqrt|;
|
||||
* |*out_perfect| is set to 1 if and only if |n| is a perfect square.
|
||||
* One of |out_sqrt| and |out_perfect| can be NULL; |in_ctx| can be NULL.
|
||||
*
|
||||
* Returns 0 on error, 1 on success.
|
||||
*
|
||||
* Adapted from pure Python describing cpython's math.isqrt(), without bothering
|
||||
* with any of the optimizations in the C code. A correctness proof is here:
|
||||
* https://github.com/mdickinson/snippets/blob/master/proofs/isqrt/src/isqrt.lean
|
||||
* The comments in the Python code also give a rather detailed proof.
|
||||
*/
|
||||
|
||||
int
|
||||
bn_isqrt(BIGNUM *out_sqrt, int *out_perfect, const BIGNUM *n, BN_CTX *in_ctx)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *a, *b;
|
||||
int c, d, e, s;
|
||||
int cmp, perfect;
|
||||
int ret = 0;
|
||||
|
||||
if (out_perfect == NULL && out_sqrt == NULL) {
|
||||
BNerror(ERR_R_PASSED_NULL_PARAMETER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_is_negative(n)) {
|
||||
BNerror(BN_R_INVALID_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((ctx = in_ctx) == NULL)
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((a = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((b = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (BN_is_zero(n)) {
|
||||
perfect = 1;
|
||||
BN_zero(a);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!BN_one(a))
|
||||
goto err;
|
||||
|
||||
c = (BN_num_bits(n) - 1) / 2;
|
||||
d = 0;
|
||||
|
||||
/* Calculate s = floor(log(c)). */
|
||||
if (!BN_set_word(b, c))
|
||||
goto err;
|
||||
s = BN_num_bits(b) - 1;
|
||||
|
||||
/*
|
||||
* By definition, the loop below is run <= floor(log(log(n))) times.
|
||||
* Comments in the cpython code establish the loop invariant that
|
||||
*
|
||||
* (a - 1)^2 < n / 4^(c - d) < (a + 1)^2
|
||||
*
|
||||
* holds true in every iteration. Once this is proved via induction,
|
||||
* correctness of the algorithm is easy.
|
||||
*
|
||||
* Roughly speaking, A = (a << (d - e)) is used for one Newton step
|
||||
* "a = (A >> 1) + (m >> 1) / A" approximating m = (n >> 2 * (c - d)).
|
||||
*/
|
||||
|
||||
for (; s >= 0; s--) {
|
||||
e = d;
|
||||
d = c >> s;
|
||||
|
||||
if (!BN_rshift(b, n, 2 * c - d - e + 1))
|
||||
goto err;
|
||||
|
||||
if (!BN_div_ct(b, NULL, b, a, ctx))
|
||||
goto err;
|
||||
|
||||
if (!BN_lshift(a, a, d - e - 1))
|
||||
goto err;
|
||||
|
||||
if (!BN_add(a, a, b))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The loop invariant implies that either a or a - 1 is isqrt(n).
|
||||
* Figure out which one it is. The invariant also implies that for
|
||||
* a perfect square n, a must be the square root.
|
||||
*/
|
||||
|
||||
if (!BN_sqr(b, a, ctx))
|
||||
goto err;
|
||||
|
||||
/* If a^2 > n, we must have isqrt(n) == a - 1. */
|
||||
if ((cmp = BN_cmp(b, n)) > 0) {
|
||||
if (!BN_sub_word(a, 1))
|
||||
goto err;
|
||||
}
|
||||
|
||||
perfect = cmp == 0;
|
||||
|
||||
done:
|
||||
if (out_perfect != NULL)
|
||||
*out_perfect = perfect;
|
||||
|
||||
if (out_sqrt != NULL) {
|
||||
if (!bn_copy(out_sqrt, a))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
if (ctx != in_ctx)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* is_square_mod_N[r % N] indicates whether r % N has a square root modulo N.
|
||||
* The tables are generated in regress/lib/libcrypto/bn/bn_isqrt.c.
|
||||
*/
|
||||
|
||||
const uint8_t is_square_mod_11[] = {
|
||||
1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
|
||||
};
|
||||
CTASSERT(sizeof(is_square_mod_11) == 11);
|
||||
|
||||
const uint8_t is_square_mod_63[] = {
|
||||
1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
|
||||
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
|
||||
};
|
||||
CTASSERT(sizeof(is_square_mod_63) == 63);
|
||||
|
||||
const uint8_t is_square_mod_64[] = {
|
||||
1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
CTASSERT(sizeof(is_square_mod_64) == 64);
|
||||
|
||||
const uint8_t is_square_mod_65[] = {
|
||||
1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0,
|
||||
0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0,
|
||||
1,
|
||||
};
|
||||
CTASSERT(sizeof(is_square_mod_65) == 65);
|
||||
|
||||
/*
|
||||
* Determine whether n is a perfect square or not.
|
||||
*
|
||||
* Returns 1 on success and 0 on error. In case of success, |*out_perfect| is
|
||||
* set to 1 if and only if |n| is a perfect square.
|
||||
*/
|
||||
|
||||
int
|
||||
bn_is_perfect_square(int *out_perfect, const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
BN_ULONG r;
|
||||
|
||||
*out_perfect = 0;
|
||||
|
||||
if (BN_is_negative(n))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Before performing an expensive bn_isqrt() operation, weed out many
|
||||
* obvious non-squares. See H. Cohen, "A course in computational
|
||||
* algebraic number theory", Algorithm 1.7.3.
|
||||
*
|
||||
* The idea is that a square remains a square when reduced modulo any
|
||||
* number. The moduli are chosen in such a way that a non-square has
|
||||
* probability < 1% of passing the four table lookups.
|
||||
*/
|
||||
|
||||
/* n % 64 */
|
||||
r = BN_lsw(n) & 0x3f;
|
||||
|
||||
if (!is_square_mod_64[r % 64])
|
||||
return 1;
|
||||
|
||||
if ((r = BN_mod_word(n, 11 * 63 * 65)) == (BN_ULONG)-1)
|
||||
return 0;
|
||||
|
||||
if (!is_square_mod_63[r % 63] ||
|
||||
!is_square_mod_65[r % 65] ||
|
||||
!is_square_mod_11[r % 11])
|
||||
return 1;
|
||||
|
||||
return bn_isqrt(NULL, out_perfect, n, ctx);
|
||||
}
|
||||
194
externals/libressl/crypto/bn/bn_kron.c
vendored
Normal file
194
externals/libressl/crypto/bn/bn_kron.c
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/* $OpenBSD: bn_kron.c,v 1.14 2023/03/27 10:21:23 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
/*
|
||||
* Kronecker symbol, implemented according to Henri Cohen, "A Course in
|
||||
* Computational Algebraic Number Theory", Algorithm 1.4.10.
|
||||
*
|
||||
* Returns -1, 0, or 1 on success and -2 on error.
|
||||
*/
|
||||
|
||||
int
|
||||
BN_kronecker(const BIGNUM *A, const BIGNUM *B, BN_CTX *ctx)
|
||||
{
|
||||
/* tab[BN_lsw(n) & 7] = (-1)^((n^2 - 1)) / 8) for odd values of n. */
|
||||
static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1};
|
||||
BIGNUM *a, *b, *tmp;
|
||||
int k, v;
|
||||
int ret = -2;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((a = BN_CTX_get(ctx)) == NULL)
|
||||
goto end;
|
||||
if ((b = BN_CTX_get(ctx)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!bn_copy(a, A))
|
||||
goto end;
|
||||
if (!bn_copy(b, B))
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* Cohen's step 1:
|
||||
*/
|
||||
|
||||
/* If b is zero, output 1 if |a| is 1, otherwise output 0. */
|
||||
if (BN_is_zero(b)) {
|
||||
ret = BN_abs_is_word(a, 1);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cohen's step 2:
|
||||
*/
|
||||
|
||||
/* If both are even, they have a factor in common, so output 0. */
|
||||
if (!BN_is_odd(a) && !BN_is_odd(b)) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Factorize b = 2^v * u with odd u and replace b with u. */
|
||||
v = 0;
|
||||
while (!BN_is_bit_set(b, v))
|
||||
v++;
|
||||
if (!BN_rshift(b, b, v))
|
||||
goto end;
|
||||
|
||||
/* If v is even set k = 1, otherwise set it to (-1)^((a^2 - 1) / 8). */
|
||||
k = 1;
|
||||
if (v % 2 != 0)
|
||||
k = tab[BN_lsw(a) & 7];
|
||||
|
||||
/*
|
||||
* If b is negative, replace it with -b and if a is also negative
|
||||
* replace k with -k.
|
||||
*/
|
||||
if (BN_is_negative(b)) {
|
||||
BN_set_negative(b, 0);
|
||||
|
||||
if (BN_is_negative(a))
|
||||
k = -k;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now b is positive and odd, so compute the Jacobi symbol (a/b)
|
||||
* and multiply it by k.
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
/*
|
||||
* Cohen's step 3:
|
||||
*/
|
||||
|
||||
/* b is positive and odd. */
|
||||
|
||||
/* If a is zero output k if b is one, otherwise output 0. */
|
||||
if (BN_is_zero(a)) {
|
||||
ret = BN_is_one(b) ? k : 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Factorize a = 2^v * u with odd u and replace a with u. */
|
||||
v = 0;
|
||||
while (!BN_is_bit_set(a, v))
|
||||
v++;
|
||||
if (!BN_rshift(a, a, v))
|
||||
goto end;
|
||||
|
||||
/* If v is odd, multiply k with (-1)^((b^2 - 1) / 8). */
|
||||
if (v % 2 != 0)
|
||||
k *= tab[BN_lsw(b) & 7];
|
||||
|
||||
/*
|
||||
* Cohen's step 4:
|
||||
*/
|
||||
|
||||
/*
|
||||
* Apply the reciprocity law: multiply k by (-1)^((a-1)(b-1)/4).
|
||||
*
|
||||
* This expression is -1 if and only if a and b are 3 (mod 4).
|
||||
* In turn, this is the case if and only if their two's
|
||||
* complement representations have the second bit set.
|
||||
* a could be negative in the first iteration, b is positive.
|
||||
*/
|
||||
if ((BN_is_negative(a) ? ~BN_lsw(a) : BN_lsw(a)) & BN_lsw(b) & 2)
|
||||
k = -k;
|
||||
|
||||
/*
|
||||
* (a, b) := (b mod |a|, |a|)
|
||||
*
|
||||
* Once this is done, we know that 0 < a < b at the start of the
|
||||
* loop. Since b is strictly decreasing, the loop terminates.
|
||||
*/
|
||||
|
||||
if (!BN_nnmod(b, b, a, ctx))
|
||||
goto end;
|
||||
|
||||
tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
|
||||
BN_set_negative(b, 0);
|
||||
}
|
||||
|
||||
end:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
743
externals/libressl/crypto/bn/bn_lib.c
vendored
Normal file
743
externals/libressl/crypto/bn/bn_lib.c
vendored
Normal file
@@ -0,0 +1,743 @@
|
||||
/* $OpenBSD: bn_lib.c,v 1.86 2023/04/30 19:15:48 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
#include "bn_internal.h"
|
||||
|
||||
BIGNUM *
|
||||
BN_new(void)
|
||||
{
|
||||
BIGNUM *bn;
|
||||
|
||||
if ((bn = calloc(1, sizeof(BIGNUM))) == NULL) {
|
||||
BNerror(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
bn->flags = BN_FLG_MALLOCED;
|
||||
|
||||
return bn;
|
||||
}
|
||||
|
||||
void
|
||||
BN_init(BIGNUM *a)
|
||||
{
|
||||
memset(a, 0, sizeof(BIGNUM));
|
||||
}
|
||||
|
||||
void
|
||||
BN_clear(BIGNUM *a)
|
||||
{
|
||||
if (a->d != NULL)
|
||||
explicit_bzero(a->d, a->dmax * sizeof(a->d[0]));
|
||||
a->top = 0;
|
||||
a->neg = 0;
|
||||
}
|
||||
|
||||
void
|
||||
BN_free(BIGNUM *bn)
|
||||
{
|
||||
if (bn == NULL)
|
||||
return;
|
||||
|
||||
if (!BN_get_flags(bn, BN_FLG_STATIC_DATA))
|
||||
freezero(bn->d, bn->dmax * sizeof(bn->d[0]));
|
||||
|
||||
if (!BN_get_flags(bn, BN_FLG_MALLOCED)) {
|
||||
explicit_bzero(bn, sizeof(*bn));
|
||||
return;
|
||||
}
|
||||
|
||||
freezero(bn, sizeof(*bn));
|
||||
}
|
||||
|
||||
void
|
||||
BN_clear_free(BIGNUM *bn)
|
||||
{
|
||||
BN_free(bn);
|
||||
}
|
||||
|
||||
void
|
||||
BN_set_flags(BIGNUM *b, int n)
|
||||
{
|
||||
b->flags |= n;
|
||||
}
|
||||
|
||||
int
|
||||
BN_get_flags(const BIGNUM *b, int n)
|
||||
{
|
||||
return b->flags & n;
|
||||
}
|
||||
|
||||
void
|
||||
BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
|
||||
{
|
||||
int dest_flags;
|
||||
|
||||
dest_flags = (dest->flags & BN_FLG_MALLOCED) |
|
||||
(b->flags & ~BN_FLG_MALLOCED) | BN_FLG_STATIC_DATA | flags;
|
||||
|
||||
*dest = *b;
|
||||
dest->flags = dest_flags;
|
||||
}
|
||||
|
||||
static const BN_ULONG bn_value_one_data = 1;
|
||||
static const BIGNUM bn_value_one = {
|
||||
.d = (BN_ULONG *)&bn_value_one_data,
|
||||
.top = 1,
|
||||
.dmax = 1,
|
||||
.neg = 0,
|
||||
.flags = BN_FLG_STATIC_DATA,
|
||||
};
|
||||
|
||||
const BIGNUM *
|
||||
BN_value_one(void)
|
||||
{
|
||||
return &bn_value_one;
|
||||
}
|
||||
|
||||
#ifndef HAVE_BN_WORD_CLZ
|
||||
int
|
||||
bn_word_clz(BN_ULONG w)
|
||||
{
|
||||
BN_ULONG bits, mask, shift;
|
||||
|
||||
bits = shift = BN_BITS2;
|
||||
mask = 0;
|
||||
|
||||
while ((shift >>= 1) != 0) {
|
||||
bits += (shift & mask) - (shift & ~mask);
|
||||
mask = bn_ct_ne_zero_mask(w >> bits);
|
||||
}
|
||||
bits += 1 & mask;
|
||||
|
||||
bits -= bn_ct_eq_zero(w);
|
||||
|
||||
return BN_BITS2 - bits;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
BN_num_bits_word(BN_ULONG w)
|
||||
{
|
||||
return BN_BITS2 - bn_word_clz(w);
|
||||
}
|
||||
|
||||
int
|
||||
BN_num_bits(const BIGNUM *a)
|
||||
{
|
||||
int i = a->top - 1;
|
||||
|
||||
if (BN_is_zero(a))
|
||||
return 0;
|
||||
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
|
||||
}
|
||||
|
||||
void
|
||||
bn_correct_top(BIGNUM *a)
|
||||
{
|
||||
while (a->top > 0 && a->d[a->top - 1] == 0)
|
||||
a->top--;
|
||||
}
|
||||
|
||||
static int
|
||||
bn_expand_internal(BIGNUM *bn, int words)
|
||||
{
|
||||
BN_ULONG *d;
|
||||
|
||||
if (words < 0) {
|
||||
BNerror(BN_R_BIGNUM_TOO_LONG); // XXX
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (words > INT_MAX / (4 * BN_BITS2)) {
|
||||
BNerror(BN_R_BIGNUM_TOO_LONG);
|
||||
return 0;
|
||||
}
|
||||
if (BN_get_flags(bn, BN_FLG_STATIC_DATA)) {
|
||||
BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = recallocarray(bn->d, bn->dmax, words, sizeof(BN_ULONG));
|
||||
if (d == NULL) {
|
||||
BNerror(ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
bn->d = d;
|
||||
bn->dmax = words;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
bn_expand(BIGNUM *bn, int bits)
|
||||
{
|
||||
int words;
|
||||
|
||||
if (bits < 0)
|
||||
return 0;
|
||||
|
||||
if (bits > (INT_MAX - BN_BITS2 + 1))
|
||||
return 0;
|
||||
|
||||
words = (bits + BN_BITS2 - 1) / BN_BITS2;
|
||||
|
||||
return bn_wexpand(bn, words);
|
||||
}
|
||||
|
||||
int
|
||||
bn_wexpand(BIGNUM *bn, int words)
|
||||
{
|
||||
if (words < 0)
|
||||
return 0;
|
||||
|
||||
if (words <= bn->dmax)
|
||||
return 1;
|
||||
|
||||
return bn_expand_internal(bn, words);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_dup(const BIGNUM *a)
|
||||
{
|
||||
BIGNUM *t;
|
||||
|
||||
if (a == NULL)
|
||||
return NULL;
|
||||
|
||||
t = BN_new();
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
if (!bn_copy(t, a)) {
|
||||
BN_free(t);
|
||||
return NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static inline void
|
||||
bn_copy_words(BN_ULONG *ap, const BN_ULONG *bp, int n)
|
||||
{
|
||||
while (n > 0) {
|
||||
ap[0] = bp[0];
|
||||
ap++;
|
||||
bp++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_copy(BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
if (a == b)
|
||||
return (a);
|
||||
|
||||
if (!bn_wexpand(a, b->top))
|
||||
return (NULL);
|
||||
|
||||
bn_copy_words(a->d, b->d, b->top);
|
||||
|
||||
/* Copy constant time flag from b, but make it sticky on a. */
|
||||
a->flags |= b->flags & BN_FLG_CONSTTIME;
|
||||
|
||||
a->top = b->top;
|
||||
a->neg = b->neg;
|
||||
|
||||
return (a);
|
||||
}
|
||||
|
||||
int
|
||||
bn_copy(BIGNUM *dst, const BIGNUM *src)
|
||||
{
|
||||
return BN_copy(dst, src) != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
BN_swap(BIGNUM *a, BIGNUM *b)
|
||||
{
|
||||
int flags_old_a, flags_old_b;
|
||||
BN_ULONG *tmp_d;
|
||||
int tmp_top, tmp_dmax, tmp_neg;
|
||||
|
||||
|
||||
flags_old_a = a->flags;
|
||||
flags_old_b = b->flags;
|
||||
|
||||
tmp_d = a->d;
|
||||
tmp_top = a->top;
|
||||
tmp_dmax = a->dmax;
|
||||
tmp_neg = a->neg;
|
||||
|
||||
a->d = b->d;
|
||||
a->top = b->top;
|
||||
a->dmax = b->dmax;
|
||||
a->neg = b->neg;
|
||||
|
||||
b->d = tmp_d;
|
||||
b->top = tmp_top;
|
||||
b->dmax = tmp_dmax;
|
||||
b->neg = tmp_neg;
|
||||
|
||||
a->flags = (flags_old_a & BN_FLG_MALLOCED) |
|
||||
(flags_old_b & BN_FLG_STATIC_DATA);
|
||||
b->flags = (flags_old_b & BN_FLG_MALLOCED) |
|
||||
(flags_old_a & BN_FLG_STATIC_DATA);
|
||||
}
|
||||
|
||||
BN_ULONG
|
||||
BN_get_word(const BIGNUM *a)
|
||||
{
|
||||
if (a->top > 1)
|
||||
return BN_MASK2;
|
||||
else if (a->top == 1)
|
||||
return a->d[0];
|
||||
/* a->top == 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
BN_set_word(BIGNUM *a, BN_ULONG w)
|
||||
{
|
||||
if (!bn_wexpand(a, 1))
|
||||
return (0);
|
||||
a->neg = 0;
|
||||
a->d[0] = w;
|
||||
a->top = (w ? 1 : 0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_ucmp(const BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (a->top < b->top)
|
||||
return -1;
|
||||
if (a->top > b->top)
|
||||
return 1;
|
||||
|
||||
for (i = a->top - 1; i >= 0; i--) {
|
||||
if (a->d[i] != b->d[i])
|
||||
return (a->d[i] > b->d[i] ? 1 : -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
BN_cmp(const BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
if (a == NULL || b == NULL) {
|
||||
if (a != NULL)
|
||||
return -1;
|
||||
if (b != NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->neg != b->neg)
|
||||
return b->neg - a->neg;
|
||||
|
||||
if (a->neg)
|
||||
return BN_ucmp(b, a);
|
||||
|
||||
return BN_ucmp(a, b);
|
||||
}
|
||||
|
||||
int
|
||||
BN_set_bit(BIGNUM *a, int n)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
if (n < 0)
|
||||
return 0;
|
||||
|
||||
i = n / BN_BITS2;
|
||||
j = n % BN_BITS2;
|
||||
if (a->top <= i) {
|
||||
if (!bn_wexpand(a, i + 1))
|
||||
return (0);
|
||||
for (k = a->top; k < i + 1; k++)
|
||||
a->d[k] = 0;
|
||||
a->top = i + 1;
|
||||
}
|
||||
|
||||
a->d[i] |= (((BN_ULONG)1) << j);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_clear_bit(BIGNUM *a, int n)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (n < 0)
|
||||
return 0;
|
||||
|
||||
i = n / BN_BITS2;
|
||||
j = n % BN_BITS2;
|
||||
if (a->top <= i)
|
||||
return (0);
|
||||
|
||||
a->d[i] &= (~(((BN_ULONG)1) << j));
|
||||
bn_correct_top(a);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_bit_set(const BIGNUM *a, int n)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (n < 0)
|
||||
return 0;
|
||||
i = n / BN_BITS2;
|
||||
j = n % BN_BITS2;
|
||||
if (a->top <= i)
|
||||
return 0;
|
||||
return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
|
||||
}
|
||||
|
||||
int
|
||||
BN_mask_bits(BIGNUM *a, int n)
|
||||
{
|
||||
int b, w;
|
||||
|
||||
if (n < 0)
|
||||
return 0;
|
||||
|
||||
w = n / BN_BITS2;
|
||||
b = n % BN_BITS2;
|
||||
if (w >= a->top)
|
||||
return 0;
|
||||
if (b == 0)
|
||||
a->top = w;
|
||||
else {
|
||||
a->top = w + 1;
|
||||
a->d[w] &= ~(BN_MASK2 << b);
|
||||
}
|
||||
bn_correct_top(a);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
BN_set_negative(BIGNUM *bn, int neg)
|
||||
{
|
||||
bn->neg = ~BN_is_zero(bn) & bn_ct_ne_zero(neg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constant-time conditional swap of a and b.
|
||||
* a and b are swapped if condition is not 0.
|
||||
* The code assumes that at most one bit of condition is set.
|
||||
* nwords is the number of words to swap.
|
||||
* The code assumes that at least nwords are allocated in both a and b,
|
||||
* and that no more than nwords are used by either a or b.
|
||||
* a and b cannot be the same number
|
||||
*/
|
||||
void
|
||||
BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
|
||||
{
|
||||
BN_ULONG t;
|
||||
int i;
|
||||
|
||||
assert(a != b);
|
||||
assert((condition & (condition - 1)) == 0);
|
||||
assert(sizeof(BN_ULONG) >= sizeof(int));
|
||||
|
||||
condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
|
||||
|
||||
t = (a->top^b->top) & condition;
|
||||
a->top ^= t;
|
||||
b->top ^= t;
|
||||
|
||||
#define BN_CONSTTIME_SWAP(ind) \
|
||||
do { \
|
||||
t = (a->d[ind] ^ b->d[ind]) & condition; \
|
||||
a->d[ind] ^= t; \
|
||||
b->d[ind] ^= t; \
|
||||
} while (0)
|
||||
|
||||
|
||||
switch (nwords) {
|
||||
default:
|
||||
for (i = 10; i < nwords; i++)
|
||||
BN_CONSTTIME_SWAP(i);
|
||||
/* Fallthrough */
|
||||
case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
|
||||
case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
|
||||
case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
|
||||
case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
|
||||
case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
|
||||
case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
|
||||
case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
|
||||
case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
|
||||
case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
|
||||
case 1:
|
||||
BN_CONSTTIME_SWAP(0);
|
||||
}
|
||||
#undef BN_CONSTTIME_SWAP
|
||||
}
|
||||
|
||||
/*
|
||||
* Constant-time conditional swap of a and b.
|
||||
* a and b are swapped if condition is not 0.
|
||||
* nwords is the number of words to swap.
|
||||
*/
|
||||
int
|
||||
BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, size_t nwords)
|
||||
{
|
||||
BN_ULONG t;
|
||||
int i, words;
|
||||
|
||||
if (a == b)
|
||||
return 1;
|
||||
if (nwords > INT_MAX)
|
||||
return 0;
|
||||
words = (int)nwords;
|
||||
if (!bn_wexpand(a, words) || !bn_wexpand(b, words))
|
||||
return 0;
|
||||
if (a->top > words || b->top > words) {
|
||||
BNerror(BN_R_INVALID_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set condition to 0 (if it was zero) or all 1s otherwise. */
|
||||
condition = ((~condition & (condition - 1)) >> (BN_BITS2 - 1)) - 1;
|
||||
|
||||
/* swap top field */
|
||||
t = (a->top ^ b->top) & condition;
|
||||
a->top ^= t;
|
||||
b->top ^= t;
|
||||
|
||||
/* swap neg field */
|
||||
t = (a->neg ^ b->neg) & condition;
|
||||
a->neg ^= t;
|
||||
b->neg ^= t;
|
||||
|
||||
/* swap BN_FLG_CONSTTIME from flag field */
|
||||
t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition;
|
||||
a->flags ^= t;
|
||||
b->flags ^= t;
|
||||
|
||||
/* swap the data */
|
||||
for (i = 0; i < words; i++) {
|
||||
t = (a->d[i] ^ b->d[i]) & condition;
|
||||
a->d[i] ^= t;
|
||||
b->d[i] ^= t;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
BN_zero(BIGNUM *a)
|
||||
{
|
||||
a->neg = 0;
|
||||
a->top = 0;
|
||||
}
|
||||
|
||||
int
|
||||
BN_one(BIGNUM *a)
|
||||
{
|
||||
return BN_set_word(a, 1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
|
||||
{
|
||||
return (a->top == 1 && a->d[0] == w) || (w == 0 && a->top == 0);
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_zero(const BIGNUM *bn)
|
||||
{
|
||||
BN_ULONG bits = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bn->top; i++)
|
||||
bits |= bn->d[i];
|
||||
|
||||
return bits == 0;
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_one(const BIGNUM *a)
|
||||
{
|
||||
return BN_abs_is_word(a, 1) && !a->neg;
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_word(const BIGNUM *a, const BN_ULONG w)
|
||||
{
|
||||
return BN_abs_is_word(a, w) && (w == 0 || !a->neg);
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_odd(const BIGNUM *a)
|
||||
{
|
||||
return a->top > 0 && (a->d[0] & 1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_negative(const BIGNUM *a)
|
||||
{
|
||||
return a->neg != 0;
|
||||
}
|
||||
|
||||
char *
|
||||
BN_options(void)
|
||||
{
|
||||
static int init = 0;
|
||||
static char data[16];
|
||||
|
||||
if (!init) {
|
||||
init++;
|
||||
#ifdef BN_LLONG
|
||||
snprintf(data,sizeof data, "bn(%d,%d)",
|
||||
(int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8);
|
||||
#else
|
||||
snprintf(data,sizeof data, "bn(%d,%d)",
|
||||
(int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8);
|
||||
#endif
|
||||
}
|
||||
return (data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bits of security, see SP800-57, section 5.6.11, table 2.
|
||||
*/
|
||||
int
|
||||
BN_security_bits(int L, int N)
|
||||
{
|
||||
int secbits, bits;
|
||||
|
||||
if (L >= 15360)
|
||||
secbits = 256;
|
||||
else if (L >= 7680)
|
||||
secbits = 192;
|
||||
else if (L >= 3072)
|
||||
secbits = 128;
|
||||
else if (L >= 2048)
|
||||
secbits = 112;
|
||||
else if (L >= 1024)
|
||||
secbits = 80;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (N == -1)
|
||||
return secbits;
|
||||
|
||||
bits = N / 2;
|
||||
if (bits < 80)
|
||||
return 0;
|
||||
|
||||
return bits >= secbits ? secbits : bits;
|
||||
}
|
||||
|
||||
BN_GENCB *
|
||||
BN_GENCB_new(void)
|
||||
{
|
||||
BN_GENCB *cb;
|
||||
|
||||
if ((cb = calloc(1, sizeof(*cb))) == NULL)
|
||||
return NULL;
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
void
|
||||
BN_GENCB_free(BN_GENCB *cb)
|
||||
{
|
||||
if (cb == NULL)
|
||||
return;
|
||||
free(cb);
|
||||
}
|
||||
|
||||
/* Populate a BN_GENCB structure with an "old"-style callback */
|
||||
void
|
||||
BN_GENCB_set_old(BN_GENCB *gencb, void (*cb)(int, int, void *), void *cb_arg)
|
||||
{
|
||||
gencb->ver = 1;
|
||||
gencb->cb.cb_1 = cb;
|
||||
gencb->arg = cb_arg;
|
||||
}
|
||||
|
||||
/* Populate a BN_GENCB structure with a "new"-style callback */
|
||||
void
|
||||
BN_GENCB_set(BN_GENCB *gencb, int (*cb)(int, int, BN_GENCB *), void *cb_arg)
|
||||
{
|
||||
gencb->ver = 2;
|
||||
gencb->cb.cb_2 = cb;
|
||||
gencb->arg = cb_arg;
|
||||
}
|
||||
|
||||
void *
|
||||
BN_GENCB_get_arg(BN_GENCB *cb)
|
||||
{
|
||||
return cb->arg;
|
||||
}
|
||||
330
externals/libressl/crypto/bn/bn_local.h
vendored
Normal file
330
externals/libressl/crypto/bn/bn_local.h
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
/* $OpenBSD: bn_local.h,v 1.22 2023/05/10 12:21:55 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BN_LOCAL_H
|
||||
#define HEADER_BN_LOCAL_H
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
struct bignum_st {
|
||||
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
|
||||
int top; /* Index of last used d +1. */
|
||||
/* The next are internal book keeping for bn_expand. */
|
||||
int dmax; /* Size of the d array. */
|
||||
int neg; /* one if the number is negative */
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct bn_mont_ctx_st {
|
||||
int ri; /* Number of bits in R */
|
||||
BIGNUM RR; /* Used to convert to Montgomery form */
|
||||
BIGNUM N; /* Modulus */
|
||||
|
||||
/* Least significant word(s) of Ni; R*(1/R mod N) - N*Ni = 1 */
|
||||
BN_ULONG n0[2];
|
||||
|
||||
int flags;
|
||||
};
|
||||
|
||||
/* Used for reciprocal division/mod functions
|
||||
* It cannot be shared between threads
|
||||
*/
|
||||
typedef struct bn_recp_ctx_st {
|
||||
BIGNUM N; /* the divisor */
|
||||
BIGNUM Nr; /* the reciprocal */
|
||||
int num_bits;
|
||||
int shift;
|
||||
int flags;
|
||||
} BN_RECP_CTX;
|
||||
|
||||
/* Used for slow "generation" functions. */
|
||||
struct bn_gencb_st {
|
||||
unsigned int ver; /* To handle binary (in)compatibility */
|
||||
void *arg; /* callback-specific data */
|
||||
union {
|
||||
/* if(ver==1) - handles old style callbacks */
|
||||
void (*cb_1)(int, int, void *);
|
||||
/* if(ver==2) - new callback style */
|
||||
int (*cb_2)(int, int, BN_GENCB *);
|
||||
} cb;
|
||||
};
|
||||
|
||||
/*
|
||||
* BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
|
||||
*
|
||||
*
|
||||
* For window size 'w' (w >= 2) and a random 'b' bits exponent,
|
||||
* the number of multiplications is a constant plus on average
|
||||
*
|
||||
* 2^(w-1) + (b-w)/(w+1);
|
||||
*
|
||||
* here 2^(w-1) is for precomputing the table (we actually need
|
||||
* entries only for windows that have the lowest bit set), and
|
||||
* (b-w)/(w+1) is an approximation for the expected number of
|
||||
* w-bit windows, not counting the first one.
|
||||
*
|
||||
* Thus we should use
|
||||
*
|
||||
* w >= 6 if b > 671
|
||||
* w = 5 if 671 > b > 239
|
||||
* w = 4 if 239 > b > 79
|
||||
* w = 3 if 79 > b > 23
|
||||
* w <= 2 if 23 > b
|
||||
*
|
||||
* (with draws in between). Very small exponents are often selected
|
||||
* with low Hamming weight, so we use w = 1 for b <= 23.
|
||||
*/
|
||||
#define BN_window_bits_for_exponent_size(b) \
|
||||
((b) > 671 ? 6 : \
|
||||
(b) > 239 ? 5 : \
|
||||
(b) > 79 ? 4 : \
|
||||
(b) > 23 ? 3 : 1)
|
||||
|
||||
|
||||
/* BN_mod_exp_mont_consttime is based on the assumption that the
|
||||
* L1 data cache line width of the target processor is at least
|
||||
* the following value.
|
||||
*/
|
||||
#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH ( 64 )
|
||||
#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
|
||||
|
||||
/* Window sizes optimized for fixed window size modular exponentiation
|
||||
* algorithm (BN_mod_exp_mont_consttime).
|
||||
*
|
||||
* To achieve the security goals of BN_mode_exp_mont_consttime, the
|
||||
* maximum size of the window must not exceed
|
||||
* log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH).
|
||||
*
|
||||
* Window size thresholds are defined for cache line sizes of 32 and 64,
|
||||
* cache line sizes where log_2(32)=5 and log_2(64)=6 respectively. A
|
||||
* window size of 7 should only be used on processors that have a 128
|
||||
* byte or greater cache line size.
|
||||
*/
|
||||
#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
|
||||
|
||||
# define BN_window_bits_for_ctime_exponent_size(b) \
|
||||
((b) > 937 ? 6 : \
|
||||
(b) > 306 ? 5 : \
|
||||
(b) > 89 ? 4 : \
|
||||
(b) > 22 ? 3 : 1)
|
||||
# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6)
|
||||
|
||||
#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
|
||||
|
||||
# define BN_window_bits_for_ctime_exponent_size(b) \
|
||||
((b) > 306 ? 5 : \
|
||||
(b) > 89 ? 4 : \
|
||||
(b) > 22 ? 3 : 1)
|
||||
# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Pentium pro 16,16,16,32,64 */
|
||||
/* Alpha 16,16,16,16.64 */
|
||||
#define BN_MULL_SIZE_NORMAL (16) /* 32 */
|
||||
#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */
|
||||
#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
|
||||
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
|
||||
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
|
||||
|
||||
/* The least significant word of a BIGNUM. */
|
||||
#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
|
||||
|
||||
BN_ULONG bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len,
|
||||
const BN_ULONG *b, int b_len);
|
||||
BN_ULONG bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len,
|
||||
const BN_ULONG *b, int b_len);
|
||||
|
||||
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
|
||||
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
|
||||
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
|
||||
|
||||
void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
|
||||
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
|
||||
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
|
||||
|
||||
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
const BN_ULONG *np, const BN_ULONG *n0, int num);
|
||||
|
||||
int bn_word_clz(BN_ULONG w);
|
||||
|
||||
void bn_correct_top(BIGNUM *a);
|
||||
int bn_expand(BIGNUM *a, int bits);
|
||||
int bn_wexpand(BIGNUM *a, int words);
|
||||
|
||||
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
int num);
|
||||
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
int num);
|
||||
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
|
||||
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
|
||||
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
|
||||
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
|
||||
void bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
|
||||
BN_ULONG *out_r);
|
||||
|
||||
int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
|
||||
int bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc);
|
||||
|
||||
void BN_init(BIGNUM *);
|
||||
|
||||
int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
|
||||
|
||||
void BN_RECP_CTX_init(BN_RECP_CTX *recp);
|
||||
BN_RECP_CTX *BN_RECP_CTX_new(void);
|
||||
void BN_RECP_CTX_free(BN_RECP_CTX *recp);
|
||||
int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx);
|
||||
int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
|
||||
BN_RECP_CTX *recp, BN_CTX *ctx);
|
||||
int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx);
|
||||
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
|
||||
BN_RECP_CTX *recp, BN_CTX *ctx);
|
||||
|
||||
/* Explicitly const time / non-const time versions for internal use */
|
||||
int BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx);
|
||||
int BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx);
|
||||
int BN_mod_exp_mont_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
||||
int BN_mod_exp_mont_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
||||
int BN_div_nonct(BIGNUM *q, BIGNUM *r, const BIGNUM *n, const BIGNUM *d,
|
||||
BN_CTX *ctx);
|
||||
int BN_div_ct(BIGNUM *q, BIGNUM *r, const BIGNUM *n, const BIGNUM *d,
|
||||
BN_CTX *ctx);
|
||||
int BN_mod_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
|
||||
int BN_mod_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
|
||||
|
||||
BIGNUM *BN_mod_inverse_ct(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *ctx);
|
||||
BIGNUM *BN_mod_inverse_nonct(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *ctx);
|
||||
int BN_gcd_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
|
||||
int BN_gcd_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
|
||||
|
||||
int BN_swap_ct(BN_ULONG swap, BIGNUM *a, BIGNUM *b, size_t nwords);
|
||||
|
||||
int bn_copy(BIGNUM *dst, const BIGNUM *src);
|
||||
|
||||
int bn_isqrt(BIGNUM *out_sqrt, int *out_perfect, const BIGNUM *n, BN_CTX *ctx);
|
||||
int bn_is_perfect_square(int *out_perfect, const BIGNUM *n, BN_CTX *ctx);
|
||||
|
||||
int bn_is_prime_bpsw(int *is_prime, const BIGNUM *n, BN_CTX *ctx, size_t rounds);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
#endif /* !HEADER_BN_LOCAL_H */
|
||||
315
externals/libressl/crypto/bn/bn_mod.c
vendored
Normal file
315
externals/libressl/crypto/bn/bn_mod.c
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
/* $OpenBSD: bn_mod.c,v 1.20 2023/03/27 10:21:23 tb Exp $ */
|
||||
/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
|
||||
* for the OpenSSL project. */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
int
|
||||
BN_mod_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
|
||||
{
|
||||
return BN_div_ct(NULL, r, a, m, ctx);
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
|
||||
{
|
||||
return BN_div_nonct(NULL, r, a, m, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_nnmod() is like BN_mod(), but always returns a non-negative remainder
|
||||
* (that is 0 <= r < |m| always holds). If both a and m have the same sign then
|
||||
* the result is already non-negative. Otherwise, -|m| < r < 0, which needs to
|
||||
* be adjusted as r := r + |m|. This equates to r := |m| - |r|.
|
||||
*/
|
||||
int
|
||||
BN_nnmod(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
|
||||
{
|
||||
if (!BN_mod_ct(r, a, m, ctx))
|
||||
return 0;
|
||||
if (BN_is_negative(r))
|
||||
return BN_usub(r, m, r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
if (!BN_add(r, a, b))
|
||||
return 0;
|
||||
return BN_nnmod(r, r, m, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_mod_add() variant that may only be used if both a and b are non-negative
|
||||
* and have already been reduced (less than m).
|
||||
*/
|
||||
int
|
||||
BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
|
||||
{
|
||||
if (!BN_uadd(r, a, b))
|
||||
return 0;
|
||||
if (BN_ucmp(r, m) >= 0)
|
||||
return BN_usub(r, r, m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
if (!BN_sub(r, a, b))
|
||||
return 0;
|
||||
return BN_nnmod(r, r, m, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_mod_sub() variant that may only be used if both a and b are non-negative
|
||||
* and have already been reduced (less than m).
|
||||
*/
|
||||
int
|
||||
BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
|
||||
{
|
||||
if (BN_ucmp(a, b) >= 0)
|
||||
return BN_usub(r, a, b);
|
||||
if (!BN_usub(r, b, a))
|
||||
return 0;
|
||||
return BN_usub(r, m, r);
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *rr;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
rr = r;
|
||||
if (rr == a || rr == b)
|
||||
rr = BN_CTX_get(ctx);
|
||||
if (rr == NULL)
|
||||
goto err;
|
||||
|
||||
if (a == b) {
|
||||
if (!BN_sqr(rr, a, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mul(rr, a, b, ctx))
|
||||
goto err;
|
||||
}
|
||||
if (!BN_nnmod(r, rr, m, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
|
||||
{
|
||||
return BN_mod_mul(r, a, a, m, ctx);
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
|
||||
{
|
||||
if (!BN_lshift1(r, a))
|
||||
return 0;
|
||||
return BN_nnmod(r, r, m, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_mod_lshift1() variant that may be used if a is non-negative
|
||||
* and has already been reduced (less than m).
|
||||
*/
|
||||
int
|
||||
BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
|
||||
{
|
||||
if (!BN_lshift1(r, a))
|
||||
return 0;
|
||||
if (BN_ucmp(r, m) >= 0)
|
||||
return BN_usub(r, r, m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *abs_m;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if (!BN_nnmod(r, a, m, ctx))
|
||||
goto err;
|
||||
|
||||
if (BN_is_negative(m)) {
|
||||
if ((abs_m = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if (!bn_copy(abs_m, m))
|
||||
goto err;
|
||||
BN_set_negative(abs_m, 0);
|
||||
m = abs_m;
|
||||
}
|
||||
if (!BN_mod_lshift_quick(r, r, n, m))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_mod_lshift() variant that may be used if a is non-negative
|
||||
* and has already been reduced (less than m).
|
||||
*/
|
||||
int
|
||||
BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
|
||||
{
|
||||
int max_shift;
|
||||
|
||||
if (!bn_copy(r, a))
|
||||
return 0;
|
||||
|
||||
while (n > 0) {
|
||||
if ((max_shift = BN_num_bits(m) - BN_num_bits(r)) < 0) {
|
||||
BNerror(BN_R_INPUT_NOT_REDUCED);
|
||||
return 0;
|
||||
}
|
||||
if (max_shift == 0)
|
||||
max_shift = 1;
|
||||
if (max_shift > n)
|
||||
max_shift = n;
|
||||
|
||||
if (!BN_lshift(r, r, max_shift))
|
||||
return 0;
|
||||
n -= max_shift;
|
||||
|
||||
if (BN_ucmp(r, m) >= 0) {
|
||||
if (!BN_usub(r, r, m))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
726
externals/libressl/crypto/bn/bn_mod_sqrt.c
vendored
Normal file
726
externals/libressl/crypto/bn/bn_mod_sqrt.c
vendored
Normal file
@@ -0,0 +1,726 @@
|
||||
/* $OpenBSD: bn_mod_sqrt.c,v 1.1 2023/04/11 10:08:44 tb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
/*
|
||||
* Tonelli-Shanks according to H. Cohen "A Course in Computational Algebraic
|
||||
* Number Theory", Section 1.5.1, Springer GTM volume 138, Berlin, 1996.
|
||||
*
|
||||
* Under the assumption that p is prime and a is a quadratic residue, we know:
|
||||
*
|
||||
* a^[(p-1)/2] = 1 (mod p). (*)
|
||||
*
|
||||
* To find a square root of a (mod p), we handle three cases of increasing
|
||||
* complexity. In the first two cases, we can compute a square root using an
|
||||
* explicit formula, thus avoiding the probabilistic nature of Tonelli-Shanks.
|
||||
*
|
||||
* 1. p = 3 (mod 4).
|
||||
*
|
||||
* Set n = (p+1)/4. Then 2n = 1 + (p-1)/2 and (*) shows that x = a^n (mod p)
|
||||
* is a square root of a: x^2 = a^(2n) = a * a^[(p-1)/2] = a (mod p).
|
||||
*
|
||||
* 2. p = 5 (mod 8).
|
||||
*
|
||||
* This uses a simplification due to Atkin. By Theorem 1.4.7 and 1.4.9, the
|
||||
* Kronecker symbol (2/p) evaluates to (-1)^[(p^2-1)/8]. From p = 5 (mod 8)
|
||||
* we get (p^2-1)/8 = 1 (mod 2), so (2/p) = -1, and thus
|
||||
*
|
||||
* 2^[(p-1)/2] = -1 (mod p). (**)
|
||||
*
|
||||
* Set b = (2a)^[(p-5)/8]. With (p-1)/2 = 2 + (p-5)/2, (*) and (**) show
|
||||
*
|
||||
* i = 2 a b^2 is a square root of -1 (mod p).
|
||||
*
|
||||
* Indeed, i^2 = 2^2 a^2 b^4 = 2^[(p-1)/2] a^[(p-1)/2] = -1 (mod p). Because
|
||||
* of (i-1)^2 = -2i (mod p) and i (-i) = 1 (mod p), a square root of a is
|
||||
*
|
||||
* x = a b (i-1)
|
||||
*
|
||||
* as x^2 = a^2 b^2 (-2i) = a (2 a b^2) (-i) = a (mod p).
|
||||
*
|
||||
* 3. p = 1 (mod 8).
|
||||
*
|
||||
* This is the Tonelli-Shanks algorithm. For a prime p, the multiplicative
|
||||
* group of GF(p) is cyclic of order p - 1 = 2^s q, with odd q. Denote its
|
||||
* 2-Sylow subgroup by S. It is cyclic of order 2^s. The squares in S have
|
||||
* order dividing 2^(s-1). They are the even powers of any generator z of S.
|
||||
* If a is a quadratic residue, 1 = a^[(p-1)/2] = (a^q)^[2^(s-1)], so b = a^q
|
||||
* is a square in S. Therefore there is an integer k such that b z^(2k) = 1.
|
||||
* Set x = a^[(q+1)/2] z^k, and find x^2 = a (mod p).
|
||||
*
|
||||
* The problem is thus reduced to finding a generator z of the 2-Sylow
|
||||
* subgroup S of GF(p)* and finding k. An iterative constructions avoids
|
||||
* the need for an explicit k, a generator is found by a randomized search.
|
||||
*
|
||||
* While we do not actually know that p is a prime number, we can still apply
|
||||
* the formulas in cases 1 and 2 and verify that we have indeed found a square
|
||||
* root of p. Similarly, in case 3, we can try to find a quadratic non-residue,
|
||||
* which will fail for example if p is a square. The iterative construction
|
||||
* may or may not find a candidate square root which we can then validate.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Handle the cases where p is 2, p isn't odd or p is one. Since BN_mod_sqrt()
|
||||
* can run on untrusted data, a primality check is too expensive. Also treat
|
||||
* the obvious cases where a is 0 or 1.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_trivial_cases(int *done, BIGNUM *out_sqrt, const BIGNUM *a,
|
||||
const BIGNUM *p, BN_CTX *ctx)
|
||||
{
|
||||
*done = 1;
|
||||
|
||||
if (BN_abs_is_word(p, 2))
|
||||
return BN_set_word(out_sqrt, BN_is_odd(a));
|
||||
|
||||
if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
|
||||
BNerror(BN_R_P_IS_NOT_PRIME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_is_zero(a) || BN_is_one(a))
|
||||
return BN_set_word(out_sqrt, BN_is_one(a));
|
||||
|
||||
*done = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case 1. We know that (a/p) = 1 and that p = 3 (mod 4).
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_p_is_3_mod_4(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *n;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((n = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Calculate n = (|p| + 1) / 4. */
|
||||
if (!BN_uadd(n, p, BN_value_one()))
|
||||
goto err;
|
||||
if (!BN_rshift(n, n, 2))
|
||||
goto err;
|
||||
|
||||
/* By case 1 above, out_sqrt = a^n is a square root of a (mod p). */
|
||||
if (!BN_mod_exp_ct(out_sqrt, a, n, p, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case 2. We know that (a/p) = 1 and that p = 5 (mod 8).
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_p_is_5_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *b, *i, *n, *tmp;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((b = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((i = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((n = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((tmp = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Calculate n = (|p| - 5) / 8. Since p = 5 (mod 8), simply shift. */
|
||||
if (!BN_rshift(n, p, 3))
|
||||
goto err;
|
||||
BN_set_negative(n, 0);
|
||||
|
||||
/* Compute tmp = 2a (mod p) for later use. */
|
||||
if (!BN_mod_lshift1(tmp, a, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* Calculate b = (2a)^n (mod p). */
|
||||
if (!BN_mod_exp_ct(b, tmp, n, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* Calculate i = 2 a b^2 (mod p). */
|
||||
if (!BN_mod_sqr(i, b, p, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(i, tmp, i, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* A square root is out_sqrt = a b (i-1) (mod p). */
|
||||
if (!BN_sub_word(i, 1))
|
||||
goto err;
|
||||
if (!BN_mod_mul(out_sqrt, a, b, p, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(out_sqrt, out_sqrt, i, p, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case 3. We know that (a/p) = 1 and that p = 1 (mod 8).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Simple helper. To find a generator of the 2-Sylow subgroup of GF(p)*, we
|
||||
* need to find a quadratic non-residue of p, i.e., n such that (n/p) = -1.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_n_is_non_residue(int *is_non_residue, const BIGNUM *n,
|
||||
const BIGNUM *p, BN_CTX *ctx)
|
||||
{
|
||||
switch (BN_kronecker(n, p, ctx)) {
|
||||
case -1:
|
||||
*is_non_residue = 1;
|
||||
return 1;
|
||||
case 1:
|
||||
*is_non_residue = 0;
|
||||
return 1;
|
||||
case 0:
|
||||
/* n divides p, so ... */
|
||||
BNerror(BN_R_P_IS_NOT_PRIME);
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The following is the only non-deterministic part preparing Tonelli-Shanks.
|
||||
*
|
||||
* If we find n such that (n/p) = -1, then n^q (mod p) is a generator of the
|
||||
* 2-Sylow subgroup of GF(p)*. To find such n, first try some small numbers,
|
||||
* then random ones.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_find_sylow_generator(BIGNUM *out_generator, const BIGNUM *p,
|
||||
const BIGNUM *q, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *n, *p_abs, *thirty_two;
|
||||
int i, is_non_residue;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((n = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((thirty_two = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((p_abs = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
for (i = 2; i < 32; i++) {
|
||||
if (!BN_set_word(n, i))
|
||||
goto err;
|
||||
if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx))
|
||||
goto err;
|
||||
if (is_non_residue)
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (!BN_set_word(thirty_two, 32))
|
||||
goto err;
|
||||
if (!bn_copy(p_abs, p))
|
||||
goto err;
|
||||
BN_set_negative(p_abs, 0);
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
if (!bn_rand_interval(n, thirty_two, p_abs))
|
||||
goto err;
|
||||
if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx))
|
||||
goto err;
|
||||
if (is_non_residue)
|
||||
goto found;
|
||||
}
|
||||
|
||||
/*
|
||||
* The probability to get here is < 2^(-128) for prime p. For squares
|
||||
* it is easy: for p = 1369 = 37^2 this happens in ~3% of runs.
|
||||
*/
|
||||
|
||||
BNerror(BN_R_TOO_MANY_ITERATIONS);
|
||||
goto err;
|
||||
|
||||
found:
|
||||
/*
|
||||
* If p is prime, n^q generates the 2-Sylow subgroup S of GF(p)*.
|
||||
*/
|
||||
|
||||
if (!BN_mod_exp_ct(out_generator, n, q, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* Sanity: p is not necessarily prime, so we could have found 0 or 1. */
|
||||
if (BN_is_zero(out_generator) || BN_is_one(out_generator)) {
|
||||
BNerror(BN_R_P_IS_NOT_PRIME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization step for Tonelli-Shanks.
|
||||
*
|
||||
* In the end, b = a^q (mod p) and x = a^[(q+1)/2] (mod p). Cohen optimizes this
|
||||
* to minimize taking powers of a. This is a bit confusing and distracting, so
|
||||
* factor this into a separate function.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_tonelli_shanks_initialize(BIGNUM *b, BIGNUM *x, const BIGNUM *a,
|
||||
const BIGNUM *p, const BIGNUM *q, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *k;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((k = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* k = (q-1)/2. Since q is odd, we can shift. */
|
||||
if (!BN_rshift1(k, q))
|
||||
goto err;
|
||||
|
||||
/* x = a^[(q-1)/2] (mod p). */
|
||||
if (!BN_mod_exp_ct(x, a, k, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* b = ax^2 = a^q (mod p). */
|
||||
if (!BN_mod_sqr(b, x, p, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(b, a, b, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* x = ax = a^[(q+1)/2] (mod p). */
|
||||
if (!BN_mod_mul(x, a, x, p, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find smallest exponent m such that b^(2^m) = 1 (mod p). Assuming that a
|
||||
* is a quadratic residue and p is a prime, we know that 1 <= m < r.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_tonelli_shanks_find_exponent(int *out_exponent, const BIGNUM *b,
|
||||
const BIGNUM *p, int r, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *x;
|
||||
int m;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((x = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* If r <= 1, the Tonelli-Shanks iteration should have terminated as
|
||||
* r == 1 implies b == 1.
|
||||
*/
|
||||
if (r <= 1) {
|
||||
BNerror(BN_R_P_IS_NOT_PRIME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check to ensure taking squares actually does something:
|
||||
* If b is 1, the Tonelli-Shanks iteration should have terminated.
|
||||
* If b is 0, something's very wrong, in particular p can't be prime.
|
||||
*/
|
||||
if (BN_is_zero(b) || BN_is_one(b)) {
|
||||
BNerror(BN_R_P_IS_NOT_PRIME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!bn_copy(x, b))
|
||||
goto err;
|
||||
|
||||
for (m = 1; m < r; m++) {
|
||||
if (!BN_mod_sqr(x, x, p, ctx))
|
||||
goto err;
|
||||
if (BN_is_one(x))
|
||||
break;
|
||||
}
|
||||
|
||||
if (m >= r) {
|
||||
/* This means a is not a quadratic residue. As (a/p) = 1, ... */
|
||||
BNerror(BN_R_P_IS_NOT_PRIME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*out_exponent = m;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The update step. With the minimal m such that b^(2^m) = 1 (mod m),
|
||||
* set t = y^[2^(r-m-1)] (mod p) and update x = xt, y = t^2, b = by.
|
||||
* This preserves the loop invariants a b = x^2, y^[2^(r-1)] = -1 and
|
||||
* b^[2^(r-1)] = 1.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_tonelli_shanks_update(BIGNUM *b, BIGNUM *x, BIGNUM *y,
|
||||
const BIGNUM *p, int m, int r, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *t;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((t = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* t = y^[2^(r-m-1)] (mod p). */
|
||||
if (!BN_set_bit(t, r - m - 1))
|
||||
goto err;
|
||||
if (!BN_mod_exp_ct(t, y, t, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* x = xt (mod p). */
|
||||
if (!BN_mod_mul(x, x, t, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* y = t^2 = y^[2^(r-m)] (mod p). */
|
||||
if (!BN_mod_sqr(y, t, p, ctx))
|
||||
goto err;
|
||||
|
||||
/* b = by (mod p). */
|
||||
if (!BN_mod_mul(b, b, y, p, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_p_is_1_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *b, *q, *x, *y;
|
||||
int e, m, r;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((b = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((q = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((x = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((y = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Factor p - 1 = 2^e q with odd q. Since p = 1 (mod 8), we know e >= 3.
|
||||
*/
|
||||
|
||||
e = 1;
|
||||
while (!BN_is_bit_set(p, e))
|
||||
e++;
|
||||
if (!BN_rshift(q, p, e))
|
||||
goto err;
|
||||
|
||||
if (!bn_mod_sqrt_find_sylow_generator(y, p, q, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Set b = a^q (mod p) and x = a^[(q+1)/2] (mod p).
|
||||
*/
|
||||
if (!bn_mod_sqrt_tonelli_shanks_initialize(b, x, a, p, q, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* The Tonelli-Shanks iteration. Starting with r = e, the following loop
|
||||
* invariants hold at the start of the loop.
|
||||
*
|
||||
* a b = x^2 (mod p)
|
||||
* y^[2^(r-1)] = -1 (mod p)
|
||||
* b^[2^(r-1)] = 1 (mod p)
|
||||
*
|
||||
* In particular, if b = 1 (mod p), x is a square root of a.
|
||||
*
|
||||
* Since p - 1 = 2^e q, we have 2^(e-1) q = (p - 1) / 2, so in the first
|
||||
* iteration this follows from (a/p) = 1, (n/p) = -1, y = n^q, b = a^q.
|
||||
*
|
||||
* In subsequent iterations, t = y^[2^(r-m-1)], where m is the smallest
|
||||
* m such that b^(2^m) = 1. With x = xt (mod p) and b = bt^2 (mod p) the
|
||||
* first invariant is preserved, the second and third follow from
|
||||
* y = t^2 (mod p) and r = m as well as the choice of m.
|
||||
*
|
||||
* Finally, r is strictly decreasing in each iteration. If p is prime,
|
||||
* let S be the 2-Sylow subgroup of GF(p)*. We can prove the algorithm
|
||||
* stops: Let S_r be the subgroup of S consisting of elements of order
|
||||
* dividing 2^r. Then S_r = <y> and b is in S_(r-1). The S_r form a
|
||||
* descending filtration of S and when r = 1, then b = 1.
|
||||
*/
|
||||
|
||||
for (r = e; r >= 1; r = m) {
|
||||
/*
|
||||
* Termination condition. If b == 1 then x is a square root.
|
||||
*/
|
||||
if (BN_is_one(b))
|
||||
goto done;
|
||||
|
||||
/* Find smallest exponent 1 <= m < r such that b^(2^m) == 1. */
|
||||
if (!bn_mod_sqrt_tonelli_shanks_find_exponent(&m, b, p, r, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* With t = y^[2^(r-m-1)], update x = xt, y = t^2, b = by.
|
||||
*/
|
||||
if (!bn_mod_sqrt_tonelli_shanks_update(b, x, y, p, m, r, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Sanity check to make sure we don't loop indefinitely.
|
||||
* bn_mod_sqrt_tonelli_shanks_find_exponent() ensures m < r.
|
||||
*/
|
||||
if (r <= m)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If p is prime, we should not get here.
|
||||
*/
|
||||
|
||||
BNerror(BN_R_NOT_A_SQUARE);
|
||||
goto err;
|
||||
|
||||
done:
|
||||
if (!bn_copy(out_sqrt, x))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Choose the smaller of sqrt and |p| - sqrt.
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_normalize(BIGNUM *sqrt, const BIGNUM *p, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *x;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((x = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_lshift1(x, sqrt))
|
||||
goto err;
|
||||
|
||||
if (BN_ucmp(x, p) > 0) {
|
||||
if (!BN_usub(sqrt, p, sqrt))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that a = (sqrt_a)^2 (mod p). Requires that a is reduced (mod p).
|
||||
*/
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_verify(const BIGNUM *a, const BIGNUM *sqrt_a, const BIGNUM *p,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *x;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((x = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_mod_sqr(x, sqrt_a, p, ctx))
|
||||
goto err;
|
||||
|
||||
if (BN_cmp(x, a) != 0) {
|
||||
BNerror(BN_R_NOT_A_SQUARE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
bn_mod_sqrt_internal(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *a_mod_p, *sqrt;
|
||||
BN_ULONG lsw;
|
||||
int done;
|
||||
int kronecker;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((a_mod_p = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((sqrt = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_nnmod(a_mod_p, a, p, ctx))
|
||||
goto err;
|
||||
|
||||
if (!bn_mod_sqrt_trivial_cases(&done, sqrt, a_mod_p, p, ctx))
|
||||
goto err;
|
||||
if (done)
|
||||
goto verify;
|
||||
|
||||
/*
|
||||
* Make sure that the Kronecker symbol (a/p) == 1. In case p is prime
|
||||
* this is equivalent to a having a square root (mod p). The cost of
|
||||
* BN_kronecker() is O(log^2(n)). This is small compared to the cost
|
||||
* O(log^4(n)) of Tonelli-Shanks.
|
||||
*/
|
||||
|
||||
if ((kronecker = BN_kronecker(a_mod_p, p, ctx)) == -2)
|
||||
goto err;
|
||||
if (kronecker <= 0) {
|
||||
/* This error is only accurate if p is known to be a prime. */
|
||||
BNerror(BN_R_NOT_A_SQUARE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
lsw = BN_lsw(p);
|
||||
|
||||
if (lsw % 4 == 3) {
|
||||
if (!bn_mod_sqrt_p_is_3_mod_4(sqrt, a_mod_p, p, ctx))
|
||||
goto err;
|
||||
} else if (lsw % 8 == 5) {
|
||||
if (!bn_mod_sqrt_p_is_5_mod_8(sqrt, a_mod_p, p, ctx))
|
||||
goto err;
|
||||
} else if (lsw % 8 == 1) {
|
||||
if (!bn_mod_sqrt_p_is_1_mod_8(sqrt, a_mod_p, p, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
/* Impossible to hit since the trivial cases ensure p is odd. */
|
||||
BNerror(BN_R_P_IS_NOT_PRIME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!bn_mod_sqrt_normalize(sqrt, p, ctx))
|
||||
goto err;
|
||||
|
||||
verify:
|
||||
if (!bn_mod_sqrt_verify(a_mod_p, sqrt, p, ctx))
|
||||
goto err;
|
||||
|
||||
if (!bn_copy(out_sqrt, sqrt))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *out_sqrt;
|
||||
|
||||
if ((out_sqrt = in) == NULL)
|
||||
out_sqrt = BN_new();
|
||||
if (out_sqrt == NULL)
|
||||
goto err;
|
||||
|
||||
if (!bn_mod_sqrt_internal(out_sqrt, a, p, ctx))
|
||||
goto err;
|
||||
|
||||
return out_sqrt;
|
||||
|
||||
err:
|
||||
if (out_sqrt != in)
|
||||
BN_free(out_sqrt);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
572
externals/libressl/crypto/bn/bn_mont.c
vendored
Normal file
572
externals/libressl/crypto/bn/bn_mont.c
vendored
Normal file
@@ -0,0 +1,572 @@
|
||||
/* $OpenBSD: bn_mont.c,v 1.59 2023/04/30 05:21:20 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Details about Montgomery multiplication algorithms can be found at
|
||||
* http://security.ece.orst.edu/publications.html, e.g.
|
||||
* http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
|
||||
* sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bn_internal.h"
|
||||
#include "bn_local.h"
|
||||
|
||||
BN_MONT_CTX *
|
||||
BN_MONT_CTX_new(void)
|
||||
{
|
||||
BN_MONT_CTX *mctx;
|
||||
|
||||
if ((mctx = calloc(1, sizeof(BN_MONT_CTX))) == NULL)
|
||||
return NULL;
|
||||
mctx->flags = BN_FLG_MALLOCED;
|
||||
|
||||
BN_init(&mctx->RR);
|
||||
BN_init(&mctx->N);
|
||||
|
||||
return mctx;
|
||||
}
|
||||
|
||||
void
|
||||
BN_MONT_CTX_free(BN_MONT_CTX *mctx)
|
||||
{
|
||||
if (mctx == NULL)
|
||||
return;
|
||||
|
||||
BN_free(&mctx->RR);
|
||||
BN_free(&mctx->N);
|
||||
|
||||
if (mctx->flags & BN_FLG_MALLOCED)
|
||||
free(mctx);
|
||||
}
|
||||
|
||||
BN_MONT_CTX *
|
||||
BN_MONT_CTX_copy(BN_MONT_CTX *dst, BN_MONT_CTX *src)
|
||||
{
|
||||
if (dst == src)
|
||||
return dst;
|
||||
|
||||
if (!bn_copy(&dst->RR, &src->RR))
|
||||
return NULL;
|
||||
if (!bn_copy(&dst->N, &src->N))
|
||||
return NULL;
|
||||
|
||||
dst->ri = src->ri;
|
||||
dst->n0[0] = src->n0[0];
|
||||
dst->n0[1] = src->n0[1];
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
int
|
||||
BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *N, *Ninv, *Rinv, *R;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((N = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((Ninv = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((R = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((Rinv = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Save modulus and determine length of R. */
|
||||
if (BN_is_zero(mod))
|
||||
goto err;
|
||||
if (!bn_copy(&mont->N, mod))
|
||||
goto err;
|
||||
mont->N.neg = 0;
|
||||
mont->ri = ((BN_num_bits(mod) + BN_BITS2 - 1) / BN_BITS2) * BN_BITS2;
|
||||
if (mont->ri * 2 < mont->ri)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Compute Ninv = (R * Rinv - 1)/N mod R, for R = 2^64. This provides
|
||||
* a single or double word result (dependent on BN word size), that is
|
||||
* later used to implement Montgomery reduction.
|
||||
*/
|
||||
BN_zero(R);
|
||||
if (!BN_set_bit(R, 64))
|
||||
goto err;
|
||||
|
||||
/* N = N mod R. */
|
||||
if (!bn_wexpand(N, 2))
|
||||
goto err;
|
||||
if (!BN_set_word(N, mod->d[0]))
|
||||
goto err;
|
||||
#if BN_BITS2 == 32
|
||||
if (mod->top > 1) {
|
||||
N->d[1] = mod->d[1];
|
||||
N->top += bn_ct_ne_zero(N->d[1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Rinv = R^-1 mod N */
|
||||
if ((BN_mod_inverse_ct(Rinv, R, N, ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Ninv = (R * Rinv - 1) / N */
|
||||
if (!BN_lshift(Ninv, Rinv, 64))
|
||||
goto err;
|
||||
if (BN_is_zero(Ninv)) {
|
||||
/* R * Rinv == 0, set to R so that R * Rinv - 1 is mod R. */
|
||||
if (!BN_set_bit(Ninv, 64))
|
||||
goto err;
|
||||
}
|
||||
if (!BN_sub_word(Ninv, 1))
|
||||
goto err;
|
||||
if (!BN_div_ct(Ninv, NULL, Ninv, N, ctx))
|
||||
goto err;
|
||||
|
||||
/* Store least significant word(s) of Ninv. */
|
||||
mont->n0[0] = mont->n0[1] = 0;
|
||||
if (Ninv->top > 0)
|
||||
mont->n0[0] = Ninv->d[0];
|
||||
#if BN_BITS2 == 32
|
||||
/* Some BN_BITS2 == 32 platforms (namely parisc) use two words of Ninv. */
|
||||
if (Ninv->top > 1)
|
||||
mont->n0[1] = Ninv->d[1];
|
||||
#endif
|
||||
|
||||
/* Compute RR = R * R mod N, for use when converting to Montgomery form. */
|
||||
BN_zero(&mont->RR);
|
||||
if (!BN_set_bit(&mont->RR, mont->ri * 2))
|
||||
goto err;
|
||||
if (!BN_mod_ct(&mont->RR, &mont->RR, &mont->N, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BN_MONT_CTX *
|
||||
BN_MONT_CTX_set_locked(BN_MONT_CTX **pmctx, int lock, const BIGNUM *mod,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BN_MONT_CTX *mctx = NULL;
|
||||
|
||||
CRYPTO_r_lock(lock);
|
||||
mctx = *pmctx;
|
||||
CRYPTO_r_unlock(lock);
|
||||
|
||||
if (mctx != NULL)
|
||||
goto done;
|
||||
|
||||
if ((mctx = BN_MONT_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!BN_MONT_CTX_set(mctx, mod, ctx))
|
||||
goto err;
|
||||
|
||||
CRYPTO_w_lock(lock);
|
||||
if (*pmctx != NULL) {
|
||||
/* Someone else raced us... */
|
||||
BN_MONT_CTX_free(mctx);
|
||||
mctx = *pmctx;
|
||||
} else {
|
||||
*pmctx = mctx;
|
||||
}
|
||||
CRYPTO_w_unlock(lock);
|
||||
|
||||
goto done;
|
||||
err:
|
||||
BN_MONT_CTX_free(mctx);
|
||||
mctx = NULL;
|
||||
done:
|
||||
return mctx;
|
||||
}
|
||||
|
||||
static int bn_montgomery_reduce(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mctx);
|
||||
|
||||
static int
|
||||
bn_mod_mul_montgomery_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mctx, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *tmp;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((tmp = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (a == b) {
|
||||
if (!BN_sqr(tmp, a, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mul(tmp, a, b, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Reduce from aRR to aR. */
|
||||
if (!bn_montgomery_reduce(r, tmp, mctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* bn_montgomery_multiply_words() computes r = aR * bR * R^-1 = abR for the
|
||||
* given word arrays. The caller must ensure that rp, ap, bp and np are all
|
||||
* n_len words in length, while tp must be n_len * 2 + 2 words in length.
|
||||
*/
|
||||
void
|
||||
bn_montgomery_multiply_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
const BN_ULONG *np, BN_ULONG *tp, BN_ULONG n0, int n_len)
|
||||
{
|
||||
BN_ULONG a0, b, carry_a, carry_n, carry, mask, w, x;
|
||||
int i, j;
|
||||
|
||||
carry_a = carry_n = carry = 0;
|
||||
|
||||
for (i = 0; i < n_len; i++)
|
||||
tp[i] = 0;
|
||||
|
||||
a0 = ap[0];
|
||||
|
||||
for (i = 0; i < n_len; i++) {
|
||||
b = bp[i];
|
||||
|
||||
/* Compute new t[0] * n0, as we need it inside the loop. */
|
||||
w = (a0 * b + tp[0]) * n0;
|
||||
|
||||
for (j = 0; j < n_len; j++) {
|
||||
bn_mulw_addw_addw(ap[j], b, tp[j], carry_a, &carry_a, &x);
|
||||
bn_mulw_addw_addw(np[j], w, x, carry_n, &carry_n, &tp[j]);
|
||||
}
|
||||
bn_addw_addw(carry_a, carry_n, carry, &carry, &tp[n_len]);
|
||||
carry_a = carry_n = 0;
|
||||
|
||||
tp++;
|
||||
}
|
||||
tp[n_len] = carry;
|
||||
|
||||
/*
|
||||
* The output is now in the range of [0, 2N). Attempt to reduce once by
|
||||
* subtracting the modulus. If the reduction was necessary then the
|
||||
* result is already in r, otherwise copy the value prior to reduction
|
||||
* from tp.
|
||||
*/
|
||||
mask = bn_ct_ne_zero(tp[n_len]) - bn_sub_words(rp, tp, np, n_len);
|
||||
|
||||
for (i = 0; i < n_len; i++) {
|
||||
*rp = (*rp & ~mask) | (*tp & mask);
|
||||
rp++;
|
||||
tp++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bn_montgomery_multiply() computes r = aR * bR * R^-1 = abR for the given
|
||||
* BIGNUMs. The caller must ensure that the modulus is two or more words in
|
||||
* length and that a and b have the same number of words as the modulus.
|
||||
*/
|
||||
int
|
||||
bn_montgomery_multiply(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mctx, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *t;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if (mctx->N.top <= 1 || a->top != mctx->N.top || b->top != mctx->N.top)
|
||||
goto err;
|
||||
if (!bn_wexpand(r, mctx->N.top))
|
||||
goto err;
|
||||
|
||||
if ((t = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if (!bn_wexpand(t, mctx->N.top * 2 + 2))
|
||||
goto err;
|
||||
|
||||
bn_montgomery_multiply_words(r->d, a->d, b->d, mctx->N.d, t->d,
|
||||
mctx->n0[0], mctx->N.top);
|
||||
|
||||
r->top = mctx->N.top;
|
||||
bn_correct_top(r);
|
||||
|
||||
BN_set_negative(r, a->neg ^ b->neg);
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_BN_ASM_MONT
|
||||
int
|
||||
bn_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mctx, BN_CTX *ctx)
|
||||
{
|
||||
if (mctx->N.top <= 1 || a->top != mctx->N.top || b->top != mctx->N.top)
|
||||
return bn_mod_mul_montgomery_simple(r, a, b, mctx, ctx);
|
||||
|
||||
return bn_montgomery_multiply(r, a, b, mctx, ctx);
|
||||
}
|
||||
#else
|
||||
|
||||
int
|
||||
bn_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mctx, BN_CTX *ctx)
|
||||
{
|
||||
if (mctx->N.top <= 1 || a->top != mctx->N.top || b->top != mctx->N.top)
|
||||
return bn_mod_mul_montgomery_simple(r, a, b, mctx, ctx);
|
||||
|
||||
/*
|
||||
* Legacy bn_mul_mont() performs stack based allocation, without
|
||||
* size limitation. Allowing a large size results in the stack
|
||||
* being blown.
|
||||
*/
|
||||
if (mctx->N.top > (8 * 1024 / sizeof(BN_ULONG)))
|
||||
return bn_montgomery_multiply(r, a, b, mctx, ctx);
|
||||
|
||||
if (!bn_wexpand(r, mctx->N.top))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Legacy bn_mul_mont() can indicate that we should "fallback" to
|
||||
* another implementation.
|
||||
*/
|
||||
if (!bn_mul_mont(r->d, a->d, b->d, mctx->N.d, mctx->n0, mctx->N.top))
|
||||
return bn_montgomery_multiply(r, a, b, mctx, ctx);
|
||||
|
||||
r->top = mctx->N.top;
|
||||
bn_correct_top(r);
|
||||
|
||||
BN_set_negative(r, a->neg ^ b->neg);
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mctx, BN_CTX *ctx)
|
||||
{
|
||||
/* Compute r = aR * bR * R^-1 mod N = abR mod N */
|
||||
return bn_mod_mul_montgomery(r, a, b, mctx, ctx);
|
||||
}
|
||||
|
||||
int
|
||||
BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mctx, BN_CTX *ctx)
|
||||
{
|
||||
/* Compute r = a * R * R * R^-1 mod N = aR mod N */
|
||||
return bn_mod_mul_montgomery(r, a, &mctx->RR, mctx, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* bn_montgomery_reduce() performs Montgomery reduction, reducing the input
|
||||
* from its Montgomery form aR to a, returning the result in r. Note that the
|
||||
* input is mutated in the process of performing the reduction, destroying its
|
||||
* original value.
|
||||
*/
|
||||
static int
|
||||
bn_montgomery_reduce(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mctx)
|
||||
{
|
||||
BIGNUM *n;
|
||||
BN_ULONG *ap, *rp, n0, v, carry, mask;
|
||||
int i, max, n_len;
|
||||
|
||||
n = &mctx->N;
|
||||
n_len = mctx->N.top;
|
||||
|
||||
if (n_len == 0) {
|
||||
BN_zero(r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bn_wexpand(r, n_len))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Expand a to twice the length of the modulus, zero if necessary.
|
||||
* XXX - make this a requirement of the caller.
|
||||
*/
|
||||
if ((max = 2 * n_len) < n_len)
|
||||
return 0;
|
||||
if (!bn_wexpand(a, max))
|
||||
return 0;
|
||||
for (i = a->top; i < max; i++)
|
||||
a->d[i] = 0;
|
||||
|
||||
carry = 0;
|
||||
n0 = mctx->n0[0];
|
||||
|
||||
/* Add multiples of the modulus, so that it becomes divisible by R. */
|
||||
for (i = 0; i < n_len; i++) {
|
||||
v = bn_mul_add_words(&a->d[i], n->d, n_len, a->d[i] * n0);
|
||||
bn_addw_addw(v, a->d[i + n_len], carry, &carry,
|
||||
&a->d[i + n_len]);
|
||||
}
|
||||
|
||||
/* Divide by R (this is the equivalent of right shifting by n_len). */
|
||||
ap = &a->d[n_len];
|
||||
|
||||
/*
|
||||
* The output is now in the range of [0, 2N). Attempt to reduce once by
|
||||
* subtracting the modulus. If the reduction was necessary then the
|
||||
* result is already in r, otherwise copy the value prior to reduction
|
||||
* from the top half of a.
|
||||
*/
|
||||
mask = carry - bn_sub_words(r->d, ap, n->d, n_len);
|
||||
|
||||
rp = r->d;
|
||||
for (i = 0; i < n_len; i++) {
|
||||
*rp = (*rp & ~mask) | (*ap & mask);
|
||||
rp++;
|
||||
ap++;
|
||||
}
|
||||
r->top = n_len;
|
||||
|
||||
bn_correct_top(r);
|
||||
|
||||
BN_set_negative(r, a->neg ^ n->neg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_from_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mctx, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *tmp;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((tmp = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if (!bn_copy(tmp, a))
|
||||
goto err;
|
||||
if (!bn_montgomery_reduce(r, tmp, mctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
376
externals/libressl/crypto/bn/bn_mul.c
vendored
Normal file
376
externals/libressl/crypto/bn/bn_mul.c
vendored
Normal file
@@ -0,0 +1,376 @@
|
||||
/* $OpenBSD: bn_mul.c,v 1.37 2023/04/19 10:51:22 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include "bn_arch.h"
|
||||
#include "bn_internal.h"
|
||||
#include "bn_local.h"
|
||||
|
||||
/*
|
||||
* bn_mul_comba4() computes r[] = a[] * b[] using Comba multiplication
|
||||
* (https://everything2.com/title/Comba+multiplication), where a and b are both
|
||||
* four word arrays, producing an eight word array result.
|
||||
*/
|
||||
#ifndef HAVE_BN_MUL_COMBA4
|
||||
void
|
||||
bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
|
||||
{
|
||||
BN_ULONG c0, c1, c2;
|
||||
|
||||
bn_mulw_addtw(a[0], b[0], 0, 0, 0, &c2, &c1, &r[0]);
|
||||
|
||||
bn_mulw_addtw(a[0], b[1], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[0], c2, c1, c0, &c2, &c1, &r[1]);
|
||||
|
||||
bn_mulw_addtw(a[2], b[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[0], b[2], c2, c1, c0, &c2, &c1, &r[2]);
|
||||
|
||||
bn_mulw_addtw(a[0], b[3], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[0], c2, c1, c0, &c2, &c1, &r[3]);
|
||||
|
||||
bn_mulw_addtw(a[3], b[1], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[3], c2, c1, c0, &c2, &c1, &r[4]);
|
||||
|
||||
bn_mulw_addtw(a[2], b[3], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[2], c2, c1, c0, &c2, &c1, &r[5]);
|
||||
|
||||
bn_mulw_addtw(a[3], b[3], 0, c2, c1, &c2, &r[7], &r[6]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mul_comba8() computes r[] = a[] * b[] using Comba multiplication
|
||||
* (https://everything2.com/title/Comba+multiplication), where a and b are both
|
||||
* eight word arrays, producing a 16 word array result.
|
||||
*/
|
||||
#ifndef HAVE_BN_MUL_COMBA8
|
||||
void
|
||||
bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
|
||||
{
|
||||
BN_ULONG c0, c1, c2;
|
||||
|
||||
bn_mulw_addtw(a[0], b[0], 0, 0, 0, &c2, &c1, &r[0]);
|
||||
|
||||
bn_mulw_addtw(a[0], b[1], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[0], c2, c1, c0, &c2, &c1, &r[1]);
|
||||
|
||||
bn_mulw_addtw(a[2], b[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[0], b[2], c2, c1, c0, &c2, &c1, &r[2]);
|
||||
|
||||
bn_mulw_addtw(a[0], b[3], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[0], c2, c1, c0, &c2, &c1, &r[3]);
|
||||
|
||||
bn_mulw_addtw(a[4], b[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[0], b[4], c2, c1, c0, &c2, &c1, &r[4]);
|
||||
|
||||
bn_mulw_addtw(a[0], b[5], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[4], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[4], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[0], c2, c1, c0, &c2, &c1, &r[5]);
|
||||
|
||||
bn_mulw_addtw(a[6], b[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[4], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[4], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[5], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[0], b[6], c2, c1, c0, &c2, &c1, &r[6]);
|
||||
|
||||
bn_mulw_addtw(a[0], b[7], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[6], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[5], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[4], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[4], b[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[6], b[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[7], b[0], c2, c1, c0, &c2, &c1, &r[7]);
|
||||
|
||||
bn_mulw_addtw(a[7], b[1], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[6], b[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[4], b[4], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[5], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[2], b[6], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[1], b[7], c2, c1, c0, &c2, &c1, &r[8]);
|
||||
|
||||
bn_mulw_addtw(a[2], b[7], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[6], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[4], b[5], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[4], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[6], b[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[7], b[2], c2, c1, c0, &c2, &c1, &r[9]);
|
||||
|
||||
bn_mulw_addtw(a[7], b[3], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[6], b[4], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[5], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[4], b[6], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[3], b[7], c2, c1, c0, &c2, &c1, &r[10]);
|
||||
|
||||
bn_mulw_addtw(a[4], b[7], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[6], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[6], b[5], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[7], b[4], c2, c1, c0, &c2, &c1, &r[11]);
|
||||
|
||||
bn_mulw_addtw(a[7], b[5], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[6], b[6], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[5], b[7], c2, c1, c0, &c2, &c1, &r[12]);
|
||||
|
||||
bn_mulw_addtw(a[6], b[7], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mulw_addtw(a[7], b[6], c2, c1, c0, &c2, &c1, &r[13]);
|
||||
|
||||
bn_mulw_addtw(a[7], b[7], 0, c2, c1, &c2, &r[15], &r[14]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mul_words() computes (carry:r[i]) = a[i] * w + carry, where a is an array
|
||||
* of words and w is a single word. This should really be called bn_mulw_words()
|
||||
* since only one input is an array. This is used as a step in the multiplication
|
||||
* of word arrays.
|
||||
*/
|
||||
#ifndef HAVE_BN_MUL_WORDS
|
||||
BN_ULONG
|
||||
bn_mul_words(BN_ULONG *r, const BN_ULONG *a, int num, BN_ULONG w)
|
||||
{
|
||||
BN_ULONG carry = 0;
|
||||
|
||||
assert(num >= 0);
|
||||
if (num <= 0)
|
||||
return 0;
|
||||
|
||||
#ifndef OPENSSL_SMALL_FOOTPRINT
|
||||
while (num & ~3) {
|
||||
bn_mulw_addw(a[0], w, carry, &carry, &r[0]);
|
||||
bn_mulw_addw(a[1], w, carry, &carry, &r[1]);
|
||||
bn_mulw_addw(a[2], w, carry, &carry, &r[2]);
|
||||
bn_mulw_addw(a[3], w, carry, &carry, &r[3]);
|
||||
a += 4;
|
||||
r += 4;
|
||||
num -= 4;
|
||||
}
|
||||
#endif
|
||||
while (num) {
|
||||
bn_mulw_addw(a[0], w, carry, &carry, &r[0]);
|
||||
a++;
|
||||
r++;
|
||||
num--;
|
||||
}
|
||||
return carry;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_mul_add_words() computes (carry:r[i]) = a[i] * w + r[i] + carry, where
|
||||
* a is an array of words and w is a single word. This should really be called
|
||||
* bn_mulw_add_words() since only one input is an array. This is used as a step
|
||||
* in the multiplication of word arrays.
|
||||
*/
|
||||
#ifndef HAVE_BN_MUL_ADD_WORDS
|
||||
BN_ULONG
|
||||
bn_mul_add_words(BN_ULONG *r, const BN_ULONG *a, int num, BN_ULONG w)
|
||||
{
|
||||
BN_ULONG carry = 0;
|
||||
|
||||
assert(num >= 0);
|
||||
if (num <= 0)
|
||||
return 0;
|
||||
|
||||
#ifndef OPENSSL_SMALL_FOOTPRINT
|
||||
while (num & ~3) {
|
||||
bn_mulw_addw_addw(a[0], w, r[0], carry, &carry, &r[0]);
|
||||
bn_mulw_addw_addw(a[1], w, r[1], carry, &carry, &r[1]);
|
||||
bn_mulw_addw_addw(a[2], w, r[2], carry, &carry, &r[2]);
|
||||
bn_mulw_addw_addw(a[3], w, r[3], carry, &carry, &r[3]);
|
||||
a += 4;
|
||||
r += 4;
|
||||
num -= 4;
|
||||
}
|
||||
#endif
|
||||
while (num) {
|
||||
bn_mulw_addw_addw(a[0], w, r[0], carry, &carry, &r[0]);
|
||||
a++;
|
||||
r++;
|
||||
num--;
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
|
||||
{
|
||||
BN_ULONG *rr;
|
||||
|
||||
|
||||
if (na < nb) {
|
||||
int itmp;
|
||||
BN_ULONG *ltmp;
|
||||
|
||||
itmp = na;
|
||||
na = nb;
|
||||
nb = itmp;
|
||||
ltmp = a;
|
||||
a = b;
|
||||
b = ltmp;
|
||||
|
||||
}
|
||||
rr = &(r[na]);
|
||||
if (nb <= 0) {
|
||||
(void)bn_mul_words(r, a, na, 0);
|
||||
return;
|
||||
} else
|
||||
rr[0] = bn_mul_words(r, a, na, b[0]);
|
||||
|
||||
for (;;) {
|
||||
if (--nb <= 0)
|
||||
return;
|
||||
rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
|
||||
if (--nb <= 0)
|
||||
return;
|
||||
rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
|
||||
if (--nb <= 0)
|
||||
return;
|
||||
rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
|
||||
if (--nb <= 0)
|
||||
return;
|
||||
rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
|
||||
rr += 4;
|
||||
r += 4;
|
||||
b += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_BN_MUL
|
||||
int
|
||||
bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int rn, BN_CTX *ctx)
|
||||
{
|
||||
bn_mul_normal(r->d, a->d, a->top, b->d, b->top);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_BN_MUL */
|
||||
|
||||
int
|
||||
BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *rr;
|
||||
int rn;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if (BN_is_zero(a) || BN_is_zero(b)) {
|
||||
BN_zero(r);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rr = r;
|
||||
if (rr == a || rr == b)
|
||||
rr = BN_CTX_get(ctx);
|
||||
if (rr == NULL)
|
||||
goto err;
|
||||
|
||||
rn = a->top + b->top;
|
||||
if (rn < a->top)
|
||||
goto err;
|
||||
if (!bn_wexpand(rr, rn))
|
||||
goto err;
|
||||
|
||||
if (a->top == 4 && b->top == 4) {
|
||||
bn_mul_comba4(rr->d, a->d, b->d);
|
||||
} else if (a->top == 8 && b->top == 8) {
|
||||
bn_mul_comba8(rr->d, a->d, b->d);
|
||||
} else {
|
||||
if (!bn_mul(rr, a, b, rn, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
rr->top = rn;
|
||||
bn_correct_top(rr);
|
||||
|
||||
BN_set_negative(rr, a->neg ^ b->neg);
|
||||
|
||||
if (!bn_copy(r, rr))
|
||||
goto err;
|
||||
done:
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
408
externals/libressl/crypto/bn/bn_prime.c
vendored
Normal file
408
externals/libressl/crypto/bn/bn_prime.c
vendored
Normal file
@@ -0,0 +1,408 @@
|
||||
/* $OpenBSD: bn_prime.c,v 1.32 2023/05/10 12:21:55 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
/* The quick sieve algorithm approach to weeding out primes is
|
||||
* Philip Zimmermann's, as implemented in PGP. I have had a read of
|
||||
* his comments and implemented my own version.
|
||||
*/
|
||||
#include "bn_prime.h"
|
||||
|
||||
static int probable_prime(BIGNUM *rnd, int bits);
|
||||
static int probable_prime_dh(BIGNUM *rnd, int bits,
|
||||
const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
|
||||
static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
|
||||
const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
|
||||
|
||||
int
|
||||
BN_GENCB_call(BN_GENCB *cb, int a, int b)
|
||||
{
|
||||
/* No callback means continue */
|
||||
if (!cb)
|
||||
return 1;
|
||||
switch (cb->ver) {
|
||||
case 1:
|
||||
/* Deprecated-style callbacks */
|
||||
if (!cb->cb.cb_1)
|
||||
return 1;
|
||||
cb->cb.cb_1(a, b, cb->arg);
|
||||
return 1;
|
||||
case 2:
|
||||
/* New-style callbacks */
|
||||
return cb->cb.cb_2(a, b, cb);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Unrecognised callback type */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
|
||||
const BIGNUM *rem, BN_GENCB *cb)
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
BIGNUM *p;
|
||||
int is_prime;
|
||||
int loops = 0;
|
||||
int found = 0;
|
||||
|
||||
if (bits < 2 || (bits == 2 && safe)) {
|
||||
/*
|
||||
* There are no prime numbers smaller than 2, and the smallest
|
||||
* safe prime (7) spans three bits.
|
||||
*/
|
||||
BNerror(BN_R_BITS_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
BN_CTX_start(ctx);
|
||||
if ((p = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
loop:
|
||||
/* Make a random number and set the top and bottom bits. */
|
||||
if (add == NULL) {
|
||||
if (!probable_prime(ret, bits))
|
||||
goto err;
|
||||
} else {
|
||||
if (safe) {
|
||||
if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!probable_prime_dh(ret, bits, add, rem, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!BN_GENCB_call(cb, 0, loops++))
|
||||
goto err;
|
||||
|
||||
if (!safe) {
|
||||
if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1))
|
||||
goto err;
|
||||
if (!is_prime)
|
||||
goto loop;
|
||||
} else {
|
||||
if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1))
|
||||
goto err;
|
||||
if (!is_prime)
|
||||
goto loop;
|
||||
|
||||
/*
|
||||
* For safe prime generation, check that p = (ret-1)/2 is prime.
|
||||
* Since this prime has >= 3 bits, it is odd, and we can simply
|
||||
* divide by 2.
|
||||
*/
|
||||
if (!BN_rshift1(p, ret))
|
||||
goto err;
|
||||
|
||||
if (!bn_is_prime_bpsw(&is_prime, p, ctx, 1))
|
||||
goto err;
|
||||
if (!is_prime)
|
||||
goto loop;
|
||||
|
||||
if (!BN_GENCB_call(cb, 2, loops - 1))
|
||||
goto err;
|
||||
}
|
||||
|
||||
found = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
|
||||
{
|
||||
return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
|
||||
}
|
||||
|
||||
int
|
||||
BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
|
||||
int do_trial_division, BN_GENCB *cb)
|
||||
{
|
||||
int is_prime;
|
||||
|
||||
if (checks < 0)
|
||||
return -1;
|
||||
|
||||
if (checks == BN_prime_checks)
|
||||
checks = BN_prime_checks_for_size(BN_num_bits(a));
|
||||
|
||||
/* XXX - tickle BN_GENCB in bn_is_prime_bpsw(). */
|
||||
if (!bn_is_prime_bpsw(&is_prime, a, ctx_passed, checks))
|
||||
return -1;
|
||||
|
||||
return is_prime;
|
||||
}
|
||||
|
||||
static int
|
||||
probable_prime(BIGNUM *rnd, int bits)
|
||||
{
|
||||
int i;
|
||||
BN_ULONG mods[NUMPRIMES];
|
||||
BN_ULONG delta, maxdelta;
|
||||
|
||||
again:
|
||||
if (!BN_rand(rnd, bits, 1, 1))
|
||||
return (0);
|
||||
/* we now have a random number 'rand' to test. */
|
||||
for (i = 1; i < NUMPRIMES; i++) {
|
||||
BN_ULONG mod = BN_mod_word(rnd, primes[i]);
|
||||
if (mod == (BN_ULONG)-1)
|
||||
return (0);
|
||||
mods[i] = mod;
|
||||
}
|
||||
maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
|
||||
delta = 0;
|
||||
loop:
|
||||
for (i = 1; i < NUMPRIMES; i++) {
|
||||
/* check that rnd is not a prime and also
|
||||
* that gcd(rnd-1,primes) == 1 (except for 2) */
|
||||
if (((mods[i] + delta) % primes[i]) <= 1) {
|
||||
delta += 2;
|
||||
if (delta > maxdelta)
|
||||
goto again;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
if (!BN_add_word(rnd, delta))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int i, ret = 0;
|
||||
BIGNUM *t1;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((t1 = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_rand(rnd, bits, 0, 1))
|
||||
goto err;
|
||||
|
||||
/* we need ((rnd-rem) % add) == 0 */
|
||||
|
||||
if (!BN_mod_ct(t1, rnd, add, ctx))
|
||||
goto err;
|
||||
if (!BN_sub(rnd, rnd, t1))
|
||||
goto err;
|
||||
if (rem == NULL) {
|
||||
if (!BN_add_word(rnd, 1))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_add(rnd, rnd, rem))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* we now have a random number 'rand' to test. */
|
||||
|
||||
loop:
|
||||
for (i = 1; i < NUMPRIMES; i++) {
|
||||
/* check that rnd is a prime */
|
||||
BN_LONG mod = BN_mod_word(rnd, primes[i]);
|
||||
if (mod == (BN_ULONG)-1)
|
||||
goto err;
|
||||
if (mod <= 1) {
|
||||
if (!BN_add(rnd, rnd, add))
|
||||
goto err;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
|
||||
const BIGNUM *rem, BN_CTX *ctx)
|
||||
{
|
||||
int i, ret = 0;
|
||||
BIGNUM *t1, *qadd, *q;
|
||||
|
||||
bits--;
|
||||
BN_CTX_start(ctx);
|
||||
if ((t1 = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((q = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((qadd = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_rshift1(qadd, padd))
|
||||
goto err;
|
||||
|
||||
if (!BN_rand(q, bits, 0, 1))
|
||||
goto err;
|
||||
|
||||
/* we need ((rnd-rem) % add) == 0 */
|
||||
if (!BN_mod_ct(t1, q,qadd, ctx))
|
||||
goto err;
|
||||
if (!BN_sub(q, q, t1))
|
||||
goto err;
|
||||
if (rem == NULL) {
|
||||
if (!BN_add_word(q, 1))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_rshift1(t1, rem))
|
||||
goto err;
|
||||
if (!BN_add(q, q, t1))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* we now have a random number 'rand' to test. */
|
||||
if (!BN_lshift1(p, q))
|
||||
goto err;
|
||||
if (!BN_add_word(p, 1))
|
||||
goto err;
|
||||
|
||||
loop:
|
||||
for (i = 1; i < NUMPRIMES; i++) {
|
||||
/* check that p and q are prime */
|
||||
/* check that for p and q
|
||||
* gcd(p-1,primes) == 1 (except for 2) */
|
||||
BN_ULONG pmod = BN_mod_word(p, primes[i]);
|
||||
BN_ULONG qmod = BN_mod_word(q, primes[i]);
|
||||
if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1)
|
||||
goto err;
|
||||
if (pmod == 0 || qmod == 0) {
|
||||
if (!BN_add(p, p, padd))
|
||||
goto err;
|
||||
if (!BN_add(q, q, qadd))
|
||||
goto err;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
14
externals/libressl/crypto/bn/bn_prime.h
vendored
Normal file
14
externals/libressl/crypto/bn/bn_prime.h
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/* $OpenBSD: bn_prime.h,v 1.9 2022/11/10 10:24:50 tb Exp $ */
|
||||
/*
|
||||
* Public domain.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
#define NUMPRIMES 2048
|
||||
|
||||
extern const uint16_t primes[NUMPRIMES];
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
314
externals/libressl/crypto/bn/bn_rand.c
vendored
Normal file
314
externals/libressl/crypto/bn/bn_rand.c
vendored
Normal file
@@ -0,0 +1,314 @@
|
||||
/* $OpenBSD: bn_rand.c,v 1.27 2022/11/26 16:08:51 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
static int
|
||||
bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
|
||||
{
|
||||
unsigned char *buf = NULL;
|
||||
int ret = 0, bit, bytes, mask;
|
||||
|
||||
if (rnd == NULL) {
|
||||
BNerror(ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (bits < 0 || (bits == 1 && top > 0)) {
|
||||
BNerror(BN_R_BITS_TOO_SMALL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (bits == 0) {
|
||||
BN_zero(rnd);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bytes = (bits + 7) / 8;
|
||||
bit = (bits - 1) % 8;
|
||||
mask = 0xff << (bit + 1);
|
||||
|
||||
buf = malloc(bytes);
|
||||
if (buf == NULL) {
|
||||
BNerror(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* make a random number and set the top and bottom bits */
|
||||
arc4random_buf(buf, bytes);
|
||||
|
||||
#if 1
|
||||
if (pseudorand == 2) {
|
||||
/* generate patterns that are more likely to trigger BN
|
||||
library bugs */
|
||||
int i;
|
||||
unsigned char c;
|
||||
|
||||
for (i = 0; i < bytes; i++) {
|
||||
arc4random_buf(&c, 1);
|
||||
if (c >= 128 && i > 0)
|
||||
buf[i] = buf[i - 1];
|
||||
else if (c < 42)
|
||||
buf[i] = 0;
|
||||
else if (c < 84)
|
||||
buf[i] = 255;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (top > 0) {
|
||||
if (bit == 0) {
|
||||
buf[0] = 1;
|
||||
buf[1] |= 0x80;
|
||||
} else {
|
||||
buf[0] |= (3 << (bit - 1));
|
||||
}
|
||||
}
|
||||
if (top == 0)
|
||||
buf[0] |= (1 << bit);
|
||||
buf[0] &= ~mask;
|
||||
if (bottom) /* set bottom bit if requested */
|
||||
buf[bytes - 1] |= 1;
|
||||
if (BN_bin2bn(buf, bytes, rnd) == NULL)
|
||||
goto err;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(buf, bytes);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
|
||||
{
|
||||
return bnrand(0, rnd, bits, top, bottom);
|
||||
}
|
||||
|
||||
int
|
||||
BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
|
||||
{
|
||||
return bnrand(1, rnd, bits, top, bottom);
|
||||
}
|
||||
|
||||
#if 1
|
||||
int
|
||||
BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
|
||||
{
|
||||
return bnrand(2, rnd, bits, top, bottom);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* random number r: 0 <= r < range */
|
||||
static int
|
||||
bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
|
||||
{
|
||||
int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
|
||||
int n;
|
||||
int count = 100;
|
||||
|
||||
if (range->neg || BN_is_zero(range)) {
|
||||
BNerror(BN_R_INVALID_RANGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = BN_num_bits(range); /* n > 0 */
|
||||
|
||||
/* BN_is_bit_set(range, n - 1) always holds */
|
||||
|
||||
if (n == 1)
|
||||
BN_zero(r);
|
||||
else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
|
||||
/* range = 100..._2,
|
||||
* so 3*range (= 11..._2) is exactly one bit longer than range */
|
||||
do {
|
||||
if (!bn_rand(r, n + 1, -1, 0))
|
||||
return 0;
|
||||
/* If r < 3*range, use r := r MOD range
|
||||
* (which is either r, r - range, or r - 2*range).
|
||||
* Otherwise, iterate once more.
|
||||
* Since 3*range = 11..._2, each iteration succeeds with
|
||||
* probability >= .75. */
|
||||
if (BN_cmp(r, range) >= 0) {
|
||||
if (!BN_sub(r, r, range))
|
||||
return 0;
|
||||
if (BN_cmp(r, range) >= 0)
|
||||
if (!BN_sub(r, r, range))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!--count) {
|
||||
BNerror(BN_R_TOO_MANY_ITERATIONS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} while (BN_cmp(r, range) >= 0);
|
||||
} else {
|
||||
do {
|
||||
/* range = 11..._2 or range = 101..._2 */
|
||||
if (!bn_rand(r, n, -1, 0))
|
||||
return 0;
|
||||
|
||||
if (!--count) {
|
||||
BNerror(BN_R_TOO_MANY_ITERATIONS);
|
||||
return 0;
|
||||
}
|
||||
} while (BN_cmp(r, range) >= 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_rand_range(BIGNUM *r, const BIGNUM *range)
|
||||
{
|
||||
return bn_rand_range(0, r, range);
|
||||
}
|
||||
|
||||
int
|
||||
bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc)
|
||||
{
|
||||
BIGNUM *len = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (BN_cmp(lower_inc, upper_exc) >= 0)
|
||||
goto err;
|
||||
|
||||
if ((len = BN_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_sub(len, upper_exc, lower_inc))
|
||||
goto err;
|
||||
|
||||
if (!bn_rand_range(0, rnd, len))
|
||||
goto err;
|
||||
|
||||
if (!BN_add(rnd, rnd, lower_inc))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_free(len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
|
||||
{
|
||||
return bn_rand_range(1, r, range);
|
||||
}
|
||||
260
externals/libressl/crypto/bn/bn_recp.c
vendored
Normal file
260
externals/libressl/crypto/bn/bn_recp.c
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
/* $OpenBSD: bn_recp.c,v 1.19 2023/03/27 10:25:02 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
void
|
||||
BN_RECP_CTX_init(BN_RECP_CTX *recp)
|
||||
{
|
||||
BN_init(&(recp->N));
|
||||
BN_init(&(recp->Nr));
|
||||
recp->num_bits = 0;
|
||||
recp->flags = 0;
|
||||
}
|
||||
|
||||
BN_RECP_CTX *
|
||||
BN_RECP_CTX_new(void)
|
||||
{
|
||||
BN_RECP_CTX *ret;
|
||||
|
||||
if ((ret = malloc(sizeof(BN_RECP_CTX))) == NULL)
|
||||
return (NULL);
|
||||
|
||||
BN_RECP_CTX_init(ret);
|
||||
ret->flags = BN_FLG_MALLOCED;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
BN_RECP_CTX_free(BN_RECP_CTX *recp)
|
||||
{
|
||||
if (recp == NULL)
|
||||
return;
|
||||
|
||||
BN_free(&(recp->N));
|
||||
BN_free(&(recp->Nr));
|
||||
if (recp->flags & BN_FLG_MALLOCED)
|
||||
free(recp);
|
||||
}
|
||||
|
||||
int
|
||||
BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
|
||||
{
|
||||
if (!bn_copy(&(recp->N), d))
|
||||
return 0;
|
||||
BN_zero(&(recp->Nr));
|
||||
recp->num_bits = BN_num_bits(d);
|
||||
recp->shift = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
|
||||
BN_RECP_CTX *recp, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *a;
|
||||
const BIGNUM *ca;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((a = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
if (y != NULL) {
|
||||
if (x == y) {
|
||||
if (!BN_sqr(a, x, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mul(a, x, y, ctx))
|
||||
goto err;
|
||||
}
|
||||
ca = a;
|
||||
} else
|
||||
ca = x; /* Just do the mod */
|
||||
|
||||
ret = BN_div_recp(NULL, r, ca, recp, ctx);
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int i, j, ret = 0;
|
||||
BIGNUM *a, *b, *d, *r;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
a = BN_CTX_get(ctx);
|
||||
b = BN_CTX_get(ctx);
|
||||
if (dv != NULL)
|
||||
d = dv;
|
||||
else
|
||||
d = BN_CTX_get(ctx);
|
||||
if (rem != NULL)
|
||||
r = rem;
|
||||
else
|
||||
r = BN_CTX_get(ctx);
|
||||
if (a == NULL || b == NULL || d == NULL || r == NULL)
|
||||
goto err;
|
||||
|
||||
if (BN_ucmp(m, &(recp->N)) < 0) {
|
||||
BN_zero(d);
|
||||
if (!bn_copy(r, m)) {
|
||||
BN_CTX_end(ctx);
|
||||
return 0;
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* We want the remainder
|
||||
* Given input of ABCDEF / ab
|
||||
* we need multiply ABCDEF by 3 digests of the reciprocal of ab
|
||||
*
|
||||
*/
|
||||
|
||||
/* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
|
||||
i = BN_num_bits(m);
|
||||
j = recp->num_bits << 1;
|
||||
if (j > i)
|
||||
i = j;
|
||||
|
||||
/* Nr := round(2^i / N) */
|
||||
if (i != recp->shift)
|
||||
recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx);
|
||||
|
||||
/* BN_reciprocal returns i, or -1 for an error */
|
||||
if (recp->shift == -1)
|
||||
goto err;
|
||||
|
||||
/* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
|
||||
* = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
|
||||
* <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
|
||||
* = |m/N|
|
||||
*/
|
||||
if (!BN_rshift(a, m, recp->num_bits))
|
||||
goto err;
|
||||
if (!BN_mul(b, a,&(recp->Nr), ctx))
|
||||
goto err;
|
||||
if (!BN_rshift(d, b, i - recp->num_bits))
|
||||
goto err;
|
||||
d->neg = 0;
|
||||
|
||||
if (!BN_mul(b, &(recp->N), d, ctx))
|
||||
goto err;
|
||||
if (!BN_usub(r, m, b))
|
||||
goto err;
|
||||
r->neg = 0;
|
||||
|
||||
#if 1
|
||||
j = 0;
|
||||
while (BN_ucmp(r, &(recp->N)) >= 0) {
|
||||
if (j++ > 2) {
|
||||
BNerror(BN_R_BAD_RECIPROCAL);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_usub(r, r, &(recp->N)))
|
||||
goto err;
|
||||
if (!BN_add_word(d, 1))
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
BN_set_negative(r, m->neg);
|
||||
BN_set_negative(d, m->neg ^ recp->N.neg);
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* len is the expected size of the result
|
||||
* We actually calculate with an extra word of precision, so
|
||||
* we can do faster division if the remainder is not required.
|
||||
*/
|
||||
/* r := 2^len / m */
|
||||
int
|
||||
BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
|
||||
{
|
||||
int ret = -1;
|
||||
BIGNUM *t;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((t = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_set_bit(t, len))
|
||||
goto err;
|
||||
|
||||
if (!BN_div_ct(r, NULL, t,m, ctx))
|
||||
goto err;
|
||||
|
||||
ret = len;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
}
|
||||
171
externals/libressl/crypto/bn/bn_shift.c
vendored
Normal file
171
externals/libressl/crypto/bn/bn_shift.c
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/* $OpenBSD: bn_shift.c,v 1.21 2023/02/13 04:25:37 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022, 2023 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
static inline int
|
||||
bn_lshift(BIGNUM *r, const BIGNUM *a, int n)
|
||||
{
|
||||
size_t count, shift_bits, shift_words;
|
||||
size_t lshift, rshift;
|
||||
ssize_t rstride;
|
||||
BN_ULONG *dst, *src;
|
||||
|
||||
if (n < 0) {
|
||||
BNerror(BN_R_INVALID_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
shift_bits = n;
|
||||
|
||||
/*
|
||||
* Left bit shift, potentially across word boundaries.
|
||||
*
|
||||
* When shift is not an exact multiple of BN_BITS2, the bottom bits of
|
||||
* the previous word need to be right shifted and combined with the left
|
||||
* shifted bits using bitwise OR. If shift is an exact multiple of
|
||||
* BN_BITS2, the source for the left and right shifts are the same
|
||||
* and the shifts become zero bits (which is effectively a memmove).
|
||||
*/
|
||||
shift_words = shift_bits / BN_BITS2;
|
||||
lshift = shift_bits % BN_BITS2;
|
||||
rshift = (BN_BITS2 - lshift) % BN_BITS2;
|
||||
rstride = 0 - (lshift + rshift) / BN_BITS2;
|
||||
|
||||
if (a->top < 1) {
|
||||
BN_zero(r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
count = a->top + shift_words + 1;
|
||||
|
||||
if (count < shift_words)
|
||||
return 0;
|
||||
|
||||
if (!bn_wexpand(r, count))
|
||||
return 0;
|
||||
|
||||
src = a->d + a->top - 1;
|
||||
dst = r->d + a->top + shift_words;
|
||||
|
||||
/* Handle right shift for top most word. */
|
||||
*dst = (*src >> rshift) & rstride;
|
||||
dst--;
|
||||
|
||||
/* Handle left shift and right shift for remaining words. */
|
||||
while (src > a->d) {
|
||||
*dst = *src << lshift | src[rstride] >> rshift;
|
||||
src--;
|
||||
dst--;
|
||||
}
|
||||
*dst = *src << lshift;
|
||||
|
||||
/* Zero any additional words resulting from the left shift. */
|
||||
while (dst > r->d) {
|
||||
dst--;
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
r->top = count;
|
||||
bn_correct_top(r);
|
||||
|
||||
BN_set_negative(r, a->neg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
bn_rshift(BIGNUM *r, const BIGNUM *a, int n)
|
||||
{
|
||||
size_t count, shift_bits, shift_words;
|
||||
size_t lshift, rshift;
|
||||
ssize_t lstride;
|
||||
BN_ULONG *dst, *src;
|
||||
size_t i;
|
||||
|
||||
if (n < 0) {
|
||||
BNerror(BN_R_INVALID_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
shift_bits = n;
|
||||
|
||||
/*
|
||||
* Right bit shift, potentially across word boundaries.
|
||||
*
|
||||
* When shift is not an exact multiple of BN_BITS2, the top bits of
|
||||
* the next word need to be left shifted and combined with the right
|
||||
* shifted bits using bitwise OR. If shift is an exact multiple of
|
||||
* BN_BITS2, the source for the left and right shifts are the same
|
||||
* and the shifts become zero (which is effectively a memmove).
|
||||
*/
|
||||
shift_words = shift_bits / BN_BITS2;
|
||||
rshift = shift_bits % BN_BITS2;
|
||||
lshift = (BN_BITS2 - rshift) % BN_BITS2;
|
||||
lstride = (lshift + rshift) / BN_BITS2;
|
||||
|
||||
if (a->top <= shift_words) {
|
||||
BN_zero(r);
|
||||
return 1;
|
||||
}
|
||||
count = a->top - shift_words;
|
||||
|
||||
if (!bn_wexpand(r, count))
|
||||
return 0;
|
||||
|
||||
src = a->d + shift_words;
|
||||
dst = r->d;
|
||||
|
||||
for (i = 1; i < count; i++) {
|
||||
*dst = src[lstride] << lshift | *src >> rshift;
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
*dst = *src >> rshift;
|
||||
|
||||
r->top = count;
|
||||
bn_correct_top(r);
|
||||
|
||||
BN_set_negative(r, a->neg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
BN_lshift1(BIGNUM *r, const BIGNUM *a)
|
||||
{
|
||||
return bn_lshift(r, a, 1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
|
||||
{
|
||||
return bn_lshift(r, a, n);
|
||||
}
|
||||
|
||||
int
|
||||
BN_rshift1(BIGNUM *r, const BIGNUM *a)
|
||||
{
|
||||
return bn_rshift(r, a, 1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
|
||||
{
|
||||
return bn_rshift(r, a, n);
|
||||
}
|
||||
265
externals/libressl/crypto/bn/bn_small_primes.c
vendored
Normal file
265
externals/libressl/crypto/bn/bn_small_primes.c
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
/* $OpenBSD: bn_small_primes.c,v 1.1 2022/11/09 22:52:51 tb Exp $ */
|
||||
/*
|
||||
* Public domain, generated by bn_prime.pl.
|
||||
*/
|
||||
|
||||
#include "bn_prime.h"
|
||||
|
||||
const uint16_t primes[NUMPRIMES] = {
|
||||
2, 3, 5, 7, 11, 13, 17, 19,
|
||||
23, 29, 31, 37, 41, 43, 47, 53,
|
||||
59, 61, 67, 71, 73, 79, 83, 89,
|
||||
97, 101, 103, 107, 109, 113, 127, 131,
|
||||
137, 139, 149, 151, 157, 163, 167, 173,
|
||||
179, 181, 191, 193, 197, 199, 211, 223,
|
||||
227, 229, 233, 239, 241, 251, 257, 263,
|
||||
269, 271, 277, 281, 283, 293, 307, 311,
|
||||
313, 317, 331, 337, 347, 349, 353, 359,
|
||||
367, 373, 379, 383, 389, 397, 401, 409,
|
||||
419, 421, 431, 433, 439, 443, 449, 457,
|
||||
461, 463, 467, 479, 487, 491, 499, 503,
|
||||
509, 521, 523, 541, 547, 557, 563, 569,
|
||||
571, 577, 587, 593, 599, 601, 607, 613,
|
||||
617, 619, 631, 641, 643, 647, 653, 659,
|
||||
661, 673, 677, 683, 691, 701, 709, 719,
|
||||
727, 733, 739, 743, 751, 757, 761, 769,
|
||||
773, 787, 797, 809, 811, 821, 823, 827,
|
||||
829, 839, 853, 857, 859, 863, 877, 881,
|
||||
883, 887, 907, 911, 919, 929, 937, 941,
|
||||
947, 953, 967, 971, 977, 983, 991, 997,
|
||||
1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
|
||||
1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,
|
||||
1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
|
||||
1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
|
||||
1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283,
|
||||
1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
|
||||
1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423,
|
||||
1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459,
|
||||
1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
|
||||
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571,
|
||||
1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
|
||||
1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
|
||||
1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
|
||||
1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
|
||||
1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
|
||||
1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949,
|
||||
1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
|
||||
2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
|
||||
2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
|
||||
2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203,
|
||||
2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
|
||||
2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311,
|
||||
2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
|
||||
2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
|
||||
2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
|
||||
2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579,
|
||||
2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657,
|
||||
2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
|
||||
2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
|
||||
2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801,
|
||||
2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861,
|
||||
2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939,
|
||||
2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011,
|
||||
3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
|
||||
3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
|
||||
3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
|
||||
3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301,
|
||||
3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347,
|
||||
3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
|
||||
3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491,
|
||||
3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541,
|
||||
3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
|
||||
3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671,
|
||||
3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
|
||||
3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
|
||||
3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863,
|
||||
3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923,
|
||||
3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003,
|
||||
4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
|
||||
4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
|
||||
4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
|
||||
4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259,
|
||||
4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337,
|
||||
4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
|
||||
4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481,
|
||||
4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
|
||||
4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621,
|
||||
4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673,
|
||||
4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
|
||||
4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813,
|
||||
4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909,
|
||||
4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967,
|
||||
4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
|
||||
5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
|
||||
5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167,
|
||||
5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233,
|
||||
5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
|
||||
5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
|
||||
5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
|
||||
5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507,
|
||||
5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573,
|
||||
5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
|
||||
5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711,
|
||||
5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
|
||||
5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849,
|
||||
5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897,
|
||||
5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
|
||||
6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
|
||||
6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
|
||||
6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211,
|
||||
6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
|
||||
6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329,
|
||||
6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
|
||||
6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
|
||||
6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563,
|
||||
6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637,
|
||||
6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701,
|
||||
6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779,
|
||||
6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
|
||||
6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907,
|
||||
6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971,
|
||||
6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027,
|
||||
7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121,
|
||||
7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
|
||||
7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253,
|
||||
7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349,
|
||||
7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457,
|
||||
7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
|
||||
7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
|
||||
7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
|
||||
7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691,
|
||||
7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757,
|
||||
7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853,
|
||||
7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
|
||||
7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
|
||||
8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087,
|
||||
8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,
|
||||
8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231,
|
||||
8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
|
||||
8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369,
|
||||
8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
|
||||
8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537,
|
||||
8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609,
|
||||
8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
|
||||
8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731,
|
||||
8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803,
|
||||
8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861,
|
||||
8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
|
||||
8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
|
||||
9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091,
|
||||
9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161,
|
||||
9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
|
||||
9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311,
|
||||
9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
|
||||
9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433,
|
||||
9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491,
|
||||
9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587,
|
||||
9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649,
|
||||
9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
|
||||
9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791,
|
||||
9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
|
||||
9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929,
|
||||
9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
|
||||
10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099,
|
||||
10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163,
|
||||
10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247,
|
||||
10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303,
|
||||
10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369,
|
||||
10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459,
|
||||
10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531,
|
||||
10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627,
|
||||
10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691,
|
||||
10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771,
|
||||
10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
|
||||
10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937,
|
||||
10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003,
|
||||
11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087,
|
||||
11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161,
|
||||
11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
|
||||
11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
|
||||
11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399,
|
||||
11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483,
|
||||
11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551,
|
||||
11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657,
|
||||
11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
|
||||
11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813,
|
||||
11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887,
|
||||
11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941,
|
||||
11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
|
||||
12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101,
|
||||
12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161,
|
||||
12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251,
|
||||
12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323,
|
||||
12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401,
|
||||
12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473,
|
||||
12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
|
||||
12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589,
|
||||
12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653,
|
||||
12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739,
|
||||
12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821,
|
||||
12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907,
|
||||
12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967,
|
||||
12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033,
|
||||
13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109,
|
||||
13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
|
||||
13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259,
|
||||
13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
|
||||
13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421,
|
||||
13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499,
|
||||
13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597,
|
||||
13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681,
|
||||
13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723,
|
||||
13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799,
|
||||
13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879,
|
||||
13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933,
|
||||
13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033,
|
||||
14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143,
|
||||
14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
|
||||
14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323,
|
||||
14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407,
|
||||
14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461,
|
||||
14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549,
|
||||
14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627,
|
||||
14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699,
|
||||
14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
|
||||
14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821,
|
||||
14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887,
|
||||
14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957,
|
||||
14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
|
||||
15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137,
|
||||
15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217,
|
||||
15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277,
|
||||
15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331,
|
||||
15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
|
||||
15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473,
|
||||
15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569,
|
||||
15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643,
|
||||
15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727,
|
||||
15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773,
|
||||
15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
|
||||
15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919,
|
||||
15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007,
|
||||
16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087,
|
||||
16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
|
||||
16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249,
|
||||
16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349,
|
||||
16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427,
|
||||
16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493,
|
||||
16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603,
|
||||
16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661,
|
||||
16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
|
||||
16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843,
|
||||
16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927,
|
||||
16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993,
|
||||
17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053,
|
||||
17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159,
|
||||
17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231,
|
||||
17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327,
|
||||
17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389,
|
||||
17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467,
|
||||
17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519,
|
||||
17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
|
||||
17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683,
|
||||
17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783,
|
||||
17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
|
||||
};
|
||||
309
externals/libressl/crypto/bn/bn_sqr.c
vendored
Normal file
309
externals/libressl/crypto/bn/bn_sqr.c
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
/* $OpenBSD: bn_sqr.c,v 1.30 2023/04/19 10:51:22 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bn_arch.h"
|
||||
#include "bn_local.h"
|
||||
#include "bn_internal.h"
|
||||
|
||||
int bn_sqr(BIGNUM *r, const BIGNUM *a, int max, BN_CTX *ctx);
|
||||
|
||||
/*
|
||||
* bn_sqr_comba4() computes r[] = a[] * a[] using Comba multiplication
|
||||
* (https://everything2.com/title/Comba+multiplication), where a is a
|
||||
* four word array, producing an eight word array result.
|
||||
*/
|
||||
#ifndef HAVE_BN_SQR_COMBA4
|
||||
void
|
||||
bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
|
||||
{
|
||||
BN_ULONG c2, c1, c0;
|
||||
|
||||
bn_mulw_addtw(a[0], a[0], 0, 0, 0, &c2, &c1, &r[0]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[1], a[0], 0, c2, c1, &c2, &c1, &r[1]);
|
||||
|
||||
bn_mulw_addtw(a[1], a[1], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[2], a[0], c2, c1, c0, &c2, &c1, &r[2]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[3], a[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[2], a[1], c2, c1, c0, &c2, &c1, &r[3]);
|
||||
|
||||
bn_mulw_addtw(a[2], a[2], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[3], a[1], c2, c1, c0, &c2, &c1, &r[4]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[3], a[2], 0, c2, c1, &c2, &c1, &r[5]);
|
||||
|
||||
bn_mulw_addtw(a[3], a[3], 0, c2, c1, &c2, &r[7], &r[6]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bn_sqr_comba8() computes r[] = a[] * a[] using Comba multiplication
|
||||
* (https://everything2.com/title/Comba+multiplication), where a is an
|
||||
* eight word array, producing an 16 word array result.
|
||||
*/
|
||||
#ifndef HAVE_BN_SQR_COMBA8
|
||||
void
|
||||
bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
|
||||
{
|
||||
BN_ULONG c2, c1, c0;
|
||||
|
||||
bn_mulw_addtw(a[0], a[0], 0, 0, 0, &c2, &c1, &r[0]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[1], a[0], 0, c2, c1, &c2, &c1, &r[1]);
|
||||
|
||||
bn_mulw_addtw(a[1], a[1], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[2], a[0], c2, c1, c0, &c2, &c1, &r[2]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[3], a[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[2], a[1], c2, c1, c0, &c2, &c1, &r[3]);
|
||||
|
||||
bn_mulw_addtw(a[2], a[2], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[3], a[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[4], a[0], c2, c1, c0, &c2, &c1, &r[4]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[5], a[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[4], a[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[3], a[2], c2, c1, c0, &c2, &c1, &r[5]);
|
||||
|
||||
bn_mulw_addtw(a[3], a[3], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[4], a[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[5], a[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[6], a[0], c2, c1, c0, &c2, &c1, &r[6]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[7], a[0], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[6], a[1], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[5], a[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[4], a[3], c2, c1, c0, &c2, &c1, &r[7]);
|
||||
|
||||
bn_mulw_addtw(a[4], a[4], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[5], a[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[6], a[2], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[7], a[1], c2, c1, c0, &c2, &c1, &r[8]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[7], a[2], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[6], a[3], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[5], a[4], c2, c1, c0, &c2, &c1, &r[9]);
|
||||
|
||||
bn_mulw_addtw(a[5], a[5], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[6], a[4], c2, c1, c0, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[7], a[3], c2, c1, c0, &c2, &c1, &r[10]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[7], a[4], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[6], a[5], c2, c1, c0, &c2, &c1, &r[11]);
|
||||
|
||||
bn_mulw_addtw(a[6], a[6], 0, c2, c1, &c2, &c1, &c0);
|
||||
bn_mul2_mulw_addtw(a[7], a[5], c2, c1, c0, &c2, &c1, &r[12]);
|
||||
|
||||
bn_mul2_mulw_addtw(a[7], a[6], 0, c2, c1, &c2, &c1, &r[13]);
|
||||
|
||||
bn_mulw_addtw(a[7], a[7], 0, c2, c1, &c2, &r[15], &r[14]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_SQR_WORDS
|
||||
/*
|
||||
* bn_sqr_words() computes (r[i*2+1]:r[i*2]) = a[i] * a[i].
|
||||
*/
|
||||
void
|
||||
bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
|
||||
{
|
||||
assert(n >= 0);
|
||||
if (n <= 0)
|
||||
return;
|
||||
|
||||
#ifndef OPENSSL_SMALL_FOOTPRINT
|
||||
while (n & ~3) {
|
||||
bn_mulw(a[0], a[0], &r[1], &r[0]);
|
||||
bn_mulw(a[1], a[1], &r[3], &r[2]);
|
||||
bn_mulw(a[2], a[2], &r[5], &r[4]);
|
||||
bn_mulw(a[3], a[3], &r[7], &r[6]);
|
||||
a += 4;
|
||||
r += 8;
|
||||
n -= 4;
|
||||
}
|
||||
#endif
|
||||
while (n) {
|
||||
bn_mulw(a[0], a[0], &r[1], &r[0]);
|
||||
a++;
|
||||
r += 2;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tmp must have 2*n words */
|
||||
void
|
||||
bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
|
||||
{
|
||||
int i, j, max;
|
||||
const BN_ULONG *ap;
|
||||
BN_ULONG *rp;
|
||||
|
||||
max = n * 2;
|
||||
ap = a;
|
||||
rp = r;
|
||||
rp[0] = rp[max - 1] = 0;
|
||||
rp++;
|
||||
j = n;
|
||||
|
||||
if (--j > 0) {
|
||||
ap++;
|
||||
rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
|
||||
rp += 2;
|
||||
}
|
||||
|
||||
for (i = n - 2; i > 0; i--) {
|
||||
j--;
|
||||
ap++;
|
||||
rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
|
||||
rp += 2;
|
||||
}
|
||||
|
||||
bn_add_words(r, r, r, max);
|
||||
|
||||
/* There will not be a carry */
|
||||
|
||||
bn_sqr_words(tmp, a, n);
|
||||
|
||||
bn_add_words(r, r, tmp, max);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* bn_sqr() computes a * a, storing the result in r. The caller must ensure that
|
||||
* r is not the same BIGNUM as a and that r has been expanded to rn = a->top * 2
|
||||
* words.
|
||||
*/
|
||||
#ifndef HAVE_BN_SQR
|
||||
int
|
||||
bn_sqr(BIGNUM *r, const BIGNUM *a, int rn, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *tmp;
|
||||
int ret = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((tmp = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!bn_wexpand(tmp, rn))
|
||||
goto err;
|
||||
bn_sqr_normal(r->d, a->d, a->top, tmp->d);
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *rr;
|
||||
int rn;
|
||||
int ret = 1;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if (BN_is_zero(a)) {
|
||||
BN_zero(r);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((rr = r) == a)
|
||||
rr = BN_CTX_get(ctx);
|
||||
if (rr == NULL)
|
||||
goto err;
|
||||
|
||||
rn = a->top * 2;
|
||||
if (rn < a->top)
|
||||
goto err;
|
||||
if (!bn_wexpand(rr, rn))
|
||||
goto err;
|
||||
|
||||
if (a->top == 4) {
|
||||
bn_sqr_comba4(rr->d, a->d);
|
||||
} else if (a->top == 8) {
|
||||
bn_sqr_comba8(rr->d, a->d);
|
||||
} else {
|
||||
if (!bn_sqr(rr, a, rn, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
rr->top = rn;
|
||||
bn_correct_top(rr);
|
||||
|
||||
rr->neg = 0;
|
||||
|
||||
if (!bn_copy(r, rr))
|
||||
goto err;
|
||||
done:
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
240
externals/libressl/crypto/bn/bn_word.c
vendored
Normal file
240
externals/libressl/crypto/bn/bn_word.c
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
/* $OpenBSD: bn_word.c,v 1.20 2023/03/11 14:14:54 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bn_local.h"
|
||||
|
||||
BN_ULONG
|
||||
BN_mod_word(const BIGNUM *a, BN_ULONG w)
|
||||
{
|
||||
#ifndef BN_LLONG
|
||||
BN_ULONG ret = 0;
|
||||
#else
|
||||
BN_ULLONG ret = 0;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
if (w == 0)
|
||||
return (BN_ULONG) - 1;
|
||||
|
||||
#ifndef BN_ULLONG
|
||||
/* If |w| is too long and we don't have |BN_ULLONG| then we need to fall back
|
||||
* to using |BN_div_word|. */
|
||||
if (w > ((BN_ULONG)1 << BN_BITS4)) {
|
||||
BIGNUM *tmp = BN_dup(a);
|
||||
if (tmp == NULL) {
|
||||
return (BN_ULONG)-1;
|
||||
}
|
||||
ret = BN_div_word(tmp, w);
|
||||
BN_free(tmp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
w &= BN_MASK2;
|
||||
for (i = a->top - 1; i >= 0; i--) {
|
||||
#ifndef BN_LLONG
|
||||
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) &
|
||||
BN_MASK2l)) % w;
|
||||
ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
|
||||
#else
|
||||
ret = (BN_ULLONG)(((ret << (BN_ULLONG)BN_BITS2) |
|
||||
a->d[i]) % (BN_ULLONG)w);
|
||||
#endif
|
||||
}
|
||||
return ((BN_ULONG)ret);
|
||||
}
|
||||
|
||||
BN_ULONG
|
||||
BN_div_word(BIGNUM *a, BN_ULONG w)
|
||||
{
|
||||
BN_ULONG ret = 0;
|
||||
int i, j;
|
||||
|
||||
w &= BN_MASK2;
|
||||
|
||||
if (!w)
|
||||
/* actually this an error (division by zero) */
|
||||
return (BN_ULONG) - 1;
|
||||
if (a->top == 0)
|
||||
return 0;
|
||||
|
||||
/* normalize input (so bn_div_words doesn't complain) */
|
||||
j = BN_BITS2 - BN_num_bits_word(w);
|
||||
w <<= j;
|
||||
if (!BN_lshift(a, a, j))
|
||||
return (BN_ULONG) - 1;
|
||||
|
||||
for (i = a->top - 1; i >= 0; i--) {
|
||||
BN_ULONG l, d;
|
||||
|
||||
l = a->d[i];
|
||||
bn_div_rem_words(ret, l, w, &d, &ret);
|
||||
a->d[i] = d;
|
||||
}
|
||||
if ((a->top > 0) && (a->d[a->top - 1] == 0))
|
||||
a->top--;
|
||||
ret >>= j;
|
||||
|
||||
/* Set negative again, to handle -0 case. */
|
||||
BN_set_negative(a, a->neg);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
BN_add_word(BIGNUM *a, BN_ULONG w)
|
||||
{
|
||||
BN_ULONG l;
|
||||
int i;
|
||||
|
||||
w &= BN_MASK2;
|
||||
|
||||
/* degenerate case: w is zero */
|
||||
if (!w)
|
||||
return 1;
|
||||
/* degenerate case: a is zero */
|
||||
if (BN_is_zero(a))
|
||||
return BN_set_word(a, w);
|
||||
/* handle 'a' when negative */
|
||||
if (a->neg) {
|
||||
a->neg = 0;
|
||||
i = BN_sub_word(a, w);
|
||||
BN_set_negative(a, !a->neg);
|
||||
return (i);
|
||||
}
|
||||
for (i = 0; w != 0 && i < a->top; i++) {
|
||||
a->d[i] = l = (a->d[i] + w) & BN_MASK2;
|
||||
w = (w > l) ? 1 : 0;
|
||||
}
|
||||
if (w && i == a->top) {
|
||||
if (!bn_wexpand(a, a->top + 1))
|
||||
return 0;
|
||||
a->top++;
|
||||
a->d[i] = w;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_sub_word(BIGNUM *a, BN_ULONG w)
|
||||
{
|
||||
int i;
|
||||
|
||||
w &= BN_MASK2;
|
||||
|
||||
/* degenerate case: w is zero */
|
||||
if (!w)
|
||||
return 1;
|
||||
/* degenerate case: a is zero */
|
||||
if (BN_is_zero(a)) {
|
||||
i = BN_set_word(a, w);
|
||||
if (i != 0)
|
||||
BN_set_negative(a, 1);
|
||||
return i;
|
||||
}
|
||||
/* handle 'a' when negative */
|
||||
if (a->neg) {
|
||||
a->neg = 0;
|
||||
i = BN_add_word(a, w);
|
||||
BN_set_negative(a, !a->neg);
|
||||
return (i);
|
||||
}
|
||||
|
||||
if ((a->top == 1) && (a->d[0] < w)) {
|
||||
a->d[0] = w - a->d[0];
|
||||
BN_set_negative(a, 1);
|
||||
return (1);
|
||||
}
|
||||
i = 0;
|
||||
for (;;) {
|
||||
if (a->d[i] >= w) {
|
||||
a->d[i] -= w;
|
||||
break;
|
||||
} else {
|
||||
a->d[i] = (a->d[i] - w) & BN_MASK2;
|
||||
i++;
|
||||
w = 1;
|
||||
}
|
||||
}
|
||||
if ((a->d[i] == 0) && (i == (a->top - 1)))
|
||||
a->top--;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
BN_mul_word(BIGNUM *a, BN_ULONG w)
|
||||
{
|
||||
BN_ULONG ll;
|
||||
|
||||
w &= BN_MASK2;
|
||||
if (a->top) {
|
||||
if (w == 0)
|
||||
BN_zero(a);
|
||||
else {
|
||||
ll = bn_mul_words(a->d, a->d, a->top, w);
|
||||
if (ll) {
|
||||
if (!bn_wexpand(a, a->top + 1))
|
||||
return (0);
|
||||
a->d[a->top++] = ll;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
1782
externals/libressl/crypto/bn/modexp512-elf-x86_64.S
vendored
Normal file
1782
externals/libressl/crypto/bn/modexp512-elf-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1779
externals/libressl/crypto/bn/modexp512-macosx-x86_64.S
vendored
Normal file
1779
externals/libressl/crypto/bn/modexp512-macosx-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1864
externals/libressl/crypto/bn/modexp512-masm-x86_64.S
vendored
Normal file
1864
externals/libressl/crypto/bn/modexp512-masm-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
148
externals/libressl/crypto/bn/mont-elf-armv4.S
vendored
Normal file
148
externals/libressl/crypto/bn/mont-elf-armv4.S
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
.text
|
||||
|
||||
.global bn_mul_mont
|
||||
.type bn_mul_mont,%function
|
||||
|
||||
.align 2
|
||||
bn_mul_mont:
|
||||
stmdb sp!,{r0,r2} @ sp points at argument block
|
||||
ldr r0,[sp,#3*4] @ load num
|
||||
cmp r0,#2
|
||||
movlt r0,#0
|
||||
addlt sp,sp,#2*4
|
||||
blt .Labrt
|
||||
|
||||
stmdb sp!,{r4-r12,lr} @ save 10 registers
|
||||
|
||||
mov r0,r0,lsl#2 @ rescale r0 for byte count
|
||||
sub sp,sp,r0 @ alloca(4*num)
|
||||
sub sp,sp,#4 @ +extra dword
|
||||
sub r0,r0,#4 @ "num=num-1"
|
||||
add r4,r2,r0 @ &bp[num-1]
|
||||
|
||||
add r0,sp,r0 @ r0 to point at &tp[num-1]
|
||||
ldr r8,[r0,#14*4] @ &n0
|
||||
ldr r2,[r2] @ bp[0]
|
||||
ldr r5,[r1],#4 @ ap[0],ap++
|
||||
ldr r6,[r3],#4 @ np[0],np++
|
||||
ldr r8,[r8] @ *n0
|
||||
str r4,[r0,#15*4] @ save &bp[num]
|
||||
|
||||
umull r10,r11,r5,r2 @ ap[0]*bp[0]
|
||||
str r8,[r0,#14*4] @ save n0 value
|
||||
mul r8,r10,r8 @ "tp[0]"*n0
|
||||
mov r12,#0
|
||||
umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]"
|
||||
mov r4,sp
|
||||
|
||||
.L1st:
|
||||
ldr r5,[r1],#4 @ ap[j],ap++
|
||||
mov r10,r11
|
||||
ldr r6,[r3],#4 @ np[j],np++
|
||||
mov r11,#0
|
||||
umlal r10,r11,r5,r2 @ ap[j]*bp[0]
|
||||
mov r14,#0
|
||||
umlal r12,r14,r6,r8 @ np[j]*n0
|
||||
adds r12,r12,r10
|
||||
str r12,[r4],#4 @ tp[j-1]=,tp++
|
||||
adc r12,r14,#0
|
||||
cmp r4,r0
|
||||
bne .L1st
|
||||
|
||||
adds r12,r12,r11
|
||||
ldr r4,[r0,#13*4] @ restore bp
|
||||
mov r14,#0
|
||||
ldr r8,[r0,#14*4] @ restore n0
|
||||
adc r14,r14,#0
|
||||
str r12,[r0] @ tp[num-1]=
|
||||
str r14,[r0,#4] @ tp[num]=
|
||||
|
||||
.Louter:
|
||||
sub r7,r0,sp @ "original" r0-1 value
|
||||
sub r1,r1,r7 @ "rewind" ap to &ap[1]
|
||||
ldr r2,[r4,#4]! @ *(++bp)
|
||||
sub r3,r3,r7 @ "rewind" np to &np[1]
|
||||
ldr r5,[r1,#-4] @ ap[0]
|
||||
ldr r10,[sp] @ tp[0]
|
||||
ldr r6,[r3,#-4] @ np[0]
|
||||
ldr r7,[sp,#4] @ tp[1]
|
||||
|
||||
mov r11,#0
|
||||
umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0]
|
||||
str r4,[r0,#13*4] @ save bp
|
||||
mul r8,r10,r8
|
||||
mov r12,#0
|
||||
umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]"
|
||||
mov r4,sp
|
||||
|
||||
.Linner:
|
||||
ldr r5,[r1],#4 @ ap[j],ap++
|
||||
adds r10,r11,r7 @ +=tp[j]
|
||||
ldr r6,[r3],#4 @ np[j],np++
|
||||
mov r11,#0
|
||||
umlal r10,r11,r5,r2 @ ap[j]*bp[i]
|
||||
mov r14,#0
|
||||
umlal r12,r14,r6,r8 @ np[j]*n0
|
||||
adc r11,r11,#0
|
||||
ldr r7,[r4,#8] @ tp[j+1]
|
||||
adds r12,r12,r10
|
||||
str r12,[r4],#4 @ tp[j-1]=,tp++
|
||||
adc r12,r14,#0
|
||||
cmp r4,r0
|
||||
bne .Linner
|
||||
|
||||
adds r12,r12,r11
|
||||
mov r14,#0
|
||||
ldr r4,[r0,#13*4] @ restore bp
|
||||
adc r14,r14,#0
|
||||
ldr r8,[r0,#14*4] @ restore n0
|
||||
adds r12,r12,r7
|
||||
ldr r7,[r0,#15*4] @ restore &bp[num]
|
||||
adc r14,r14,#0
|
||||
str r12,[r0] @ tp[num-1]=
|
||||
str r14,[r0,#4] @ tp[num]=
|
||||
|
||||
cmp r4,r7
|
||||
bne .Louter
|
||||
|
||||
ldr r2,[r0,#12*4] @ pull rp
|
||||
add r0,r0,#4 @ r0 to point at &tp[num]
|
||||
sub r5,r0,sp @ "original" num value
|
||||
mov r4,sp @ "rewind" r4
|
||||
mov r1,r4 @ "borrow" r1
|
||||
sub r3,r3,r5 @ "rewind" r3 to &np[0]
|
||||
|
||||
subs r7,r7,r7 @ "clear" carry flag
|
||||
.Lsub: ldr r7,[r4],#4
|
||||
ldr r6,[r3],#4
|
||||
sbcs r7,r7,r6 @ tp[j]-np[j]
|
||||
str r7,[r2],#4 @ rp[j]=
|
||||
teq r4,r0 @ preserve carry
|
||||
bne .Lsub
|
||||
sbcs r14,r14,#0 @ upmost carry
|
||||
mov r4,sp @ "rewind" r4
|
||||
sub r2,r2,r5 @ "rewind" r2
|
||||
|
||||
and r1,r4,r14
|
||||
bic r3,r2,r14
|
||||
orr r1,r1,r3 @ ap=borrow?tp:rp
|
||||
|
||||
.Lcopy: ldr r7,[r1],#4 @ copy or in-place refresh
|
||||
str sp,[r4],#4 @ zap tp
|
||||
str r7,[r2],#4
|
||||
cmp r4,r0
|
||||
bne .Lcopy
|
||||
|
||||
add sp,r0,#4 @ skip over tp[num+1]
|
||||
ldmia sp!,{r4-r12,lr} @ restore registers
|
||||
add sp,sp,#2*4 @ skip over {r0,r2}
|
||||
mov r0,#1
|
||||
.Labrt: tst lr,#1
|
||||
moveq pc,lr @ be binary compatible with V4, yet
|
||||
.word 0xe12fff1e @ interoperable with Thumb ISA:-)
|
||||
.size bn_mul_mont,.-bn_mul_mont
|
||||
.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
|
||||
.align 2
|
||||
#if defined(HAVE_GNU_STACK)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
1379
externals/libressl/crypto/bn/mont-elf-x86_64.S
vendored
Normal file
1379
externals/libressl/crypto/bn/mont-elf-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1376
externals/libressl/crypto/bn/mont-macosx-x86_64.S
vendored
Normal file
1376
externals/libressl/crypto/bn/mont-macosx-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1493
externals/libressl/crypto/bn/mont-masm-x86_64.S
vendored
Normal file
1493
externals/libressl/crypto/bn/mont-masm-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
287
externals/libressl/crypto/bn/mont-mips.S
vendored
Normal file
287
externals/libressl/crypto/bn/mont-mips.S
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
.text
|
||||
|
||||
.set noat
|
||||
.set noreorder
|
||||
|
||||
.align 5
|
||||
.globl bn_mul_mont
|
||||
.ent bn_mul_mont
|
||||
bn_mul_mont:
|
||||
lw $8,16($29)
|
||||
lw $9,20($29)
|
||||
slt $1,$9,4
|
||||
bnez $1,1f
|
||||
li $2,0
|
||||
slt $1,$9,17 # on in-order CPU
|
||||
bnez $1,bn_mul_mont_internal
|
||||
nop
|
||||
1: jr $31
|
||||
li $4,0
|
||||
.end bn_mul_mont
|
||||
|
||||
.align 5
|
||||
.ent bn_mul_mont_internal
|
||||
bn_mul_mont_internal:
|
||||
.frame $30,14*4,$31
|
||||
.mask 0x40000000|16711680,-4
|
||||
sub $29,14*4
|
||||
sw $30,(14-1)*4($29)
|
||||
sw $23,(14-2)*4($29)
|
||||
sw $22,(14-3)*4($29)
|
||||
sw $21,(14-4)*4($29)
|
||||
sw $20,(14-5)*4($29)
|
||||
sw $19,(14-6)*4($29)
|
||||
sw $18,(14-7)*4($29)
|
||||
sw $17,(14-8)*4($29)
|
||||
sw $16,(14-9)*4($29)
|
||||
move $30,$29
|
||||
|
||||
.set reorder
|
||||
lw $8,0($8)
|
||||
lw $13,0($6) # bp[0]
|
||||
lw $12,0($5) # ap[0]
|
||||
lw $14,0($7) # np[0]
|
||||
|
||||
sub $29,2*4 # place for two extra words
|
||||
sll $9,2
|
||||
li $1,-4096
|
||||
sub $29,$9
|
||||
and $29,$1
|
||||
|
||||
multu $12,$13
|
||||
lw $16,4($5)
|
||||
lw $18,4($7)
|
||||
mflo $10
|
||||
mfhi $11
|
||||
multu $10,$8
|
||||
mflo $23
|
||||
|
||||
multu $16,$13
|
||||
mflo $16
|
||||
mfhi $17
|
||||
|
||||
multu $14,$23
|
||||
mflo $24
|
||||
mfhi $25
|
||||
multu $18,$23
|
||||
addu $24,$10
|
||||
sltu $1,$24,$10
|
||||
addu $25,$1
|
||||
mflo $18
|
||||
mfhi $19
|
||||
|
||||
move $15,$29
|
||||
li $22,2*4
|
||||
.align 4
|
||||
.L1st:
|
||||
.set noreorder
|
||||
add $12,$5,$22
|
||||
add $14,$7,$22
|
||||
lw $12,($12)
|
||||
lw $14,($14)
|
||||
|
||||
multu $12,$13
|
||||
addu $10,$16,$11
|
||||
addu $24,$18,$25
|
||||
sltu $1,$10,$11
|
||||
sltu $2,$24,$25
|
||||
addu $11,$17,$1
|
||||
addu $25,$19,$2
|
||||
mflo $16
|
||||
mfhi $17
|
||||
|
||||
addu $24,$10
|
||||
sltu $1,$24,$10
|
||||
multu $14,$23
|
||||
addu $25,$1
|
||||
addu $22,4
|
||||
sw $24,($15)
|
||||
sltu $2,$22,$9
|
||||
mflo $18
|
||||
mfhi $19
|
||||
|
||||
bnez $2,.L1st
|
||||
add $15,4
|
||||
.set reorder
|
||||
|
||||
addu $10,$16,$11
|
||||
sltu $1,$10,$11
|
||||
addu $11,$17,$1
|
||||
|
||||
addu $24,$18,$25
|
||||
sltu $2,$24,$25
|
||||
addu $25,$19,$2
|
||||
addu $24,$10
|
||||
sltu $1,$24,$10
|
||||
addu $25,$1
|
||||
|
||||
sw $24,($15)
|
||||
|
||||
addu $25,$11
|
||||
sltu $1,$25,$11
|
||||
sw $25,4($15)
|
||||
sw $1,2*4($15)
|
||||
|
||||
li $21,4
|
||||
.align 4
|
||||
.Louter:
|
||||
add $13,$6,$21
|
||||
lw $13,($13)
|
||||
lw $12,($5)
|
||||
lw $16,4($5)
|
||||
lw $20,($29)
|
||||
|
||||
multu $12,$13
|
||||
lw $14,($7)
|
||||
lw $18,4($7)
|
||||
mflo $10
|
||||
mfhi $11
|
||||
addu $10,$20
|
||||
multu $10,$8
|
||||
sltu $1,$10,$20
|
||||
addu $11,$1
|
||||
mflo $23
|
||||
|
||||
multu $16,$13
|
||||
mflo $16
|
||||
mfhi $17
|
||||
|
||||
multu $14,$23
|
||||
mflo $24
|
||||
mfhi $25
|
||||
|
||||
multu $18,$23
|
||||
addu $24,$10
|
||||
sltu $1,$24,$10
|
||||
addu $25,$1
|
||||
mflo $18
|
||||
mfhi $19
|
||||
|
||||
move $15,$29
|
||||
li $22,2*4
|
||||
lw $20,4($15)
|
||||
.align 4
|
||||
.Linner:
|
||||
.set noreorder
|
||||
add $12,$5,$22
|
||||
add $14,$7,$22
|
||||
lw $12,($12)
|
||||
lw $14,($14)
|
||||
|
||||
multu $12,$13
|
||||
addu $10,$16,$11
|
||||
addu $24,$18,$25
|
||||
sltu $1,$10,$11
|
||||
sltu $2,$24,$25
|
||||
addu $11,$17,$1
|
||||
addu $25,$19,$2
|
||||
mflo $16
|
||||
mfhi $17
|
||||
|
||||
addu $10,$20
|
||||
addu $22,4
|
||||
multu $14,$23
|
||||
sltu $1,$10,$20
|
||||
addu $24,$10
|
||||
addu $11,$1
|
||||
sltu $2,$24,$10
|
||||
lw $20,2*4($15)
|
||||
addu $25,$2
|
||||
sltu $1,$22,$9
|
||||
mflo $18
|
||||
mfhi $19
|
||||
sw $24,($15)
|
||||
bnez $1,.Linner
|
||||
add $15,4
|
||||
.set reorder
|
||||
|
||||
addu $10,$16,$11
|
||||
sltu $1,$10,$11
|
||||
addu $11,$17,$1
|
||||
addu $10,$20
|
||||
sltu $2,$10,$20
|
||||
addu $11,$2
|
||||
|
||||
lw $20,2*4($15)
|
||||
addu $24,$18,$25
|
||||
sltu $1,$24,$25
|
||||
addu $25,$19,$1
|
||||
addu $24,$10
|
||||
sltu $2,$24,$10
|
||||
addu $25,$2
|
||||
sw $24,($15)
|
||||
|
||||
addu $24,$25,$11
|
||||
sltu $25,$24,$11
|
||||
addu $24,$20
|
||||
sltu $1,$24,$20
|
||||
addu $25,$1
|
||||
sw $24,4($15)
|
||||
sw $25,2*4($15)
|
||||
|
||||
addu $21,4
|
||||
sltu $2,$21,$9
|
||||
bnez $2,.Louter
|
||||
|
||||
.set noreorder
|
||||
add $20,$29,$9 # &tp[num]
|
||||
move $15,$29
|
||||
move $5,$29
|
||||
li $11,0 # clear borrow bit
|
||||
|
||||
.align 4
|
||||
.Lsub: lw $10,($15)
|
||||
lw $24,($7)
|
||||
add $15,4
|
||||
add $7,4
|
||||
subu $24,$10,$24 # tp[i]-np[i]
|
||||
sgtu $1,$24,$10
|
||||
subu $10,$24,$11
|
||||
sgtu $11,$10,$24
|
||||
sw $10,($4)
|
||||
or $11,$1
|
||||
sltu $1,$15,$20
|
||||
bnez $1,.Lsub
|
||||
add $4,4
|
||||
|
||||
subu $11,$25,$11 # handle upmost overflow bit
|
||||
move $15,$29
|
||||
sub $4,$9 # restore rp
|
||||
not $25,$11
|
||||
|
||||
and $5,$11,$29
|
||||
and $6,$25,$4
|
||||
or $5,$5,$6 # ap=borrow?tp:rp
|
||||
|
||||
.align 4
|
||||
.Lcopy: lw $12,($5)
|
||||
add $5,4
|
||||
sw $0,($15)
|
||||
add $15,4
|
||||
sltu $1,$15,$20
|
||||
sw $12,($4)
|
||||
bnez $1,.Lcopy
|
||||
add $4,4
|
||||
|
||||
li $4,1
|
||||
li $2,1
|
||||
|
||||
.set noreorder
|
||||
move $29,$30
|
||||
lw $30,(14-1)*4($29)
|
||||
lw $23,(14-2)*4($29)
|
||||
lw $22,(14-3)*4($29)
|
||||
lw $21,(14-4)*4($29)
|
||||
lw $20,(14-5)*4($29)
|
||||
lw $19,(14-6)*4($29)
|
||||
lw $18,(14-7)*4($29)
|
||||
lw $17,(14-8)*4($29)
|
||||
lw $16,(14-9)*4($29)
|
||||
jr $31
|
||||
add $29,14*4
|
||||
.end bn_mul_mont_internal
|
||||
.rdata
|
||||
.asciiz "Montgomery Multiplication for MIPS, CRYPTOGAMS by <appro@openssl.org>"
|
||||
#if defined(HAVE_GNU_STACK)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
1182
externals/libressl/crypto/bn/mont5-elf-x86_64.S
vendored
Normal file
1182
externals/libressl/crypto/bn/mont5-elf-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1179
externals/libressl/crypto/bn/mont5-macosx-x86_64.S
vendored
Normal file
1179
externals/libressl/crypto/bn/mont5-macosx-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1415
externals/libressl/crypto/bn/mont5-masm-x86_64.S
vendored
Normal file
1415
externals/libressl/crypto/bn/mont5-masm-x86_64.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
856
externals/libressl/crypto/bn/s2n_bignum.h
vendored
Normal file
856
externals/libressl/crypto/bn/s2n_bignum.h
vendored
Normal file
@@ -0,0 +1,856 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// C prototypes for s2n-bignum functions, so you can use them in C programs via
|
||||
//
|
||||
// #include "s2n-bignum.h"
|
||||
//
|
||||
// The functions are listed in alphabetical order with a brief description
|
||||
// in comments for each one. For more detailed documentation see the comment
|
||||
// banner at the top of the corresponding assembly (.S) file, and
|
||||
// for the last word in what properties it satisfies see the spec in the
|
||||
// formal proof (the .ml file in the architecture-specific directory).
|
||||
//
|
||||
// For some functions there are additional variants with names ending in
|
||||
// "_alt". These have the same core mathematical functionality as their
|
||||
// non-"alt" versions, but can be better suited to some microarchitectures:
|
||||
//
|
||||
// - On x86, the "_alt" forms avoid BMI and ADX instruction set
|
||||
// extensions, so will run on any x86_64 machine, even older ones
|
||||
//
|
||||
// - On ARM, the "_alt" forms target machines with higher multiplier
|
||||
// throughput, generally offering higher performance there.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Add, z := x + y
|
||||
// Inputs x[m], y[n]; outputs function return (carry-out) and z[p]
|
||||
extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Add modulo p_25519, z := (x + y) mod p_25519, assuming x and y reduced
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_add_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Add modulo p_256, z := (x + y) mod p_256, assuming x and y reduced
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_add_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Add modulo p_256k1, z := (x + y) mod p_256k1, assuming x and y reduced
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_add_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Add modulo p_384, z := (x + y) mod p_384, assuming x and y reduced
|
||||
// Inputs x[6], y[6]; output z[6]
|
||||
extern void bignum_add_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]);
|
||||
|
||||
// Add modulo p_521, z := (x + y) mod p_521, assuming x and y reduced
|
||||
// Inputs x[9], y[9]; output z[9]
|
||||
extern void bignum_add_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]);
|
||||
|
||||
// Compute "amontification" constant z :== 2^{128k} (congruent mod m)
|
||||
// Input m[k]; output z[k]; temporary buffer t[>=k]
|
||||
extern void bignum_amontifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t);
|
||||
|
||||
// Almost-Montgomery multiply, z :== (x * y / 2^{64k}) (congruent mod m)
|
||||
// Inputs x[k], y[k], m[k]; output z[k]
|
||||
extern void bignum_amontmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m);
|
||||
|
||||
// Almost-Montgomery reduce, z :== (x' / 2^{64p}) (congruent mod m)
|
||||
// Inputs x[n], m[k], p; output z[k]
|
||||
extern void bignum_amontredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p);
|
||||
|
||||
// Almost-Montgomery square, z :== (x^2 / 2^{64k}) (congruent mod m)
|
||||
// Inputs x[k], m[k]; output z[k]
|
||||
extern void bignum_amontsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m);
|
||||
|
||||
// Convert 4-digit (256-bit) bignum to/from big-endian form
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_bigendian_4 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert 6-digit (384-bit) bignum to/from big-endian form
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_bigendian_6 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Select bitfield starting at bit n with length l <= 64
|
||||
// Inputs x[k], n, l; output function return
|
||||
extern uint64_t bignum_bitfield (uint64_t k, uint64_t *x, uint64_t n, uint64_t l);
|
||||
|
||||
// Return size of bignum in bits
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_bitsize (uint64_t k, uint64_t *x);
|
||||
|
||||
// Divide by a single (nonzero) word, z := x / m and return x mod m
|
||||
// Inputs x[n], m; outputs function return (remainder) and z[k]
|
||||
extern uint64_t bignum_cdiv (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m);
|
||||
|
||||
// Divide by a single word, z := x / m when known to be exact
|
||||
// Inputs x[n], m; output z[k]
|
||||
extern void bignum_cdiv_exact (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m);
|
||||
|
||||
// Count leading zero digits (64-bit words)
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_cld (uint64_t k, uint64_t *x);
|
||||
|
||||
// Count leading zero bits
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_clz (uint64_t k, uint64_t *x);
|
||||
|
||||
// Multiply-add with single-word multiplier, z := z + c * y
|
||||
// Inputs c, y[n]; outputs function return (carry-out) and z[k]
|
||||
extern uint64_t bignum_cmadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y);
|
||||
|
||||
// Negated multiply-add with single-word multiplier, z := z - c * y
|
||||
// Inputs c, y[n]; outputs function return (negative carry-out) and z[k]
|
||||
extern uint64_t bignum_cmnegadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y);
|
||||
|
||||
// Find modulus of bignum w.r.t. single nonzero word m, returning x mod m
|
||||
// Input x[k], m; output function return
|
||||
extern uint64_t bignum_cmod (uint64_t k, uint64_t *x, uint64_t m);
|
||||
|
||||
// Multiply by a single word, z := c * y
|
||||
// Inputs c, y[n]; outputs function return (carry-out) and z[k]
|
||||
extern uint64_t bignum_cmul (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y);
|
||||
|
||||
// Multiply by a single word modulo p_25519, z := (c * x) mod p_25519, assuming x reduced
|
||||
// Inputs c, x[4]; output z[4]
|
||||
extern void bignum_cmul_p25519 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]);
|
||||
extern void bignum_cmul_p25519_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]);
|
||||
|
||||
// Multiply by a single word modulo p_256, z := (c * x) mod p_256, assuming x reduced
|
||||
// Inputs c, x[4]; output z[4]
|
||||
extern void bignum_cmul_p256 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]);
|
||||
extern void bignum_cmul_p256_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]);
|
||||
|
||||
// Multiply by a single word modulo p_256k1, z := (c * x) mod p_256k1, assuming x reduced
|
||||
// Inputs c, x[4]; output z[4]
|
||||
extern void bignum_cmul_p256k1 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]);
|
||||
extern void bignum_cmul_p256k1_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]);
|
||||
|
||||
// Multiply by a single word modulo p_384, z := (c * x) mod p_384, assuming x reduced
|
||||
// Inputs c, x[6]; output z[6]
|
||||
extern void bignum_cmul_p384 (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]);
|
||||
extern void bignum_cmul_p384_alt (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]);
|
||||
|
||||
// Multiply by a single word modulo p_521, z := (c * x) mod p_521, assuming x reduced
|
||||
// Inputs c, x[9]; output z[9]
|
||||
extern void bignum_cmul_p521 (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]);
|
||||
extern void bignum_cmul_p521_alt (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]);
|
||||
|
||||
// Test bignums for coprimality, gcd(x,y) = 1
|
||||
// Inputs x[m], y[n]; output function return; temporary buffer t[>=2*max(m,n)]
|
||||
extern uint64_t bignum_coprime (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y, uint64_t *t);
|
||||
|
||||
// Copy bignum with zero-extension or truncation, z := x
|
||||
// Input x[n]; output z[k]
|
||||
extern void bignum_copy (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x);
|
||||
|
||||
// Count trailing zero digits (64-bit words)
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_ctd (uint64_t k, uint64_t *x);
|
||||
|
||||
// Count trailing zero bits
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_ctz (uint64_t k, uint64_t *x);
|
||||
|
||||
// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_deamont_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_deamont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256k1
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_deamont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert from almost-Montgomery form, z := (x / 2^384) mod p_384
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_deamont_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
extern void bignum_deamont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Convert from almost-Montgomery form z := (x / 2^576) mod p_521
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_deamont_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Convert from (almost-)Montgomery form z := (x / 2^{64k}) mod m
|
||||
// Inputs x[k], m[k]; output z[k]
|
||||
extern void bignum_demont (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m);
|
||||
|
||||
// Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_demont_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_demont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert from Montgomery form z := (x / 2^256) mod p_256k1, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_demont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert from Montgomery form z := (x / 2^384) mod p_384, assuming x reduced
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_demont_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
extern void bignum_demont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Convert from Montgomery form z := (x / 2^576) mod p_521, assuming x reduced
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_demont_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Select digit x[n]
|
||||
// Inputs x[k], n; output function return
|
||||
extern uint64_t bignum_digit (uint64_t k, uint64_t *x, uint64_t n);
|
||||
|
||||
// Return size of bignum in digits (64-bit word)
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_digitsize (uint64_t k, uint64_t *x);
|
||||
|
||||
// Divide bignum by 10: z' := z div 10, returning remainder z mod 10
|
||||
// Inputs z[k]; outputs function return (remainder) and z[k]
|
||||
extern uint64_t bignum_divmod10 (uint64_t k, uint64_t *z);
|
||||
|
||||
// Double modulo p_25519, z := (2 * x) mod p_25519, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_double_p25519 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Double modulo p_256, z := (2 * x) mod p_256, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_double_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Double modulo p_256k1, z := (2 * x) mod p_256k1, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_double_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Double modulo p_384, z := (2 * x) mod p_384, assuming x reduced
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_double_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Double modulo p_521, z := (2 * x) mod p_521, assuming x reduced
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_double_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Extended Montgomery reduce, returning results in input-output buffer
|
||||
// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k]
|
||||
extern uint64_t bignum_emontredc (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w);
|
||||
|
||||
// Extended Montgomery reduce in 8-digit blocks, results in input-output buffer
|
||||
// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k]
|
||||
extern uint64_t bignum_emontredc_8n (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w);
|
||||
|
||||
// Test bignums for equality, x = y
|
||||
// Inputs x[m], y[n]; output function return
|
||||
extern uint64_t bignum_eq (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Test bignum for even-ness
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_even (uint64_t k, uint64_t *x);
|
||||
|
||||
// Convert 4-digit (256-bit) bignum from big-endian bytes
|
||||
// Input x[32] (bytes); output z[4]
|
||||
extern void bignum_frombebytes_4 (uint64_t z[static 4], uint8_t x[static 32]);
|
||||
|
||||
// Convert 6-digit (384-bit) bignum from big-endian bytes
|
||||
// Input x[48] (bytes); output z[6]
|
||||
extern void bignum_frombebytes_6 (uint64_t z[static 6], uint8_t x[static 48]);
|
||||
|
||||
// Convert 4-digit (256-bit) bignum from little-endian bytes
|
||||
// Input x[32] (bytes); output z[4]
|
||||
extern void bignum_fromlebytes_4 (uint64_t z[static 4], uint8_t x[static 32]);
|
||||
|
||||
// Convert 6-digit (384-bit) bignum from little-endian bytes
|
||||
// Input x[48] (bytes); output z[6]
|
||||
extern void bignum_fromlebytes_6 (uint64_t z[static 6], uint8_t x[static 48]);
|
||||
|
||||
// Convert little-endian bytes to 9-digit 528-bit bignum
|
||||
// Input x[66] (bytes); output z[9]
|
||||
extern void bignum_fromlebytes_p521 (uint64_t z[static 9],uint8_t x[static 66]);
|
||||
|
||||
// Compare bignums, x >= y
|
||||
// Inputs x[m], y[n]; output function return
|
||||
extern uint64_t bignum_ge (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Compare bignums, x > y
|
||||
// Inputs x[m], y[n]; output function return
|
||||
extern uint64_t bignum_gt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Halve modulo p_256, z := (x / 2) mod p_256, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_half_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Halve modulo p_256k1, z := (x / 2) mod p_256k1, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_half_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Halve modulo p_384, z := (x / 2) mod p_384, assuming x reduced
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_half_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// 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]);
|
||||
|
||||
// Test bignum for zero-ness, x = 0
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_iszero (uint64_t k, uint64_t *x);
|
||||
|
||||
// Multiply z := x * y
|
||||
// Inputs x[16], y[16]; output z[32]; temporary buffer t[>=32]
|
||||
extern void bignum_kmul_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t y[static 16], uint64_t t[static 32]);
|
||||
|
||||
// Multiply z := x * y
|
||||
// Inputs x[32], y[32]; output z[64]; temporary buffer t[>=96]
|
||||
extern void bignum_kmul_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t y[static 32], uint64_t t[static 96]);
|
||||
|
||||
// Square, z := x^2
|
||||
// Input x[16]; output z[32]; temporary buffer t[>=24]
|
||||
extern void bignum_ksqr_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t t[static 24]);
|
||||
|
||||
// Square, z := x^2
|
||||
// Input x[32]; output z[64]; temporary buffer t[>=72]
|
||||
extern void bignum_ksqr_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t t[static 72]);
|
||||
|
||||
// Compare bignums, x <= y
|
||||
// Inputs x[m], y[n]; output function return
|
||||
extern uint64_t bignum_le (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Convert 4-digit (256-bit) bignum to/from little-endian form
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_littleendian_4 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert 6-digit (384-bit) bignum to/from little-endian form
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_littleendian_6 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Compare bignums, x < y
|
||||
// Inputs x[m], y[n]; output function return
|
||||
extern uint64_t bignum_lt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Multiply-add, z := z + x * y
|
||||
// Inputs x[m], y[n]; outputs function return (carry-out) and z[k]
|
||||
extern uint64_t bignum_madd (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Reduce modulo group order, z := x mod n_256
|
||||
// Input x[k]; output z[4]
|
||||
extern void bignum_mod_n256 (uint64_t z[static 4], uint64_t k, uint64_t *x);
|
||||
extern void bignum_mod_n256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x);
|
||||
|
||||
// Reduce modulo group order, z := x mod n_256
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_mod_n256_4 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Reduce modulo group order, z := x mod n_256k1
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_mod_n256k1_4 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Reduce modulo group order, z := x mod n_384
|
||||
// Input x[k]; output z[6]
|
||||
extern void bignum_mod_n384 (uint64_t z[static 6], uint64_t k, uint64_t *x);
|
||||
extern void bignum_mod_n384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x);
|
||||
|
||||
// Reduce modulo group order, z := x mod n_384
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_mod_n384_6 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Reduce modulo group order, z := x mod n_521
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_mod_n521_9 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
extern void bignum_mod_n521_9_alt (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Reduce modulo field characteristic, z := x mod p_25519
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_mod_p25519_4 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Reduce modulo field characteristic, z := x mod p_256
|
||||
// Input x[k]; output z[4]
|
||||
extern void bignum_mod_p256 (uint64_t z[static 4], uint64_t k, uint64_t *x);
|
||||
extern void bignum_mod_p256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x);
|
||||
|
||||
// Reduce modulo field characteristic, z := x mod p_256
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_mod_p256_4 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Reduce modulo field characteristic, z := x mod p_256k1
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_mod_p256k1_4 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Reduce modulo field characteristic, z := x mod p_384
|
||||
// Input x[k]; output z[6]
|
||||
extern void bignum_mod_p384 (uint64_t z[static 6], uint64_t k, uint64_t *x);
|
||||
extern void bignum_mod_p384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x);
|
||||
|
||||
// Reduce modulo field characteristic, z := x mod p_384
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_mod_p384_6 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Reduce modulo field characteristic, z := x mod p_521
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_mod_p521_9 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// 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, uint64_t *x, uint64_t *y, uint64_t *m);
|
||||
|
||||
// Double modulo m, z := (2 * x) mod m, assuming x reduced
|
||||
// Inputs x[k], m[k]; output z[k]
|
||||
extern void bignum_moddouble (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m);
|
||||
|
||||
// Compute "modification" constant z := 2^{64k} mod m
|
||||
// Input m[k]; output z[k]; temporary buffer t[>=k]
|
||||
extern void bignum_modifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t);
|
||||
|
||||
// Invert modulo m, z = (1/a) mod b, assuming b is an odd number > 1, a coprime to b
|
||||
// Inputs a[k], b[k]; output z[k]; temporary buffer t[>=3*k]
|
||||
extern void bignum_modinv (uint64_t k, uint64_t *z, uint64_t *a, uint64_t *b, uint64_t *t);
|
||||
|
||||
// Optionally negate modulo m, z := (-x) mod m (if p nonzero) or z := x (if p zero), assuming x reduced
|
||||
// Inputs p, x[k], m[k]; output z[k]
|
||||
extern void bignum_modoptneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x, uint64_t *m);
|
||||
|
||||
// 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, uint64_t *x, uint64_t *y, uint64_t *m);
|
||||
|
||||
// Compute "montification" constant z := 2^{128k} mod m
|
||||
// Input m[k]; output z[k]; temporary buffer t[>=k]
|
||||
extern void bignum_montifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t);
|
||||
|
||||
// Montgomery multiply, z := (x * y / 2^{64k}) mod m
|
||||
// Inputs x[k], y[k], m[k]; output z[k]
|
||||
extern void bignum_montmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m);
|
||||
|
||||
// Montgomery multiply, z := (x * y / 2^256) mod p_256
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_montmul_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
extern void bignum_montmul_p256_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Montgomery multiply, z := (x * y / 2^256) mod p_256k1
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_montmul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
extern void bignum_montmul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Montgomery multiply, z := (x * y / 2^384) mod p_384
|
||||
// Inputs x[6], y[6]; output z[6]
|
||||
extern void bignum_montmul_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]);
|
||||
extern void bignum_montmul_p384_alt (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]);
|
||||
|
||||
// Montgomery multiply, z := (x * y / 2^576) mod p_521
|
||||
// Inputs x[9], y[9]; output z[9]
|
||||
extern void bignum_montmul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]);
|
||||
extern void bignum_montmul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]);
|
||||
|
||||
// Montgomery reduce, z := (x' / 2^{64p}) MOD m
|
||||
// Inputs x[n], m[k], p; output z[k]
|
||||
extern void bignum_montredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p);
|
||||
|
||||
// Montgomery square, z := (x^2 / 2^{64k}) mod m
|
||||
// Inputs x[k], m[k]; output z[k]
|
||||
extern void bignum_montsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m);
|
||||
|
||||
// Montgomery square, z := (x^2 / 2^256) mod p_256
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_montsqr_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_montsqr_p256_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Montgomery square, z := (x^2 / 2^256) mod p_256k1
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_montsqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_montsqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Montgomery square, z := (x^2 / 2^384) mod p_384
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_montsqr_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
extern void bignum_montsqr_p384_alt (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Montgomery square, z := (x^2 / 2^576) mod p_521
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_montsqr_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
extern void bignum_montsqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Multiply z := x * y
|
||||
// Inputs x[m], y[n]; output z[k]
|
||||
extern void bignum_mul (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Multiply z := x * y
|
||||
// Inputs x[4], y[4]; output z[8]
|
||||
extern void bignum_mul_4_8 (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
extern void bignum_mul_4_8_alt (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Multiply z := x * y
|
||||
// Inputs x[6], y[6]; output z[12]
|
||||
extern void bignum_mul_6_12 (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]);
|
||||
extern void bignum_mul_6_12_alt (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]);
|
||||
|
||||
// Multiply z := x * y
|
||||
// Inputs x[8], y[8]; output z[16]
|
||||
extern void bignum_mul_8_16 (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]);
|
||||
extern void bignum_mul_8_16_alt (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]);
|
||||
|
||||
// Multiply modulo p_25519, z := (x * y) mod p_25519
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_mul_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
extern void bignum_mul_p25519_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Multiply modulo p_256k1, z := (x * y) mod p_256k1
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_mul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
extern void bignum_mul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Multiply modulo p_521, z := (x * y) mod p_521, assuming x and y reduced
|
||||
// Inputs x[9], y[9]; output z[9]
|
||||
extern void bignum_mul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]);
|
||||
extern void bignum_mul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]);
|
||||
|
||||
// Multiply bignum by 10 and add word: z := 10 * z + d
|
||||
// Inputs z[k], d; outputs function return (carry) and z[k]
|
||||
extern uint64_t bignum_muladd10 (uint64_t k, uint64_t *z, uint64_t d);
|
||||
|
||||
// Multiplex/select z := x (if p nonzero) or z := y (if p zero)
|
||||
// Inputs p, x[k], y[k]; output z[k]
|
||||
extern void bignum_mux (uint64_t p, uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y);
|
||||
|
||||
// 256-bit multiplex/select z := x (if p nonzero) or z := y (if p zero)
|
||||
// Inputs p, x[4], y[4]; output z[4]
|
||||
extern void bignum_mux_4 (uint64_t p, uint64_t z[static 4],uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// 384-bit multiplex/select z := x (if p nonzero) or z := y (if p zero)
|
||||
// Inputs p, x[6], y[6]; output z[6]
|
||||
extern void bignum_mux_6 (uint64_t p, uint64_t z[static 6],uint64_t x[static 6], uint64_t y[static 6]);
|
||||
|
||||
// Select element from 16-element table, z := xs[k*i]
|
||||
// Inputs xs[16*k], i; output z[k]
|
||||
extern void bignum_mux16 (uint64_t k, uint64_t *z, uint64_t *xs, uint64_t i);
|
||||
|
||||
// Negate modulo p_25519, z := (-x) mod p_25519, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_neg_p25519 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Negate modulo p_256, z := (-x) mod p_256, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_neg_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Negate modulo p_256k1, z := (-x) mod p_256k1, assuming x reduced
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_neg_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Negate modulo p_384, z := (-x) mod p_384, assuming x reduced
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_neg_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Negate modulo p_521, z := (-x) mod p_521, assuming x reduced
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_neg_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Negated modular inverse, z := (-1/x) mod 2^{64k}
|
||||
// Input x[k]; output z[k]
|
||||
extern void bignum_negmodinv (uint64_t k, uint64_t *z, uint64_t *x);
|
||||
|
||||
// Test bignum for nonzero-ness x =/= 0
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_nonzero (uint64_t k, uint64_t *x);
|
||||
|
||||
// Test 256-bit bignum for nonzero-ness x =/= 0
|
||||
// Input x[4]; output function return
|
||||
extern uint64_t bignum_nonzero_4(uint64_t x[static 4]);
|
||||
|
||||
// Test 384-bit bignum for nonzero-ness x =/= 0
|
||||
// Input x[6]; output function return
|
||||
extern uint64_t bignum_nonzero_6(uint64_t x[static 6]);
|
||||
|
||||
// Normalize bignum in-place by shifting left till top bit is 1
|
||||
// Input z[k]; outputs function return (bits shifted left) and z[k]
|
||||
extern uint64_t bignum_normalize (uint64_t k, uint64_t *z);
|
||||
|
||||
// Test bignum for odd-ness
|
||||
// Input x[k]; output function return
|
||||
extern uint64_t bignum_odd (uint64_t k, uint64_t *x);
|
||||
|
||||
// Convert single digit to bignum, z := n
|
||||
// Input n; output z[k]
|
||||
extern void bignum_of_word (uint64_t k, uint64_t *z, uint64_t n);
|
||||
|
||||
// Optionally add, z := x + y (if p nonzero) or z := x (if p zero)
|
||||
// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k]
|
||||
extern uint64_t bignum_optadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y);
|
||||
|
||||
// Optionally negate, z := -x (if p nonzero) or z := x (if p zero)
|
||||
// Inputs p, x[k]; outputs function return (nonzero input) and z[k]
|
||||
extern uint64_t bignum_optneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x);
|
||||
|
||||
// Optionally negate modulo p_25519, z := (-x) mod p_25519 (if p nonzero) or z := x (if p zero), assuming x reduced
|
||||
// Inputs p, x[4]; output z[4]
|
||||
extern void bignum_optneg_p25519 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]);
|
||||
|
||||
// Optionally negate modulo p_256, z := (-x) mod p_256 (if p nonzero) or z := x (if p zero), assuming x reduced
|
||||
// Inputs p, x[4]; output z[4]
|
||||
extern void bignum_optneg_p256 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]);
|
||||
|
||||
// Optionally negate modulo p_256k1, z := (-x) mod p_256k1 (if p nonzero) or z := x (if p zero), assuming x reduced
|
||||
// Inputs p, x[4]; output z[4]
|
||||
extern void bignum_optneg_p256k1 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]);
|
||||
|
||||
// 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]);
|
||||
|
||||
// Optionally negate modulo p_521, z := (-x) mod p_521 (if p nonzero) or z := x (if p zero), assuming x reduced
|
||||
// Inputs p, x[9]; output z[9]
|
||||
extern void bignum_optneg_p521 (uint64_t z[static 9], uint64_t p, uint64_t x[static 9]);
|
||||
|
||||
// Optionally subtract, z := x - y (if p nonzero) or z := x (if p zero)
|
||||
// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k]
|
||||
extern uint64_t bignum_optsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y);
|
||||
|
||||
// Optionally subtract or add, z := x + sgn(p) * y interpreting p as signed
|
||||
// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k]
|
||||
extern uint64_t bignum_optsubadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y);
|
||||
|
||||
// Return bignum of power of 2, z := 2^n
|
||||
// Input n; output z[k]
|
||||
extern void bignum_pow2 (uint64_t k, uint64_t *z, uint64_t n);
|
||||
|
||||
// Shift bignum left by c < 64 bits z := x * 2^c
|
||||
// Inputs x[n], c; outputs function return (carry-out) and z[k]
|
||||
extern uint64_t bignum_shl_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c);
|
||||
|
||||
// Shift bignum right by c < 64 bits z := floor(x / 2^c)
|
||||
// Inputs x[n], c; outputs function return (bits shifted out) and z[k]
|
||||
extern uint64_t bignum_shr_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c);
|
||||
|
||||
// Square, z := x^2
|
||||
// Input x[n]; output z[k]
|
||||
extern void bignum_sqr (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x);
|
||||
|
||||
// Square, z := x^2
|
||||
// Input x[4]; output z[8]
|
||||
extern void bignum_sqr_4_8 (uint64_t z[static 8], uint64_t x[static 4]);
|
||||
extern void bignum_sqr_4_8_alt (uint64_t z[static 8], uint64_t x[static 4]);
|
||||
|
||||
// Square, z := x^2
|
||||
// Input x[6]; output z[12]
|
||||
extern void bignum_sqr_6_12 (uint64_t z[static 12], uint64_t x[static 6]);
|
||||
extern void bignum_sqr_6_12_alt (uint64_t z[static 12], uint64_t x[static 6]);
|
||||
|
||||
// Square, z := x^2
|
||||
// Input x[8]; output z[16]
|
||||
extern void bignum_sqr_8_16 (uint64_t z[static 16], uint64_t x[static 8]);
|
||||
extern void bignum_sqr_8_16_alt (uint64_t z[static 16], uint64_t x[static 8]);
|
||||
|
||||
// Square modulo p_25519, z := (x^2) mod p_25519
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_sqr_p25519 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_sqr_p25519_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Square modulo p_256k1, z := (x^2) mod p_256k1
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_sqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_sqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Square modulo p_521, z := (x^2) mod p_521, assuming x reduced
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_sqr_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
extern void bignum_sqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Subtract, z := x - y
|
||||
// Inputs x[m], y[n]; outputs function return (carry-out) and z[p]
|
||||
extern uint64_t bignum_sub (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y);
|
||||
|
||||
// Subtract modulo p_25519, z := (x - y) mod p_25519, assuming x and y reduced
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_sub_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Subtract modulo p_256, z := (x - y) mod p_256, assuming x and y reduced
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_sub_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Subtract modulo p_256k1, z := (x - y) mod p_256k1, assuming x and y reduced
|
||||
// Inputs x[4], y[4]; output z[4]
|
||||
extern void bignum_sub_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]);
|
||||
|
||||
// Subtract modulo p_384, z := (x - y) mod p_384, assuming x and y reduced
|
||||
// Inputs x[6], y[6]; output z[6]
|
||||
extern void bignum_sub_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]);
|
||||
|
||||
// Subtract modulo p_521, z := (x - y) mod p_521, assuming x and y reduced
|
||||
// Inputs x[9], y[9]; output z[9]
|
||||
extern void bignum_sub_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]);
|
||||
|
||||
// Convert 4-digit (256-bit) bignum to big-endian bytes
|
||||
// Input x[4]; output z[32] (bytes)
|
||||
extern void bignum_tobebytes_4 (uint8_t z[static 32], uint64_t x[static 4]);
|
||||
|
||||
// Convert 6-digit (384-bit) bignum to big-endian bytes
|
||||
// Input x[6]; output z[48] (bytes)
|
||||
extern void bignum_tobebytes_6 (uint8_t z[static 48], uint64_t x[static 6]);
|
||||
|
||||
// Convert 4-digit (256-bit) bignum to little-endian bytes
|
||||
// Input x[4]; output z[32] (bytes)
|
||||
extern void bignum_tolebytes_4 (uint8_t z[static 32], uint64_t x[static 4]);
|
||||
|
||||
// Convert 6-digit (384-bit) bignum to little-endian bytes
|
||||
// Input x[6]; output z[48] (bytes)
|
||||
extern void bignum_tolebytes_6 (uint8_t z[static 48], uint64_t x[static 6]);
|
||||
|
||||
// Convert 9-digit 528-bit bignum to little-endian bytes
|
||||
// Input x[6]; output z[66] (bytes)
|
||||
extern void bignum_tolebytes_p521 (uint8_t z[static 66], uint64_t x[static 9]);
|
||||
|
||||
// Convert to Montgomery form z := (2^256 * x) mod p_256
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_tomont_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_tomont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert to Montgomery form z := (2^256 * x) mod p_256k1
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_tomont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_tomont_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Convert to Montgomery form z := (2^384 * x) mod p_384
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_tomont_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
extern void bignum_tomont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Convert to Montgomery form z := (2^576 * x) mod p_521
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_tomont_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Triple modulo p_256, z := (3 * x) mod p_256
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_triple_p256 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_triple_p256_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Triple modulo p_256k1, z := (3 * x) mod p_256k1
|
||||
// Input x[4]; output z[4]
|
||||
extern void bignum_triple_p256k1 (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
extern void bignum_triple_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]);
|
||||
|
||||
// Triple modulo p_384, z := (3 * x) mod p_384
|
||||
// Input x[6]; output z[6]
|
||||
extern void bignum_triple_p384 (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
extern void bignum_triple_p384_alt (uint64_t z[static 6], uint64_t x[static 6]);
|
||||
|
||||
// Triple modulo p_521, z := (3 * x) mod p_521, assuming x reduced
|
||||
// Input x[9]; output z[9]
|
||||
extern void bignum_triple_p521 (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
extern void bignum_triple_p521_alt (uint64_t z[static 9], uint64_t x[static 9]);
|
||||
|
||||
// Montgomery ladder step for curve25519
|
||||
// Inputs point[8], pp[16], b; output rr[16]
|
||||
extern void curve25519_ladderstep(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b);
|
||||
extern void curve25519_ladderstep_alt(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b);
|
||||
|
||||
// Projective scalar multiplication, x coordinate only, for curve25519
|
||||
// Inputs scalar[4], point[4]; output res[8]
|
||||
extern void curve25519_pxscalarmul(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]);
|
||||
extern void curve25519_pxscalarmul_alt(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]);
|
||||
|
||||
// x25519 function for curve25519
|
||||
// Inputs scalar[4], point[4]; output res[4]
|
||||
extern void curve25519_x25519(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]);
|
||||
extern void curve25519_x25519_alt(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]);
|
||||
|
||||
// x25519 function for curve25519 on base element 9
|
||||
// Input scalar[4]; output res[4]
|
||||
extern void curve25519_x25519base(uint64_t res[static 4],uint64_t scalar[static 4]);
|
||||
extern void curve25519_x25519base_alt(uint64_t res[static 4],uint64_t scalar[static 4]);
|
||||
|
||||
// Extended projective addition for edwards25519
|
||||
// Inputs p1[16], p2[16]; output p3[16]
|
||||
extern void edwards25519_epadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]);
|
||||
extern void edwards25519_epadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]);
|
||||
|
||||
// Extended projective doubling for edwards25519
|
||||
// Inputs p1[12]; output p3[16]
|
||||
extern void edwards25519_epdouble(uint64_t p3[static 16],uint64_t p1[static 12]);
|
||||
extern void edwards25519_epdouble_alt(uint64_t p3[static 16],uint64_t p1[static 12]);
|
||||
|
||||
// Projective doubling for edwards25519
|
||||
// Inputs p1[12]; output p3[12]
|
||||
extern void edwards25519_pdouble(uint64_t p3[static 12],uint64_t p1[static 12]);
|
||||
extern void edwards25519_pdouble_alt(uint64_t p3[static 12],uint64_t p1[static 12]);
|
||||
|
||||
// Extended projective + precomputed mixed addition for edwards25519
|
||||
// Inputs p1[16], p2[12]; output p3[16]
|
||||
extern void edwards25519_pepadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]);
|
||||
extern void edwards25519_pepadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]);
|
||||
|
||||
// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates
|
||||
// Inputs p1[12], p2[12]; output p3[12]
|
||||
extern void p256_montjadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]);
|
||||
|
||||
// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates
|
||||
// Inputs p1[12]; output p3[12]
|
||||
extern void p256_montjdouble(uint64_t p3[static 12],uint64_t p1[static 12]);
|
||||
|
||||
// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates
|
||||
// Inputs p1[12], p2[8]; output p3[12]
|
||||
extern void p256_montjmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]);
|
||||
|
||||
// Point addition on NIST curve P-384 in Montgomery-Jacobian coordinates
|
||||
// Inputs p1[18], p2[18]; output p3[18]
|
||||
extern void p384_montjadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 18]);
|
||||
|
||||
// Point doubling on NIST curve P-384 in Montgomery-Jacobian coordinates
|
||||
// Inputs p1[18]; output p3[18]
|
||||
extern void p384_montjdouble(uint64_t p3[static 18],uint64_t p1[static 18]);
|
||||
|
||||
// Point mixed addition on NIST curve P-384 in Montgomery-Jacobian coordinates
|
||||
// Inputs p1[18], p2[12]; output p3[18]
|
||||
extern void p384_montjmixadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 12]);
|
||||
|
||||
// Point addition on NIST curve P-521 in Jacobian coordinates
|
||||
// Inputs p1[27], p2[27]; output p3[27]
|
||||
extern void p521_jadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 27]);
|
||||
|
||||
// Point doubling on NIST curve P-521 in Jacobian coordinates
|
||||
// Input p1[27]; output p3[27]
|
||||
extern void p521_jdouble(uint64_t p3[static 27],uint64_t p1[static 27]);
|
||||
|
||||
// Point mixed addition on NIST curve P-521 in Jacobian coordinates
|
||||
// Inputs p1[27], p2[18]; output p3[27]
|
||||
extern void p521_jmixadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 18]);
|
||||
|
||||
// Point addition on SECG curve secp256k1 in Jacobian coordinates
|
||||
// Inputs p1[12], p2[12]; output p3[12]
|
||||
extern void secp256k1_jadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]);
|
||||
|
||||
// Point doubling on SECG curve secp256k1 in Jacobian coordinates
|
||||
// Input p1[12]; output p3[12]
|
||||
extern void secp256k1_jdouble(uint64_t p3[static 12],uint64_t p1[static 12]);
|
||||
|
||||
// Point mixed addition on SECG curve secp256k1 in Jacobian coordinates
|
||||
// Inputs p1[12], p2[8]; output p3[12]
|
||||
extern void secp256k1_jmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]);
|
||||
|
||||
// Reverse the bytes in a single word
|
||||
// Input a; output function return
|
||||
extern uint64_t word_bytereverse (uint64_t a);
|
||||
|
||||
// Count leading zero bits in a single word
|
||||
// Input a; output function return
|
||||
extern uint64_t word_clz (uint64_t a);
|
||||
|
||||
// Count trailing zero bits in a single word
|
||||
// Input a; output function return
|
||||
extern uint64_t word_ctz (uint64_t a);
|
||||
|
||||
// Return maximum of two unsigned 64-bit words
|
||||
// Inputs a, b; output function return
|
||||
extern uint64_t word_max (uint64_t a, uint64_t b);
|
||||
|
||||
// Return minimum of two unsigned 64-bit words
|
||||
// Inputs a, b; output function return
|
||||
extern uint64_t word_min (uint64_t a, uint64_t b);
|
||||
|
||||
// Single-word negated modular inverse (-1/a) mod 2^64
|
||||
// Input a; output function return
|
||||
extern uint64_t word_negmodinv (uint64_t a);
|
||||
|
||||
// Single-word reciprocal, 2^64 + ret = ceil(2^128/a) - 1 if MSB of "a" is set
|
||||
// Input a; output function return
|
||||
extern uint64_t word_recip (uint64_t a);
|
||||
30
externals/libressl/crypto/bn/s2n_bignum_internal.h
vendored
Normal file
30
externals/libressl/crypto/bn/s2n_bignum_internal.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define S2N_BN_SYMBOL(NAME) _##NAME
|
||||
#else
|
||||
# define S2N_BN_SYMBOL(name) name
|
||||
#endif
|
||||
|
||||
#define S2N_BN_SYM_VISIBILITY_DIRECTIVE(name) .globl S2N_BN_SYMBOL(name)
|
||||
#ifdef S2N_BN_HIDE_SYMBOLS
|
||||
# ifdef __APPLE__
|
||||
# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) .private_extern S2N_BN_SYMBOL(name)
|
||||
# else
|
||||
# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) .hidden S2N_BN_SYMBOL(name)
|
||||
# endif
|
||||
#else
|
||||
# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) /* NO-OP: S2N_BN_SYM_PRIVACY_DIRECTIVE */
|
||||
#endif
|
||||
Reference in New Issue
Block a user