mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 19:43:32 +00:00
106 lines
4.7 KiB
C
106 lines
4.7 KiB
C
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||
|
│ Copyright The Mbed TLS Contributors │
|
||
|
│ │
|
||
|
│ Licensed under the Apache License, Version 2.0 (the "License"); │
|
||
|
│ you may not use this file except in compliance with the License. │
|
||
|
│ You may obtain a copy of the License at │
|
||
|
│ │
|
||
|
│ http://www.apache.org/licenses/LICENSE-2.0 │
|
||
|
│ │
|
||
|
│ Unless required by applicable law or agreed to in writing, software │
|
||
|
│ distributed under the License is distributed on an "AS IS" BASIS, │
|
||
|
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
|
||
|
│ See the License for the specific language governing permissions and │
|
||
|
│ limitations under the License. │
|
||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||
|
#include "third_party/mbedtls/ecp.h"
|
||
|
#include "third_party/mbedtls/math.h"
|
||
|
/* clang-format off */
|
||
|
|
||
|
static void mbedtls_mpi_shift_l_mod_p256( const mbedtls_ecp_group *G,
|
||
|
mbedtls_mpi *X )
|
||
|
{
|
||
|
bool c;
|
||
|
MBEDTLS_ASSERT( G->P.n == 4 );
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_bitlen( X ) <= 256 );
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_bitlen( &G->P ) <= 256 );
|
||
|
X->p[4] = X->p[3] >> 63;
|
||
|
X->p[3] = X->p[3] << 1 | X->p[2] >> 63;
|
||
|
X->p[2] = X->p[2] << 1 | X->p[1] >> 63;
|
||
|
X->p[1] = X->p[1] << 1 | X->p[0] >> 63;
|
||
|
X->p[0] = X->p[0] << 1;
|
||
|
if( (X->p[4] ||
|
||
|
X->p[3] > G->P.p[3] ||
|
||
|
(X->p[3] == G->P.p[3] &&
|
||
|
X->p[2] > G->P.p[2] ||
|
||
|
(X->p[2] == G->P.p[2] &&
|
||
|
X->p[0] > G->P.p[0] ||
|
||
|
(X->p[0] == G->P.p[0])))) )
|
||
|
{
|
||
|
SBB(X->p[0], X->p[0], G->P.p[0], 0, c);
|
||
|
SBB(X->p[1], X->p[1], G->P.p[1], c, c);
|
||
|
SBB(X->p[2], X->p[2], G->P.p[2], c, c);
|
||
|
SBB(X->p[3], X->p[3], G->P.p[3], c, c);
|
||
|
SBB(X->p[4], X->p[4], 0, c, c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void mbedtls_mpi_shift_l_mod_p384( const mbedtls_ecp_group *G,
|
||
|
mbedtls_mpi *X )
|
||
|
{
|
||
|
bool c;
|
||
|
MBEDTLS_ASSERT( G->P.n == 6 );
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_bitlen( X ) <= 384 );
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_bitlen( &G->P ) <= 384 );
|
||
|
X->p[6] = X->p[5] >> 63;
|
||
|
X->p[5] = X->p[5] << 1 | X->p[4] >> 63;
|
||
|
X->p[4] = X->p[4] << 1 | X->p[3] >> 63;
|
||
|
X->p[3] = X->p[3] << 1 | X->p[2] >> 63;
|
||
|
X->p[2] = X->p[2] << 1 | X->p[1] >> 63;
|
||
|
X->p[1] = X->p[1] << 1 | X->p[0] >> 63;
|
||
|
X->p[0] = X->p[0] << 1;
|
||
|
if( (X->p[6] ||
|
||
|
X->p[5] > G->P.p[5] ||
|
||
|
(X->p[5] == G->P.p[5] &&
|
||
|
X->p[4] > G->P.p[4] ||
|
||
|
(X->p[4] == G->P.p[4] &&
|
||
|
X->p[3] > G->P.p[3] ||
|
||
|
(X->p[3] == G->P.p[3] &&
|
||
|
X->p[2] > G->P.p[2] ||
|
||
|
(X->p[2] == G->P.p[2] &&
|
||
|
X->p[0] > G->P.p[0] ||
|
||
|
(X->p[0] == G->P.p[0])))))) )
|
||
|
{
|
||
|
SBB(X->p[0], X->p[0], G->P.p[0], 0, c);
|
||
|
SBB(X->p[1], X->p[1], G->P.p[1], c, c);
|
||
|
SBB(X->p[2], X->p[2], G->P.p[2], c, c);
|
||
|
SBB(X->p[3], X->p[3], G->P.p[3], c, c);
|
||
|
SBB(X->p[4], X->p[4], G->P.p[4], c, c);
|
||
|
SBB(X->p[5], X->p[5], G->P.p[5], c, c);
|
||
|
SBB(X->p[6], X->p[6], 0, c, c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int mbedtls_mpi_shift_l_mod( const mbedtls_ecp_group *G, mbedtls_mpi *X )
|
||
|
{
|
||
|
int ret = 0;
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_cmp_int( X, 0 ) >= 0 );
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_cmp_mpi( X, &G->P ) < 0 );
|
||
|
if( X->n == 8 )
|
||
|
mbedtls_mpi_shift_l_mod_p256( G, X );
|
||
|
else if( X->n == 12 )
|
||
|
mbedtls_mpi_shift_l_mod_p384( G, X );
|
||
|
else
|
||
|
{
|
||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, 1 ) );
|
||
|
if( mbedtls_mpi_cmp_mpi( X, &G->P ) >= 0 )
|
||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, X, &G->P ) );
|
||
|
}
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_cmp_mpi( X, &G->P ) < 0 );
|
||
|
MBEDTLS_ASSERT( mbedtls_mpi_cmp_int( X, 0 ) >= 0 );
|
||
|
cleanup:
|
||
|
return( ret );
|
||
|
}
|