jdk/src/share/native/sun/security/ec/mpi.c
author vinnie
Tue, 11 Aug 2009 16:52:26 +0100
changeset 3492 e549cea58864
permissions -rw-r--r--
6840752: Provide out-of-the-box support for ECC algorithms Reviewed-by: alanb, mullan, wetmore
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3492
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     1
/* *********************************************************************
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     2
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     3
 * Sun elects to have this file available under and governed by the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     4
 * Mozilla Public License Version 1.1 ("MPL") (see
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     5
 * http://www.mozilla.org/MPL/ for full license text). For the avoidance
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     6
 * of doubt and subject to the following, Sun also elects to allow
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     7
 * licensees to use this file under the MPL, the GNU General Public
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     8
 * License version 2 only or the Lesser General Public License version
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     9
 * 2.1 only. Any references to the "GNU General Public License version 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    10
 * or later" or "GPL" in the following shall be construed to mean the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    11
 * GNU General Public License version 2 only. Any references to the "GNU
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    12
 * Lesser General Public License version 2.1 or later" or "LGPL" in the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    13
 * following shall be construed to mean the GNU Lesser General Public
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    14
 * License version 2.1 only. However, the following notice accompanied
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    15
 * the original version of this file:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    16
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    17
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    18
 *  Arbitrary precision integer arithmetic library
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    19
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    20
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    21
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    22
 * The contents of this file are subject to the Mozilla Public License Version
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    23
 * 1.1 (the "License"); you may not use this file except in compliance with
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    24
 * the License. You may obtain a copy of the License at
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    25
 * http://www.mozilla.org/MPL/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    26
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    27
 * Software distributed under the License is distributed on an "AS IS" basis,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    28
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    29
 * for the specific language governing rights and limitations under the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    30
 * License.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    31
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    32
 * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    33
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    34
 * The Initial Developer of the Original Code is
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    35
 * Michael J. Fromberger.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    36
 * Portions created by the Initial Developer are Copyright (C) 1998
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    37
 * the Initial Developer. All Rights Reserved.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    38
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    39
 * Contributor(s):
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    40
 *   Netscape Communications Corporation
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    41
 *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    42
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    43
 * Alternatively, the contents of this file may be used under the terms of
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    44
 * either the GNU General Public License Version 2 or later (the "GPL"), or
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    45
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    46
 * in which case the provisions of the GPL or the LGPL are applicable instead
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    47
 * of those above. If you wish to allow use of your version of this file only
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    48
 * under the terms of either the GPL or the LGPL, and not to allow others to
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    49
 * use your version of this file under the terms of the MPL, indicate your
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    50
 * decision by deleting the provisions above and replace them with the notice
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    51
 * and other provisions required by the GPL or the LGPL. If you do not delete
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    52
 * the provisions above, a recipient may use your version of this file under
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    53
 * the terms of any one of the MPL, the GPL or the LGPL.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    54
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    55
 *********************************************************************** */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    56
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    57
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    58
 * Use is subject to license terms.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    59
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    60
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    61
#pragma ident   "%Z%%M% %I%     %E% SMI"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    62
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    63
/* $Id: mpi.c,v 1.45 2006/09/29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    64
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    65
#include "mpi-priv.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    66
#if defined(OSF1)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    67
#include <c_asm.h>
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    68
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    69
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    70
#if MP_LOGTAB
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    71
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    72
  A table of the logs of 2 for various bases (the 0 and 1 entries of
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    73
  this table are meaningless and should not be referenced).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    74
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    75
  This table is used to compute output lengths for the mp_toradix()
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    76
  function.  Since a number n in radix r takes up about log_r(n)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    77
  digits, we estimate the output size by taking the least integer
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    78
  greater than log_r(n), where:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    79
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    80
  log_r(n) = log_2(n) * log_r(2)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    81
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    82
  This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    83
  which are the output bases supported.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    84
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    85
#include "logtab.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    86
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    87
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    88
/* {{{ Constant strings */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    89
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    90
/* Constant strings returned by mp_strerror() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    91
static const char *mp_err_string[] = {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    92
  "unknown result code",     /* say what?            */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    93
  "boolean true",            /* MP_OKAY, MP_YES      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    94
  "boolean false",           /* MP_NO                */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    95
  "out of memory",           /* MP_MEM               */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    96
  "argument out of range",   /* MP_RANGE             */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    97
  "invalid input parameter", /* MP_BADARG            */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    98
  "result is undefined"      /* MP_UNDEF             */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    99
};
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   100
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   101
/* Value to digit maps for radix conversion   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   102
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   103
/* s_dmap_1 - standard digits and letters */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   104
static const char *s_dmap_1 =
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   105
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   106
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   107
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   108
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   109
unsigned long mp_allocs;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   110
unsigned long mp_frees;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   111
unsigned long mp_copies;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   112
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   113
/* {{{ Default precision manipulation */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   114
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   115
/* Default precision for newly created mp_int's      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   116
static mp_size s_mp_defprec = MP_DEFPREC;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   117
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   118
mp_size mp_get_prec(void)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   119
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   120
  return s_mp_defprec;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   121
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   122
} /* end mp_get_prec() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   123
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   124
void         mp_set_prec(mp_size prec)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   125
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   126
  if(prec == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   127
    s_mp_defprec = MP_DEFPREC;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   128
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   129
    s_mp_defprec = prec;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   130
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   131
} /* end mp_set_prec() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   132
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   133
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   134
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   135
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   136
/* {{{ mp_init(mp, kmflag) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   137
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   138
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   139
  mp_init(mp, kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   140
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   141
  Initialize a new zero-valued mp_int.  Returns MP_OKAY if successful,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   142
  MP_MEM if memory could not be allocated for the structure.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   143
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   144
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   145
mp_err mp_init(mp_int *mp, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   146
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   147
  return mp_init_size(mp, s_mp_defprec, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   148
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   149
} /* end mp_init() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   150
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   151
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   152
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   153
/* {{{ mp_init_size(mp, prec, kmflag) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   154
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   155
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   156
  mp_init_size(mp, prec, kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   157
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   158
  Initialize a new zero-valued mp_int with at least the given
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   159
  precision; returns MP_OKAY if successful, or MP_MEM if memory could
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   160
  not be allocated for the structure.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   161
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   162
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   163
mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   164
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   165
  ARGCHK(mp != NULL && prec > 0, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   166
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   167
  prec = MP_ROUNDUP(prec, s_mp_defprec);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   168
  if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit), kmflag)) == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   169
    return MP_MEM;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   170
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   171
  SIGN(mp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   172
  USED(mp) = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   173
  ALLOC(mp) = prec;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   174
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   175
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   176
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   177
} /* end mp_init_size() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   178
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   179
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   180
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   181
/* {{{ mp_init_copy(mp, from) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   182
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   183
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   184
  mp_init_copy(mp, from)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   185
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   186
  Initialize mp as an exact copy of from.  Returns MP_OKAY if
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   187
  successful, MP_MEM if memory could not be allocated for the new
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   188
  structure.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   189
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   190
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   191
mp_err mp_init_copy(mp_int *mp, const mp_int *from)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   192
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   193
  ARGCHK(mp != NULL && from != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   194
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   195
  if(mp == from)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   196
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   197
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   198
  if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   199
    return MP_MEM;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   200
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   201
  s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   202
  USED(mp) = USED(from);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   203
  ALLOC(mp) = ALLOC(from);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   204
  SIGN(mp) = SIGN(from);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   205
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   206
#ifndef _WIN32
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   207
  FLAG(mp) = FLAG(from);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   208
#endif /* _WIN32 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   209
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   210
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   211
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   212
} /* end mp_init_copy() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   213
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   214
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   215
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   216
/* {{{ mp_copy(from, to) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   217
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   218
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   219
  mp_copy(from, to)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   220
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   221
  Copies the mp_int 'from' to the mp_int 'to'.  It is presumed that
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   222
  'to' has already been initialized (if not, use mp_init_copy()
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   223
  instead). If 'from' and 'to' are identical, nothing happens.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   224
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   225
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   226
mp_err mp_copy(const mp_int *from, mp_int *to)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   227
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   228
  ARGCHK(from != NULL && to != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   229
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   230
  if(from == to)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   231
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   232
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   233
  ++mp_copies;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   234
  { /* copy */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   235
    mp_digit   *tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   236
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   237
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   238
      If the allocated buffer in 'to' already has enough space to hold
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   239
      all the used digits of 'from', we'll re-use it to avoid hitting
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   240
      the memory allocater more than necessary; otherwise, we'd have
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   241
      to grow anyway, so we just allocate a hunk and make the copy as
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   242
      usual
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   243
     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   244
    if(ALLOC(to) >= USED(from)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   245
      s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   246
      s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   247
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   248
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   249
      if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   250
        return MP_MEM;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   251
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   252
      s_mp_copy(DIGITS(from), tmp, USED(from));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   253
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   254
      if(DIGITS(to) != NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   255
#if MP_CRYPTO
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   256
        s_mp_setz(DIGITS(to), ALLOC(to));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   257
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   258
        s_mp_free(DIGITS(to), ALLOC(to));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   259
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   260
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   261
      DIGITS(to) = tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   262
      ALLOC(to) = ALLOC(from);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   263
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   264
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   265
    /* Copy the precision and sign from the original */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   266
    USED(to) = USED(from);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   267
    SIGN(to) = SIGN(from);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   268
  } /* end copy */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   269
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   270
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   271
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   272
} /* end mp_copy() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   273
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   274
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   275
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   276
/* {{{ mp_exch(mp1, mp2) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   277
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   278
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   279
  mp_exch(mp1, mp2)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   280
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   281
  Exchange mp1 and mp2 without allocating any intermediate memory
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   282
  (well, unless you count the stack space needed for this call and the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   283
  locals it creates...).  This cannot fail.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   284
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   285
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   286
void mp_exch(mp_int *mp1, mp_int *mp2)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   287
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   288
#if MP_ARGCHK == 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   289
  assert(mp1 != NULL && mp2 != NULL);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   290
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   291
  if(mp1 == NULL || mp2 == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   292
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   293
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   294
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   295
  s_mp_exch(mp1, mp2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   296
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   297
} /* end mp_exch() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   298
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   299
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   300
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   301
/* {{{ mp_clear(mp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   302
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   303
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   304
  mp_clear(mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   305
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   306
  Release the storage used by an mp_int, and void its fields so that
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   307
  if someone calls mp_clear() again for the same int later, we won't
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   308
  get tollchocked.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   309
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   310
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   311
void   mp_clear(mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   312
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   313
  if(mp == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   314
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   315
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   316
  if(DIGITS(mp) != NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   317
#if MP_CRYPTO
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   318
    s_mp_setz(DIGITS(mp), ALLOC(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   319
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   320
    s_mp_free(DIGITS(mp), ALLOC(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   321
    DIGITS(mp) = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   322
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   323
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   324
  USED(mp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   325
  ALLOC(mp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   326
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   327
} /* end mp_clear() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   328
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   329
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   330
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   331
/* {{{ mp_zero(mp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   332
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   333
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   334
  mp_zero(mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   335
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   336
  Set mp to zero.  Does not change the allocated size of the structure,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   337
  and therefore cannot fail (except on a bad argument, which we ignore)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   338
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   339
void   mp_zero(mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   340
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   341
  if(mp == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   342
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   343
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   344
  s_mp_setz(DIGITS(mp), ALLOC(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   345
  USED(mp) = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   346
  SIGN(mp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   347
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   348
} /* end mp_zero() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   349
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   350
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   351
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   352
/* {{{ mp_set(mp, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   353
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   354
void   mp_set(mp_int *mp, mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   355
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   356
  if(mp == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   357
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   358
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   359
  mp_zero(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   360
  DIGIT(mp, 0) = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   361
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   362
} /* end mp_set() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   363
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   364
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   365
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   366
/* {{{ mp_set_int(mp, z) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   367
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   368
mp_err mp_set_int(mp_int *mp, long z)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   369
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   370
  int            ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   371
  unsigned long  v = labs(z);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   372
  mp_err         res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   373
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   374
  ARGCHK(mp != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   375
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   376
  mp_zero(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   377
  if(z == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   378
    return MP_OKAY;  /* shortcut for zero */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   379
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   380
  if (sizeof v <= sizeof(mp_digit)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   381
    DIGIT(mp,0) = v;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   382
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   383
    for (ix = sizeof(long) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   384
      if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   385
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   386
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   387
      res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   388
      if (res != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   389
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   390
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   391
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   392
  if(z < 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   393
    SIGN(mp) = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   394
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   395
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   396
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   397
} /* end mp_set_int() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   398
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   399
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   400
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   401
/* {{{ mp_set_ulong(mp, z) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   402
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   403
mp_err mp_set_ulong(mp_int *mp, unsigned long z)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   404
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   405
  int            ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   406
  mp_err         res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   407
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   408
  ARGCHK(mp != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   409
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   410
  mp_zero(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   411
  if(z == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   412
    return MP_OKAY;  /* shortcut for zero */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   413
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   414
  if (sizeof z <= sizeof(mp_digit)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   415
    DIGIT(mp,0) = z;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   416
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   417
    for (ix = sizeof(long) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   418
      if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   419
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   420
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   421
      res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   422
      if (res != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   423
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   424
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   425
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   426
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   427
} /* end mp_set_ulong() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   428
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   429
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   430
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   431
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   432
/* {{{ Digit arithmetic */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   433
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   434
/* {{{ mp_add_d(a, d, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   435
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   436
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   437
  mp_add_d(a, d, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   438
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   439
  Compute the sum b = a + d, for a single digit d.  Respects the sign of
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   440
  its primary addend (single digits are unsigned anyway).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   441
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   442
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   443
mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   444
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   445
  mp_int   tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   446
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   447
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   448
  ARGCHK(a != NULL && b != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   449
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   450
  if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   451
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   452
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   453
  if(SIGN(&tmp) == ZPOS) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   454
    if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   455
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   456
  } else if(s_mp_cmp_d(&tmp, d) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   457
    if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   458
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   459
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   460
    mp_neg(&tmp, &tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   461
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   462
    DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   463
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   464
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   465
  if(s_mp_cmp_d(&tmp, 0) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   466
    SIGN(&tmp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   467
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   468
  s_mp_exch(&tmp, b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   469
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   470
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   471
  mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   472
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   473
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   474
} /* end mp_add_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   475
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   476
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   477
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   478
/* {{{ mp_sub_d(a, d, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   479
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   480
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   481
  mp_sub_d(a, d, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   482
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   483
  Compute the difference b = a - d, for a single digit d.  Respects the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   484
  sign of its subtrahend (single digits are unsigned anyway).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   485
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   486
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   487
mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   488
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   489
  mp_int   tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   490
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   491
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   492
  ARGCHK(a != NULL && b != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   493
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   494
  if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   495
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   496
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   497
  if(SIGN(&tmp) == NEG) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   498
    if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   499
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   500
  } else if(s_mp_cmp_d(&tmp, d) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   501
    if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   502
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   503
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   504
    mp_neg(&tmp, &tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   505
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   506
    DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   507
    SIGN(&tmp) = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   508
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   509
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   510
  if(s_mp_cmp_d(&tmp, 0) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   511
    SIGN(&tmp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   512
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   513
  s_mp_exch(&tmp, b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   514
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   515
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   516
  mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   517
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   518
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   519
} /* end mp_sub_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   520
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   521
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   522
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   523
/* {{{ mp_mul_d(a, d, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   524
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   525
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   526
  mp_mul_d(a, d, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   527
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   528
  Compute the product b = a * d, for a single digit d.  Respects the sign
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   529
  of its multiplicand (single digits are unsigned anyway)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   530
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   531
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   532
mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   533
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   534
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   535
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   536
  ARGCHK(a != NULL && b != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   537
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   538
  if(d == 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   539
    mp_zero(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   540
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   541
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   542
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   543
  if((res = mp_copy(a, b)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   544
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   545
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   546
  res = s_mp_mul_d(b, d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   547
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   548
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   549
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   550
} /* end mp_mul_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   551
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   552
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   553
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   554
/* {{{ mp_mul_2(a, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   555
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   556
mp_err mp_mul_2(const mp_int *a, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   557
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   558
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   559
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   560
  ARGCHK(a != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   561
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   562
  if((res = mp_copy(a, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   563
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   564
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   565
  return s_mp_mul_2(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   566
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   567
} /* end mp_mul_2() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   568
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   569
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   570
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   571
/* {{{ mp_div_d(a, d, q, r) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   572
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   573
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   574
  mp_div_d(a, d, q, r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   575
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   576
  Compute the quotient q = a / d and remainder r = a mod d, for a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   577
  single digit d.  Respects the sign of its divisor (single digits are
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   578
  unsigned anyway).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   579
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   580
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   581
mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   582
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   583
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   584
  mp_int   qp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   585
  mp_digit rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   586
  int      pow;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   587
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   588
  ARGCHK(a != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   589
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   590
  if(d == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   591
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   592
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   593
  /* Shortcut for powers of two ... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   594
  if((pow = s_mp_ispow2d(d)) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   595
    mp_digit  mask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   596
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   597
    mask = ((mp_digit)1 << pow) - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   598
    rem = DIGIT(a, 0) & mask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   599
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   600
    if(q) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   601
      mp_copy(a, q);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   602
      s_mp_div_2d(q, pow);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   603
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   604
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   605
    if(r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   606
      *r = rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   607
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   608
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   609
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   610
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   611
  if((res = mp_init_copy(&qp, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   612
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   613
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   614
  res = s_mp_div_d(&qp, d, &rem);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   615
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   616
  if(s_mp_cmp_d(&qp, 0) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   617
    SIGN(q) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   618
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   619
  if(r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   620
    *r = rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   621
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   622
  if(q)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   623
    s_mp_exch(&qp, q);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   624
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   625
  mp_clear(&qp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   626
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   627
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   628
} /* end mp_div_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   629
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   630
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   631
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   632
/* {{{ mp_div_2(a, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   633
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   634
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   635
  mp_div_2(a, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   636
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   637
  Compute c = a / 2, disregarding the remainder.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   638
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   639
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   640
mp_err mp_div_2(const mp_int *a, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   641
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   642
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   643
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   644
  ARGCHK(a != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   645
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   646
  if((res = mp_copy(a, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   647
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   648
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   649
  s_mp_div_2(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   650
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   651
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   652
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   653
} /* end mp_div_2() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   654
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   655
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   656
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   657
/* {{{ mp_expt_d(a, d, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   658
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   659
mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   660
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   661
  mp_int   s, x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   662
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   663
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   664
  ARGCHK(a != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   665
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   666
  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   667
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   668
  if((res = mp_init_copy(&x, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   669
    goto X;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   670
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   671
  DIGIT(&s, 0) = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   672
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   673
  while(d != 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   674
    if(d & 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   675
      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   676
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   677
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   678
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   679
    d /= 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   680
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   681
    if((res = s_mp_sqr(&x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   682
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   683
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   684
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   685
  s_mp_exch(&s, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   686
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   687
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   688
  mp_clear(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   689
X:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   690
  mp_clear(&s);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   691
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   692
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   693
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   694
} /* end mp_expt_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   695
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   696
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   697
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   698
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   699
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   700
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   701
/* {{{ Full arithmetic */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   702
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   703
/* {{{ mp_abs(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   704
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   705
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   706
  mp_abs(a, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   707
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   708
  Compute b = |a|.  'a' and 'b' may be identical.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   709
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   710
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   711
mp_err mp_abs(const mp_int *a, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   712
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   713
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   714
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   715
  ARGCHK(a != NULL && b != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   716
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   717
  if((res = mp_copy(a, b)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   718
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   719
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   720
  SIGN(b) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   721
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   722
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   723
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   724
} /* end mp_abs() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   725
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   726
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   727
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   728
/* {{{ mp_neg(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   729
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   730
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   731
  mp_neg(a, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   732
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   733
  Compute b = -a.  'a' and 'b' may be identical.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   734
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   735
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   736
mp_err mp_neg(const mp_int *a, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   737
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   738
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   739
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   740
  ARGCHK(a != NULL && b != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   741
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   742
  if((res = mp_copy(a, b)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   743
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   744
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   745
  if(s_mp_cmp_d(b, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   746
    SIGN(b) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   747
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   748
    SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   749
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   750
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   751
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   752
} /* end mp_neg() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   753
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   754
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   755
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   756
/* {{{ mp_add(a, b, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   757
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   758
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   759
  mp_add(a, b, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   760
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   761
  Compute c = a + b.  All parameters may be identical.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   762
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   763
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   764
mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   765
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   766
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   767
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   768
  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   769
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   770
  if(SIGN(a) == SIGN(b)) { /* same sign:  add values, keep sign */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   771
    MP_CHECKOK( s_mp_add_3arg(a, b, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   772
  } else if(s_mp_cmp(a, b) >= 0) {  /* different sign: |a| >= |b|   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   773
    MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   774
  } else {                          /* different sign: |a|  < |b|   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   775
    MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   776
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   777
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   778
  if (s_mp_cmp_d(c, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   779
    SIGN(c) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   780
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   781
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   782
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   783
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   784
} /* end mp_add() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   785
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   786
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   787
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   788
/* {{{ mp_sub(a, b, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   789
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   790
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   791
  mp_sub(a, b, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   792
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   793
  Compute c = a - b.  All parameters may be identical.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   794
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   795
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   796
mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   797
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   798
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   799
  int     magDiff;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   800
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   801
  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   802
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   803
  if (a == b) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   804
    mp_zero(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   805
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   806
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   807
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   808
  if (MP_SIGN(a) != MP_SIGN(b)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   809
    MP_CHECKOK( s_mp_add_3arg(a, b, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   810
  } else if (!(magDiff = s_mp_cmp(a, b))) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   811
    mp_zero(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   812
    res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   813
  } else if (magDiff > 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   814
    MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   815
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   816
    MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   817
    MP_SIGN(c) = !MP_SIGN(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   818
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   819
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   820
  if (s_mp_cmp_d(c, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   821
    MP_SIGN(c) = MP_ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   822
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   823
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   824
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   825
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   826
} /* end mp_sub() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   827
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   828
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   829
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   830
/* {{{ mp_mul(a, b, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   831
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   832
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   833
  mp_mul(a, b, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   834
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   835
  Compute c = a * b.  All parameters may be identical.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   836
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   837
mp_err   mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   838
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   839
  mp_digit *pb;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   840
  mp_int   tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   841
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   842
  mp_size  ib;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   843
  mp_size  useda, usedb;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   844
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   845
  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   846
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   847
  if (a == c) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   848
    if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   849
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   850
    if (a == b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   851
      b = &tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   852
    a = &tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   853
  } else if (b == c) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   854
    if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   855
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   856
    b = &tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   857
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   858
    MP_DIGITS(&tmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   859
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   860
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   861
  if (MP_USED(a) < MP_USED(b)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   862
    const mp_int *xch = b;      /* switch a and b, to do fewer outer loops */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   863
    b = a;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   864
    a = xch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   865
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   866
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   867
  MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   868
  if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   869
    goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   870
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   871
#ifdef NSS_USE_COMBA
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   872
  if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   873
      if (MP_USED(a) == 4) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   874
          s_mp_mul_comba_4(a, b, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   875
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   876
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   877
      if (MP_USED(a) == 8) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   878
          s_mp_mul_comba_8(a, b, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   879
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   880
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   881
      if (MP_USED(a) == 16) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   882
          s_mp_mul_comba_16(a, b, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   883
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   884
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   885
      if (MP_USED(a) == 32) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   886
          s_mp_mul_comba_32(a, b, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   887
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   888
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   889
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   890
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   891
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   892
  pb = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   893
  s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   894
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   895
  /* Outer loop:  Digits of b */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   896
  useda = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   897
  usedb = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   898
  for (ib = 1; ib < usedb; ib++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   899
    mp_digit b_i    = *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   900
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   901
    /* Inner product:  Digits of a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   902
    if (b_i)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   903
      s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   904
    else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   905
      MP_DIGIT(c, ib + useda) = b_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   906
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   907
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   908
  s_mp_clamp(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   909
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   910
  if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   911
    SIGN(c) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   912
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   913
    SIGN(c) = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   914
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   915
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   916
  mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   917
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   918
} /* end mp_mul() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   919
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   920
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   921
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   922
/* {{{ mp_sqr(a, sqr) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   923
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   924
#if MP_SQUARE
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   925
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   926
  Computes the square of a.  This can be done more
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   927
  efficiently than a general multiplication, because many of the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   928
  computation steps are redundant when squaring.  The inner product
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   929
  step is a bit more complicated, but we save a fair number of
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   930
  iterations of the multiplication loop.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   931
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   932
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   933
/* sqr = a^2;   Caller provides both a and tmp; */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   934
mp_err   mp_sqr(const mp_int *a, mp_int *sqr)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   935
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   936
  mp_digit *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   937
  mp_digit d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   938
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   939
  mp_size  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   940
  mp_int   tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   941
  int      count;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   942
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   943
  ARGCHK(a != NULL && sqr != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   944
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   945
  if (a == sqr) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   946
    if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   947
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   948
    a = &tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   949
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   950
    DIGITS(&tmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   951
    res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   952
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   953
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   954
  ix = 2 * MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   955
  if (ix > MP_ALLOC(sqr)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   956
    MP_USED(sqr) = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   957
    MP_CHECKOK( s_mp_grow(sqr, ix) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   958
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   959
  MP_USED(sqr) = ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   960
  MP_DIGIT(sqr, 0) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   961
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   962
#ifdef NSS_USE_COMBA
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   963
  if (IS_POWER_OF_2(MP_USED(a))) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   964
      if (MP_USED(a) == 4) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   965
          s_mp_sqr_comba_4(a, sqr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   966
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   967
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   968
      if (MP_USED(a) == 8) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   969
          s_mp_sqr_comba_8(a, sqr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   970
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   971
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   972
      if (MP_USED(a) == 16) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   973
          s_mp_sqr_comba_16(a, sqr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   974
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   975
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   976
      if (MP_USED(a) == 32) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   977
          s_mp_sqr_comba_32(a, sqr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   978
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   979
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   980
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   981
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   982
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   983
  pa = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   984
  count = MP_USED(a) - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   985
  if (count > 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   986
    d = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   987
    s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   988
    for (ix = 3; --count > 0; ix += 2) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   989
      d = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   990
      s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   991
    } /* for(ix ...) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   992
    MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   993
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   994
    /* now sqr *= 2 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   995
    s_mp_mul_2(sqr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   996
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   997
    MP_DIGIT(sqr, 1) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   998
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   999
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1000
  /* now add the squares of the digits of a to sqr. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1001
  s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1002
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1003
  SIGN(sqr) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1004
  s_mp_clamp(sqr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1005
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1006
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1007
  mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1008
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1009
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1010
} /* end mp_sqr() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1011
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1012
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1013
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1014
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1015
/* {{{ mp_div(a, b, q, r) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1016
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1017
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1018
  mp_div(a, b, q, r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1019
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1020
  Compute q = a / b and r = a mod b.  Input parameters may be re-used
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1021
  as output parameters.  If q or r is NULL, that portion of the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1022
  computation will be discarded (although it will still be computed)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1023
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1024
mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1025
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1026
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1027
  mp_int   *pQ, *pR;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1028
  mp_int   qtmp, rtmp, btmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1029
  int      cmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1030
  mp_sign  signA;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1031
  mp_sign  signB;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1032
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1033
  ARGCHK(a != NULL && b != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1034
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1035
  signA = MP_SIGN(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1036
  signB = MP_SIGN(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1037
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1038
  if(mp_cmp_z(b) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1039
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1040
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1041
  DIGITS(&qtmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1042
  DIGITS(&rtmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1043
  DIGITS(&btmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1044
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1045
  /* Set up some temporaries... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1046
  if (!r || r == a || r == b) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1047
    MP_CHECKOK( mp_init_copy(&rtmp, a) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1048
    pR = &rtmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1049
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1050
    MP_CHECKOK( mp_copy(a, r) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1051
    pR = r;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1052
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1053
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1054
  if (!q || q == a || q == b) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1055
    MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a), FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1056
    pQ = &qtmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1057
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1058
    MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1059
    pQ = q;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1060
    mp_zero(pQ);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1061
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1062
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1063
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1064
    If |a| <= |b|, we can compute the solution without division;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1065
    otherwise, we actually do the work required.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1066
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1067
  if ((cmp = s_mp_cmp(a, b)) <= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1068
    if (cmp) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1069
      /* r was set to a above. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1070
      mp_zero(pQ);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1071
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1072
      mp_set(pQ, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1073
      mp_zero(pR);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1074
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1075
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1076
    MP_CHECKOK( mp_init_copy(&btmp, b) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1077
    MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1078
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1079
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1080
  /* Compute the signs for the output  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1081
  MP_SIGN(pR) = signA;   /* Sr = Sa              */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1082
  /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1083
  MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1084
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1085
  if(s_mp_cmp_d(pQ, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1086
    SIGN(pQ) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1087
  if(s_mp_cmp_d(pR, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1088
    SIGN(pR) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1089
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1090
  /* Copy output, if it is needed      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1091
  if(q && q != pQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1092
    s_mp_exch(pQ, q);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1093
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1094
  if(r && r != pR)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1095
    s_mp_exch(pR, r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1096
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1097
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1098
  mp_clear(&btmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1099
  mp_clear(&rtmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1100
  mp_clear(&qtmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1101
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1102
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1103
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1104
} /* end mp_div() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1105
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1106
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1107
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1108
/* {{{ mp_div_2d(a, d, q, r) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1109
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1110
mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1111
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1112
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1113
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1114
  ARGCHK(a != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1115
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1116
  if(q) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1117
    if((res = mp_copy(a, q)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1118
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1119
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1120
  if(r) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1121
    if((res = mp_copy(a, r)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1122
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1123
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1124
  if(q) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1125
    s_mp_div_2d(q, d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1126
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1127
  if(r) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1128
    s_mp_mod_2d(r, d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1129
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1130
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1131
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1132
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1133
} /* end mp_div_2d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1134
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1135
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1136
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1137
/* {{{ mp_expt(a, b, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1138
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1139
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1140
  mp_expt(a, b, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1141
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1142
  Compute c = a ** b, that is, raise a to the b power.  Uses a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1143
  standard iterative square-and-multiply technique.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1144
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1145
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1146
mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1147
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1148
  mp_int   s, x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1149
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1150
  mp_digit d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1151
  int      dig, bit;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1152
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1153
  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1154
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1155
  if(mp_cmp_z(b) < 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1156
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1157
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1158
  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1159
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1160
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1161
  mp_set(&s, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1162
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1163
  if((res = mp_init_copy(&x, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1164
    goto X;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1165
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1166
  /* Loop over low-order digits in ascending order */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1167
  for(dig = 0; dig < (USED(b) - 1); dig++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1168
    d = DIGIT(b, dig);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1169
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1170
    /* Loop over bits of each non-maximal digit */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1171
    for(bit = 0; bit < DIGIT_BIT; bit++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1172
      if(d & 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1173
        if((res = s_mp_mul(&s, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1174
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1175
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1176
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1177
      d >>= 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1178
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1179
      if((res = s_mp_sqr(&x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1180
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1181
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1182
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1183
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1184
  /* Consider now the last digit... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1185
  d = DIGIT(b, dig);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1186
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1187
  while(d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1188
    if(d & 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1189
      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1190
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1191
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1192
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1193
    d >>= 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1194
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1195
    if((res = s_mp_sqr(&x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1196
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1197
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1198
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1199
  if(mp_iseven(b))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1200
    SIGN(&s) = SIGN(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1201
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1202
  res = mp_copy(&s, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1203
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1204
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1205
  mp_clear(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1206
X:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1207
  mp_clear(&s);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1208
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1209
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1210
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1211
} /* end mp_expt() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1212
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1213
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1214
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1215
/* {{{ mp_2expt(a, k) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1216
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1217
/* Compute a = 2^k */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1218
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1219
mp_err mp_2expt(mp_int *a, mp_digit k)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1220
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1221
  ARGCHK(a != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1222
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1223
  return s_mp_2expt(a, k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1224
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1225
} /* end mp_2expt() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1226
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1227
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1228
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1229
/* {{{ mp_mod(a, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1230
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1231
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1232
  mp_mod(a, m, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1233
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1234
  Compute c = a (mod m).  Result will always be 0 <= c < m.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1235
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1236
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1237
mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1238
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1239
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1240
  int     mag;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1241
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1242
  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1243
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1244
  if(SIGN(m) == NEG)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1245
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1246
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1247
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1248
     If |a| > m, we need to divide to get the remainder and take the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1249
     absolute value.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1250
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1251
     If |a| < m, we don't need to do any division, just copy and adjust
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1252
     the sign (if a is negative).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1253
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1254
     If |a| == m, we can simply set the result to zero.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1255
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1256
     This order is intended to minimize the average path length of the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1257
     comparison chain on common workloads -- the most frequent cases are
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1258
     that |a| != m, so we do those first.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1259
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1260
  if((mag = s_mp_cmp(a, m)) > 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1261
    if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1262
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1263
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1264
    if(SIGN(c) == NEG) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1265
      if((res = mp_add(c, m, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1266
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1267
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1268
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1269
  } else if(mag < 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1270
    if((res = mp_copy(a, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1271
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1272
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1273
    if(mp_cmp_z(a) < 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1274
      if((res = mp_add(c, m, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1275
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1276
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1277
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1278
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1279
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1280
    mp_zero(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1281
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1282
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1283
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1284
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1285
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1286
} /* end mp_mod() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1287
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1288
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1289
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1290
/* {{{ mp_mod_d(a, d, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1291
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1292
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1293
  mp_mod_d(a, d, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1294
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1295
  Compute c = a (mod d).  Result will always be 0 <= c < d
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1296
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1297
mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1298
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1299
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1300
  mp_digit rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1301
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1302
  ARGCHK(a != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1303
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1304
  if(s_mp_cmp_d(a, d) > 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1305
    if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1306
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1307
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1308
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1309
    if(SIGN(a) == NEG)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1310
      rem = d - DIGIT(a, 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1311
    else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1312
      rem = DIGIT(a, 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1313
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1314
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1315
  if(c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1316
    *c = rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1317
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1318
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1319
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1320
} /* end mp_mod_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1321
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1322
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1323
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1324
/* {{{ mp_sqrt(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1325
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1326
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1327
  mp_sqrt(a, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1328
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1329
  Compute the integer square root of a, and store the result in b.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1330
  Uses an integer-arithmetic version of Newton's iterative linear
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1331
  approximation technique to determine this value; the result has the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1332
  following two properties:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1333
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1334
     b^2 <= a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1335
     (b+1)^2 >= a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1336
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1337
  It is a range error to pass a negative value.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1338
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1339
mp_err mp_sqrt(const mp_int *a, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1340
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1341
  mp_int   x, t;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1342
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1343
  mp_size  used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1344
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1345
  ARGCHK(a != NULL && b != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1346
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1347
  /* Cannot take square root of a negative value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1348
  if(SIGN(a) == NEG)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1349
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1350
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1351
  /* Special cases for zero and one, trivial     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1352
  if(mp_cmp_d(a, 1) <= 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1353
    return mp_copy(a, b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1354
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1355
  /* Initialize the temporaries we'll use below  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1356
  if((res = mp_init_size(&t, USED(a), FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1357
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1358
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1359
  /* Compute an initial guess for the iteration as a itself */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1360
  if((res = mp_init_copy(&x, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1361
    goto X;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1362
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1363
  used = MP_USED(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1364
  if (used > 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1365
    s_mp_rshd(&x, used / 2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1366
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1367
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1368
  for(;;) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1369
    /* t = (x * x) - a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1370
    mp_copy(&x, &t);      /* can't fail, t is big enough for original x */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1371
    if((res = mp_sqr(&t, &t)) != MP_OKAY ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1372
       (res = mp_sub(&t, a, &t)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1373
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1374
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1375
    /* t = t / 2x       */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1376
    s_mp_mul_2(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1377
    if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1378
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1379
    s_mp_div_2(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1380
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1381
    /* Terminate the loop, if the quotient is zero */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1382
    if(mp_cmp_z(&t) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1383
      break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1384
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1385
    /* x = x - t       */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1386
    if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1387
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1388
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1389
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1390
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1391
  /* Copy result to output parameter */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1392
  mp_sub_d(&x, 1, &x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1393
  s_mp_exch(&x, b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1394
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1395
 CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1396
  mp_clear(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1397
 X:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1398
  mp_clear(&t);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1399
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1400
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1401
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1402
} /* end mp_sqrt() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1403
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1404
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1405
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1406
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1407
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1408
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1409
/* {{{ Modular arithmetic */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1410
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1411
#if MP_MODARITH
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1412
/* {{{ mp_addmod(a, b, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1413
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1414
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1415
  mp_addmod(a, b, m, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1416
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1417
  Compute c = (a + b) mod m
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1418
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1419
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1420
mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1421
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1422
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1423
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1424
  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1425
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1426
  if((res = mp_add(a, b, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1427
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1428
  if((res = mp_mod(c, m, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1429
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1430
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1431
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1432
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1433
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1434
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1435
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1436
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1437
/* {{{ mp_submod(a, b, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1438
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1439
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1440
  mp_submod(a, b, m, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1441
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1442
  Compute c = (a - b) mod m
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1443
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1444
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1445
mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1446
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1447
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1448
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1449
  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1450
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1451
  if((res = mp_sub(a, b, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1452
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1453
  if((res = mp_mod(c, m, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1454
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1455
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1456
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1457
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1458
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1459
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1460
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1461
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1462
/* {{{ mp_mulmod(a, b, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1463
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1464
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1465
  mp_mulmod(a, b, m, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1466
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1467
  Compute c = (a * b) mod m
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1468
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1469
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1470
mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1471
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1472
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1473
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1474
  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1475
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1476
  if((res = mp_mul(a, b, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1477
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1478
  if((res = mp_mod(c, m, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1479
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1480
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1481
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1482
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1483
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1484
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1485
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1486
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1487
/* {{{ mp_sqrmod(a, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1488
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1489
#if MP_SQUARE
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1490
mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1491
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1492
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1493
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1494
  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1495
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1496
  if((res = mp_sqr(a, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1497
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1498
  if((res = mp_mod(c, m, c)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1499
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1500
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1501
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1502
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1503
} /* end mp_sqrmod() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1504
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1505
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1506
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1507
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1508
/* {{{ s_mp_exptmod(a, b, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1509
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1510
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1511
  s_mp_exptmod(a, b, m, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1512
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1513
  Compute c = (a ** b) mod m.  Uses a standard square-and-multiply
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1514
  method with modular reductions at each step. (This is basically the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1515
  same code as mp_expt(), except for the addition of the reductions)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1516
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1517
  The modular reductions are done using Barrett's algorithm (see
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1518
  s_mp_reduce() below for details)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1519
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1520
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1521
mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1522
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1523
  mp_int   s, x, mu;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1524
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1525
  mp_digit d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1526
  int      dig, bit;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1527
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1528
  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1529
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1530
  if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1531
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1532
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1533
  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1534
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1535
  if((res = mp_init_copy(&x, a)) != MP_OKAY ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1536
     (res = mp_mod(&x, m, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1537
    goto X;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1538
  if((res = mp_init(&mu, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1539
    goto MU;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1540
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1541
  mp_set(&s, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1542
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1543
  /* mu = b^2k / m */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1544
  s_mp_add_d(&mu, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1545
  s_mp_lshd(&mu, 2 * USED(m));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1546
  if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1547
    goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1548
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1549
  /* Loop over digits of b in ascending order, except highest order */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1550
  for(dig = 0; dig < (USED(b) - 1); dig++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1551
    d = DIGIT(b, dig);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1552
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1553
    /* Loop over the bits of the lower-order digits */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1554
    for(bit = 0; bit < DIGIT_BIT; bit++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1555
      if(d & 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1556
        if((res = s_mp_mul(&s, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1557
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1558
        if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1559
          goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1560
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1561
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1562
      d >>= 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1563
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1564
      if((res = s_mp_sqr(&x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1565
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1566
      if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1567
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1568
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1569
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1570
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1571
  /* Now do the last digit... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1572
  d = DIGIT(b, dig);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1573
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1574
  while(d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1575
    if(d & 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1576
      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1577
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1578
      if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1579
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1580
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1581
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1582
    d >>= 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1583
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1584
    if((res = s_mp_sqr(&x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1585
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1586
    if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1587
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1588
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1589
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1590
  s_mp_exch(&s, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1591
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1592
 CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1593
  mp_clear(&mu);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1594
 MU:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1595
  mp_clear(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1596
 X:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1597
  mp_clear(&s);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1598
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1599
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1600
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1601
} /* end s_mp_exptmod() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1602
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1603
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1604
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1605
/* {{{ mp_exptmod_d(a, d, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1606
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1607
mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1608
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1609
  mp_int   s, x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1610
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1611
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1612
  ARGCHK(a != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1613
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1614
  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1615
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1616
  if((res = mp_init_copy(&x, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1617
    goto X;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1618
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1619
  mp_set(&s, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1620
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1621
  while(d != 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1622
    if(d & 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1623
      if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1624
         (res = mp_mod(&s, m, &s)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1625
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1626
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1627
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1628
    d /= 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1629
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1630
    if((res = s_mp_sqr(&x)) != MP_OKAY ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1631
       (res = mp_mod(&x, m, &x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1632
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1633
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1634
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1635
  s_mp_exch(&s, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1636
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1637
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1638
  mp_clear(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1639
X:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1640
  mp_clear(&s);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1641
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1642
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1643
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1644
} /* end mp_exptmod_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1645
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1646
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1647
#endif /* if MP_MODARITH */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1648
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1649
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1650
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1651
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1652
/* {{{ Comparison functions */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1653
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1654
/* {{{ mp_cmp_z(a) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1655
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1656
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1657
  mp_cmp_z(a)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1658
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1659
  Compare a <=> 0.  Returns <0 if a<0, 0 if a=0, >0 if a>0.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1660
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1661
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1662
int    mp_cmp_z(const mp_int *a)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1663
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1664
  if(SIGN(a) == NEG)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1665
    return MP_LT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1666
  else if(USED(a) == 1 && DIGIT(a, 0) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1667
    return MP_EQ;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1668
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1669
    return MP_GT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1670
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1671
} /* end mp_cmp_z() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1672
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1673
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1674
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1675
/* {{{ mp_cmp_d(a, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1676
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1677
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1678
  mp_cmp_d(a, d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1679
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1680
  Compare a <=> d.  Returns <0 if a<d, 0 if a=d, >0 if a>d
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1681
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1682
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1683
int    mp_cmp_d(const mp_int *a, mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1684
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1685
  ARGCHK(a != NULL, MP_EQ);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1686
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1687
  if(SIGN(a) == NEG)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1688
    return MP_LT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1689
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1690
  return s_mp_cmp_d(a, d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1691
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1692
} /* end mp_cmp_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1693
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1694
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1695
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1696
/* {{{ mp_cmp(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1697
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1698
int    mp_cmp(const mp_int *a, const mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1699
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1700
  ARGCHK(a != NULL && b != NULL, MP_EQ);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1701
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1702
  if(SIGN(a) == SIGN(b)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1703
    int  mag;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1704
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1705
    if((mag = s_mp_cmp(a, b)) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1706
      return MP_EQ;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1707
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1708
    if(SIGN(a) == ZPOS)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1709
      return mag;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1710
    else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1711
      return -mag;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1712
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1713
  } else if(SIGN(a) == ZPOS) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1714
    return MP_GT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1715
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1716
    return MP_LT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1717
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1718
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1719
} /* end mp_cmp() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1720
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1721
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1722
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1723
/* {{{ mp_cmp_mag(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1724
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1725
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1726
  mp_cmp_mag(a, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1727
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1728
  Compares |a| <=> |b|, and returns an appropriate comparison result
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1729
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1730
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1731
int    mp_cmp_mag(mp_int *a, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1732
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1733
  ARGCHK(a != NULL && b != NULL, MP_EQ);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1734
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1735
  return s_mp_cmp(a, b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1736
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1737
} /* end mp_cmp_mag() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1738
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1739
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1740
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1741
/* {{{ mp_cmp_int(a, z, kmflag) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1742
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1743
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1744
  This just converts z to an mp_int, and uses the existing comparison
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1745
  routines.  This is sort of inefficient, but it's not clear to me how
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1746
  frequently this wil get used anyway.  For small positive constants,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1747
  you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1748
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1749
int    mp_cmp_int(const mp_int *a, long z, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1750
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1751
  mp_int  tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1752
  int     out;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1753
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1754
  ARGCHK(a != NULL, MP_EQ);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1755
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1756
  mp_init(&tmp, kmflag); mp_set_int(&tmp, z);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1757
  out = mp_cmp(a, &tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1758
  mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1759
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1760
  return out;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1761
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1762
} /* end mp_cmp_int() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1763
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1764
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1765
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1766
/* {{{ mp_isodd(a) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1767
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1768
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1769
  mp_isodd(a)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1770
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1771
  Returns a true (non-zero) value if a is odd, false (zero) otherwise.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1772
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1773
int    mp_isodd(const mp_int *a)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1774
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1775
  ARGCHK(a != NULL, 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1776
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1777
  return (int)(DIGIT(a, 0) & 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1778
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1779
} /* end mp_isodd() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1780
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1781
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1782
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1783
/* {{{ mp_iseven(a) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1784
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1785
int    mp_iseven(const mp_int *a)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1786
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1787
  return !mp_isodd(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1788
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1789
} /* end mp_iseven() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1790
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1791
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1792
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1793
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1794
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1795
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1796
/* {{{ Number theoretic functions */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1797
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1798
#if MP_NUMTH
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1799
/* {{{ mp_gcd(a, b, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1800
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1801
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1802
  Like the old mp_gcd() function, except computes the GCD using the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1803
  binary algorithm due to Josef Stein in 1961 (via Knuth).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1804
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1805
mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1806
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1807
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1808
  mp_int   u, v, t;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1809
  mp_size  k = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1810
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1811
  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1812
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1813
  if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1814
      return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1815
  if(mp_cmp_z(a) == MP_EQ) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1816
    return mp_copy(b, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1817
  } else if(mp_cmp_z(b) == MP_EQ) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1818
    return mp_copy(a, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1819
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1820
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1821
  if((res = mp_init(&t, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1822
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1823
  if((res = mp_init_copy(&u, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1824
    goto U;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1825
  if((res = mp_init_copy(&v, b)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1826
    goto V;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1827
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1828
  SIGN(&u) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1829
  SIGN(&v) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1830
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1831
  /* Divide out common factors of 2 until at least 1 of a, b is even */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1832
  while(mp_iseven(&u) && mp_iseven(&v)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1833
    s_mp_div_2(&u);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1834
    s_mp_div_2(&v);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1835
    ++k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1836
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1837
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1838
  /* Initialize t */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1839
  if(mp_isodd(&u)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1840
    if((res = mp_copy(&v, &t)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1841
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1842
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1843
    /* t = -v */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1844
    if(SIGN(&v) == ZPOS)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1845
      SIGN(&t) = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1846
    else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1847
      SIGN(&t) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1848
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1849
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1850
    if((res = mp_copy(&u, &t)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1851
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1852
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1853
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1854
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1855
  for(;;) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1856
    while(mp_iseven(&t)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1857
      s_mp_div_2(&t);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1858
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1859
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1860
    if(mp_cmp_z(&t) == MP_GT) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1861
      if((res = mp_copy(&t, &u)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1862
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1863
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1864
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1865
      if((res = mp_copy(&t, &v)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1866
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1867
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1868
      /* v = -t */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1869
      if(SIGN(&t) == ZPOS)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1870
        SIGN(&v) = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1871
      else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1872
        SIGN(&v) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1873
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1874
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1875
    if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1876
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1877
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1878
    if(s_mp_cmp_d(&t, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1879
      break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1880
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1881
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1882
  s_mp_2expt(&v, k);       /* v = 2^k   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1883
  res = mp_mul(&u, &v, c); /* c = u * v */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1884
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1885
 CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1886
  mp_clear(&v);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1887
 V:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1888
  mp_clear(&u);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1889
 U:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1890
  mp_clear(&t);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1891
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1892
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1893
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1894
} /* end mp_gcd() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1895
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1896
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1897
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1898
/* {{{ mp_lcm(a, b, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1899
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1900
/* We compute the least common multiple using the rule:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1901
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1902
   ab = [a, b](a, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1903
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1904
   ... by computing the product, and dividing out the gcd.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1905
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1906
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1907
mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1908
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1909
  mp_int  gcd, prod;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1910
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1911
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1912
  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1913
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1914
  /* Set up temporaries */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1915
  if((res = mp_init(&gcd, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1916
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1917
  if((res = mp_init(&prod, FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1918
    goto GCD;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1919
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1920
  if((res = mp_mul(a, b, &prod)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1921
    goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1922
  if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1923
    goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1924
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1925
  res = mp_div(&prod, &gcd, c, NULL);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1926
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1927
 CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1928
  mp_clear(&prod);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1929
 GCD:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1930
  mp_clear(&gcd);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1931
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1932
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1933
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1934
} /* end mp_lcm() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1935
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1936
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1937
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1938
/* {{{ mp_xgcd(a, b, g, x, y) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1939
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1940
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1941
  mp_xgcd(a, b, g, x, y)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1942
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1943
  Compute g = (a, b) and values x and y satisfying Bezout's identity
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1944
  (that is, ax + by = g).  This uses the binary extended GCD algorithm
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1945
  based on the Stein algorithm used for mp_gcd()
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1946
  See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1947
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1948
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1949
mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1950
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1951
  mp_int   gx, xc, yc, u, v, A, B, C, D;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1952
  mp_int  *clean[9];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1953
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1954
  int      last = -1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1955
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1956
  if(mp_cmp_z(b) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1957
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1958
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1959
  /* Initialize all these variables we need */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1960
  MP_CHECKOK( mp_init(&u, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1961
  clean[++last] = &u;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1962
  MP_CHECKOK( mp_init(&v, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1963
  clean[++last] = &v;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1964
  MP_CHECKOK( mp_init(&gx, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1965
  clean[++last] = &gx;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1966
  MP_CHECKOK( mp_init(&A, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1967
  clean[++last] = &A;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1968
  MP_CHECKOK( mp_init(&B, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1969
  clean[++last] = &B;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1970
  MP_CHECKOK( mp_init(&C, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1971
  clean[++last] = &C;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1972
  MP_CHECKOK( mp_init(&D, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1973
  clean[++last] = &D;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1974
  MP_CHECKOK( mp_init_copy(&xc, a) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1975
  clean[++last] = &xc;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1976
  mp_abs(&xc, &xc);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1977
  MP_CHECKOK( mp_init_copy(&yc, b) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1978
  clean[++last] = &yc;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1979
  mp_abs(&yc, &yc);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1980
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1981
  mp_set(&gx, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1982
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1983
  /* Divide by two until at least one of them is odd */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1984
  while(mp_iseven(&xc) && mp_iseven(&yc)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1985
    mp_size nx = mp_trailing_zeros(&xc);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1986
    mp_size ny = mp_trailing_zeros(&yc);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1987
    mp_size n  = MP_MIN(nx, ny);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1988
    s_mp_div_2d(&xc,n);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1989
    s_mp_div_2d(&yc,n);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1990
    MP_CHECKOK( s_mp_mul_2d(&gx,n) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1991
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1992
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1993
  mp_copy(&xc, &u);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1994
  mp_copy(&yc, &v);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1995
  mp_set(&A, 1); mp_set(&D, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1996
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1997
  /* Loop through binary GCD algorithm */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1998
  do {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1999
    while(mp_iseven(&u)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2000
      s_mp_div_2(&u);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2001
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2002
      if(mp_iseven(&A) && mp_iseven(&B)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2003
        s_mp_div_2(&A); s_mp_div_2(&B);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2004
      } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2005
        MP_CHECKOK( mp_add(&A, &yc, &A) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2006
        s_mp_div_2(&A);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2007
        MP_CHECKOK( mp_sub(&B, &xc, &B) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2008
        s_mp_div_2(&B);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2009
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2010
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2011
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2012
    while(mp_iseven(&v)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2013
      s_mp_div_2(&v);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2014
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2015
      if(mp_iseven(&C) && mp_iseven(&D)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2016
        s_mp_div_2(&C); s_mp_div_2(&D);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2017
      } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2018
        MP_CHECKOK( mp_add(&C, &yc, &C) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2019
        s_mp_div_2(&C);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2020
        MP_CHECKOK( mp_sub(&D, &xc, &D) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2021
        s_mp_div_2(&D);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2022
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2023
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2024
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2025
    if(mp_cmp(&u, &v) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2026
      MP_CHECKOK( mp_sub(&u, &v, &u) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2027
      MP_CHECKOK( mp_sub(&A, &C, &A) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2028
      MP_CHECKOK( mp_sub(&B, &D, &B) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2029
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2030
      MP_CHECKOK( mp_sub(&v, &u, &v) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2031
      MP_CHECKOK( mp_sub(&C, &A, &C) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2032
      MP_CHECKOK( mp_sub(&D, &B, &D) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2033
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2034
  } while (mp_cmp_z(&u) != 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2035
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2036
  /* copy results to output */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2037
  if(x)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2038
    MP_CHECKOK( mp_copy(&C, x) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2039
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2040
  if(y)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2041
    MP_CHECKOK( mp_copy(&D, y) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2042
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2043
  if(g)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2044
    MP_CHECKOK( mp_mul(&gx, &v, g) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2045
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2046
 CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2047
  while(last >= 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2048
    mp_clear(clean[last--]);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2049
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2050
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2051
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2052
} /* end mp_xgcd() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2053
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2054
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2055
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2056
mp_size mp_trailing_zeros(const mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2057
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2058
  mp_digit d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2059
  mp_size  n = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2060
  int      ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2061
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2062
  if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2063
    return n;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2064
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2065
  for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2066
    n += MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2067
  if (!d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2068
    return 0;   /* shouldn't happen, but ... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2069
#if !defined(MP_USE_UINT_DIGIT)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2070
  if (!(d & 0xffffffffU)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2071
    d >>= 32;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2072
    n  += 32;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2073
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2074
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2075
  if (!(d & 0xffffU)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2076
    d >>= 16;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2077
    n  += 16;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2078
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2079
  if (!(d & 0xffU)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2080
    d >>= 8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2081
    n  += 8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2082
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2083
  if (!(d & 0xfU)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2084
    d >>= 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2085
    n  += 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2086
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2087
  if (!(d & 0x3U)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2088
    d >>= 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2089
    n  += 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2090
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2091
  if (!(d & 0x1U)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2092
    d >>= 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2093
    n  += 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2094
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2095
#if MP_ARGCHK == 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2096
  assert(0 != (d & 1));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2097
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2098
  return n;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2099
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2100
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2101
/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2102
** Returns k (positive) or error (negative).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2103
** This technique from the paper "Fast Modular Reciprocals" (unpublished)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2104
** by Richard Schroeppel (a.k.a. Captain Nemo).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2105
*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2106
mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2107
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2108
  mp_err res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2109
  mp_err k    = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2110
  mp_int d, f, g;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2111
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2112
  ARGCHK(a && p && c, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2113
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2114
  MP_DIGITS(&d) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2115
  MP_DIGITS(&f) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2116
  MP_DIGITS(&g) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2117
  MP_CHECKOK( mp_init(&d, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2118
  MP_CHECKOK( mp_init_copy(&f, a) );    /* f = a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2119
  MP_CHECKOK( mp_init_copy(&g, p) );    /* g = p */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2120
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2121
  mp_set(c, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2122
  mp_zero(&d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2123
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2124
  if (mp_cmp_z(&f) == 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2125
    res = MP_UNDEF;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2126
  } else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2127
  for (;;) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2128
    int diff_sign;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2129
    while (mp_iseven(&f)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2130
      mp_size n = mp_trailing_zeros(&f);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2131
      if (!n) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2132
        res = MP_UNDEF;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2133
        goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2134
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2135
      s_mp_div_2d(&f, n);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2136
      MP_CHECKOK( s_mp_mul_2d(&d, n) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2137
      k += n;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2138
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2139
    if (mp_cmp_d(&f, 1) == MP_EQ) {     /* f == 1 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2140
      res = k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2141
      break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2142
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2143
    diff_sign = mp_cmp(&f, &g);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2144
    if (diff_sign < 0) {                /* f < g */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2145
      s_mp_exch(&f, &g);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2146
      s_mp_exch(c, &d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2147
    } else if (diff_sign == 0) {                /* f == g */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2148
      res = MP_UNDEF;           /* a and p are not relatively prime */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2149
      break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2150
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2151
    if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2152
      MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2153
      MP_CHECKOK( mp_sub(c,  &d,  c) ); /* c = c - d */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2154
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2155
      MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2156
      MP_CHECKOK( mp_add(c,  &d,  c) ); /* c = c + d */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2157
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2158
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2159
  if (res >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2160
    while (MP_SIGN(c) != MP_ZPOS) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2161
      MP_CHECKOK( mp_add(c, p, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2162
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2163
    res = k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2164
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2165
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2166
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2167
  mp_clear(&d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2168
  mp_clear(&f);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2169
  mp_clear(&g);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2170
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2171
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2172
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2173
/* Compute T = (P ** -1) mod MP_RADIX.  Also works for 16-bit mp_digits.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2174
** This technique from the paper "Fast Modular Reciprocals" (unpublished)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2175
** by Richard Schroeppel (a.k.a. Captain Nemo).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2176
*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2177
mp_digit  s_mp_invmod_radix(mp_digit P)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2178
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2179
  mp_digit T = P;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2180
  T *= 2 - (P * T);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2181
  T *= 2 - (P * T);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2182
  T *= 2 - (P * T);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2183
  T *= 2 - (P * T);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2184
#if !defined(MP_USE_UINT_DIGIT)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2185
  T *= 2 - (P * T);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2186
  T *= 2 - (P * T);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2187
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2188
  return T;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2189
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2190
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2191
/* Given c, k, and prime p, where a*c == 2**k (mod p),
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2192
** Compute x = (a ** -1) mod p.  This is similar to Montgomery reduction.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2193
** This technique from the paper "Fast Modular Reciprocals" (unpublished)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2194
** by Richard Schroeppel (a.k.a. Captain Nemo).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2195
*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2196
mp_err  s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2197
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2198
  int      k_orig = k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2199
  mp_digit r;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2200
  mp_size  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2201
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2202
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2203
  if (mp_cmp_z(c) < 0) {                /* c < 0 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2204
    MP_CHECKOK( mp_add(c, p, x) );      /* x = c + p */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2205
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2206
    MP_CHECKOK( mp_copy(c, x) );        /* x = c */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2207
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2208
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2209
  /* make sure x is large enough */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2210
  ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2211
  ix = MP_MAX(ix, MP_USED(x));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2212
  MP_CHECKOK( s_mp_pad(x, ix) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2213
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2214
  r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2215
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2216
  for (ix = 0; k > 0; ix++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2217
    int      j = MP_MIN(k, MP_DIGIT_BIT);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2218
    mp_digit v = r * MP_DIGIT(x, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2219
    if (j < MP_DIGIT_BIT) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2220
      v &= ((mp_digit)1 << j) - 1;      /* v = v mod (2 ** j) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2221
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2222
    s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2223
    k -= j;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2224
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2225
  s_mp_clamp(x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2226
  s_mp_div_2d(x, k_orig);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2227
  res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2228
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2229
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2230
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2231
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2232
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2233
/* compute mod inverse using Schroeppel's method, only if m is odd */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2234
mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2235
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2236
  int k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2237
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2238
  mp_int  x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2239
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2240
  ARGCHK(a && m && c, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2241
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2242
  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2243
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2244
  if (mp_iseven(m))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2245
    return MP_UNDEF;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2246
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2247
  MP_DIGITS(&x) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2248
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2249
  if (a == c) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2250
    if ((res = mp_init_copy(&x, a)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2251
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2252
    if (a == m)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2253
      m = &x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2254
    a = &x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2255
  } else if (m == c) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2256
    if ((res = mp_init_copy(&x, m)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2257
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2258
    m = &x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2259
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2260
    MP_DIGITS(&x) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2261
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2262
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2263
  MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2264
  k = res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2265
  MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2266
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2267
  mp_clear(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2268
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2269
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2270
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2271
/* Known good algorithm for computing modular inverse.  But slow. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2272
mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2273
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2274
  mp_int  g, x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2275
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2276
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2277
  ARGCHK(a && m && c, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2278
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2279
  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2280
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2281
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2282
  MP_DIGITS(&g) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2283
  MP_DIGITS(&x) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2284
  MP_CHECKOK( mp_init(&x, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2285
  MP_CHECKOK( mp_init(&g, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2286
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2287
  MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2288
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2289
  if (mp_cmp_d(&g, 1) != MP_EQ) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2290
    res = MP_UNDEF;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2291
    goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2292
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2293
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2294
  res = mp_mod(&x, m, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2295
  SIGN(c) = SIGN(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2296
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2297
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2298
  mp_clear(&x);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2299
  mp_clear(&g);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2300
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2301
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2302
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2303
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2304
/* modular inverse where modulus is 2**k. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2305
/* c = a**-1 mod 2**k */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2306
mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2307
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2308
  mp_err res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2309
  mp_size ix = k + 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2310
  mp_int t0, t1, val, tmp, two2k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2311
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2312
  static const mp_digit d2 = 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2313
  static const mp_int two = { 0, MP_ZPOS, 1, 1, (mp_digit *)&d2 };
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2314
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2315
  if (mp_iseven(a))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2316
    return MP_UNDEF;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2317
  if (k <= MP_DIGIT_BIT) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2318
    mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2319
    if (k < MP_DIGIT_BIT)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2320
      i &= ((mp_digit)1 << k) - (mp_digit)1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2321
    mp_set(c, i);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2322
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2323
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2324
  MP_DIGITS(&t0) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2325
  MP_DIGITS(&t1) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2326
  MP_DIGITS(&val) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2327
  MP_DIGITS(&tmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2328
  MP_DIGITS(&two2k) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2329
  MP_CHECKOK( mp_init_copy(&val, a) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2330
  s_mp_mod_2d(&val, k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2331
  MP_CHECKOK( mp_init_copy(&t0, &val) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2332
  MP_CHECKOK( mp_init_copy(&t1, &t0)  );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2333
  MP_CHECKOK( mp_init(&tmp, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2334
  MP_CHECKOK( mp_init(&two2k, FLAG(a)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2335
  MP_CHECKOK( s_mp_2expt(&two2k, k) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2336
  do {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2337
    MP_CHECKOK( mp_mul(&val, &t1, &tmp)  );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2338
    MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2339
    MP_CHECKOK( mp_mul(&t1, &tmp, &t1)   );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2340
    s_mp_mod_2d(&t1, k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2341
    while (MP_SIGN(&t1) != MP_ZPOS) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2342
      MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2343
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2344
    if (mp_cmp(&t1, &t0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2345
      break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2346
    MP_CHECKOK( mp_copy(&t1, &t0) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2347
  } while (--ix > 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2348
  if (!ix) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2349
    res = MP_UNDEF;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2350
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2351
    mp_exch(c, &t1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2352
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2353
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2354
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2355
  mp_clear(&t0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2356
  mp_clear(&t1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2357
  mp_clear(&val);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2358
  mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2359
  mp_clear(&two2k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2360
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2361
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2362
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2363
mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2364
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2365
  mp_err res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2366
  mp_size k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2367
  mp_int oddFactor, evenFactor; /* factors of the modulus */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2368
  mp_int oddPart, evenPart;     /* parts to combine via CRT. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2369
  mp_int C2, tmp1, tmp2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2370
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2371
  /*static const mp_digit d1 = 1; */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2372
  /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2373
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2374
  if ((res = s_mp_ispow2(m)) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2375
    k = res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2376
    return s_mp_invmod_2d(a, k, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2377
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2378
  MP_DIGITS(&oddFactor) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2379
  MP_DIGITS(&evenFactor) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2380
  MP_DIGITS(&oddPart) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2381
  MP_DIGITS(&evenPart) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2382
  MP_DIGITS(&C2)     = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2383
  MP_DIGITS(&tmp1)   = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2384
  MP_DIGITS(&tmp2)   = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2385
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2386
  MP_CHECKOK( mp_init_copy(&oddFactor, m) );    /* oddFactor = m */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2387
  MP_CHECKOK( mp_init(&evenFactor, FLAG(m)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2388
  MP_CHECKOK( mp_init(&oddPart, FLAG(m)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2389
  MP_CHECKOK( mp_init(&evenPart, FLAG(m)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2390
  MP_CHECKOK( mp_init(&C2, FLAG(m))     );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2391
  MP_CHECKOK( mp_init(&tmp1, FLAG(m))   );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2392
  MP_CHECKOK( mp_init(&tmp2, FLAG(m))   );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2393
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2394
  k = mp_trailing_zeros(m);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2395
  s_mp_div_2d(&oddFactor, k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2396
  MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2397
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2398
  /* compute a**-1 mod oddFactor. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2399
  MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2400
  /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2401
  MP_CHECKOK( s_mp_invmod_2d(   a,       k,    &evenPart) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2402
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2403
  /* Use Chinese Remainer theorem to compute a**-1 mod m. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2404
  /* let m1 = oddFactor,  v1 = oddPart,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2405
   * let m2 = evenFactor, v2 = evenPart.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2406
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2407
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2408
  /* Compute C2 = m1**-1 mod m2. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2409
  MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k,    &C2) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2410
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2411
  /* compute u = (v2 - v1)*C2 mod m2 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2412
  MP_CHECKOK( mp_sub(&evenPart, &oddPart,   &tmp1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2413
  MP_CHECKOK( mp_mul(&tmp1,     &C2,        &tmp2) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2414
  s_mp_mod_2d(&tmp2, k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2415
  while (MP_SIGN(&tmp2) != MP_ZPOS) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2416
    MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2417
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2418
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2419
  /* compute answer = v1 + u*m1 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2420
  MP_CHECKOK( mp_mul(&tmp2,     &oddFactor, c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2421
  MP_CHECKOK( mp_add(&oddPart,  c,          c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2422
  /* not sure this is necessary, but it's low cost if not. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2423
  MP_CHECKOK( mp_mod(c,         m,          c) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2424
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2425
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2426
  mp_clear(&oddFactor);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2427
  mp_clear(&evenFactor);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2428
  mp_clear(&oddPart);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2429
  mp_clear(&evenPart);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2430
  mp_clear(&C2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2431
  mp_clear(&tmp1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2432
  mp_clear(&tmp2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2433
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2434
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2435
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2436
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2437
/* {{{ mp_invmod(a, m, c) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2438
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2439
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2440
  mp_invmod(a, m, c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2441
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2442
  Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2443
  This is equivalent to the question of whether (a, m) = 1.  If not,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2444
  MP_UNDEF is returned, and there is no inverse.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2445
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2446
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2447
mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2448
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2449
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2450
  ARGCHK(a && m && c, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2451
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2452
  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2453
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2454
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2455
  if (mp_isodd(m)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2456
    return s_mp_invmod_odd_m(a, m, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2457
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2458
  if (mp_iseven(a))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2459
    return MP_UNDEF;    /* not invertable */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2460
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2461
  return s_mp_invmod_even_m(a, m, c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2462
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2463
} /* end mp_invmod() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2464
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2465
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2466
#endif /* if MP_NUMTH */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2467
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2468
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2469
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2470
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2471
/* {{{ mp_print(mp, ofp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2472
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2473
#if MP_IOFUNC
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2474
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2475
  mp_print(mp, ofp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2476
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2477
  Print a textual representation of the given mp_int on the output
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2478
  stream 'ofp'.  Output is generated using the internal radix.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2479
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2480
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2481
void   mp_print(mp_int *mp, FILE *ofp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2482
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2483
  int   ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2484
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2485
  if(mp == NULL || ofp == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2486
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2487
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2488
  fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2489
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2490
  for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2491
    fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2492
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2493
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2494
} /* end mp_print() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2495
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2496
#endif /* if MP_IOFUNC */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2497
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2498
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2499
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2500
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2501
/* {{{ More I/O Functions */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2502
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2503
/* {{{ mp_read_raw(mp, str, len) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2504
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2505
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2506
   mp_read_raw(mp, str, len)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2507
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2508
   Read in a raw value (base 256) into the given mp_int
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2509
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2510
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2511
mp_err  mp_read_raw(mp_int *mp, char *str, int len)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2512
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2513
  int            ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2514
  mp_err         res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2515
  unsigned char *ustr = (unsigned char *)str;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2516
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2517
  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2518
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2519
  mp_zero(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2520
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2521
  /* Get sign from first byte */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2522
  if(ustr[0])
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2523
    SIGN(mp) = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2524
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2525
    SIGN(mp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2526
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2527
  /* Read the rest of the digits */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2528
  for(ix = 1; ix < len; ix++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2529
    if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2530
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2531
    if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2532
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2533
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2534
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2535
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2536
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2537
} /* end mp_read_raw() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2538
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2539
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2540
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2541
/* {{{ mp_raw_size(mp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2542
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2543
int    mp_raw_size(mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2544
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2545
  ARGCHK(mp != NULL, 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2546
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2547
  return (USED(mp) * sizeof(mp_digit)) + 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2548
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2549
} /* end mp_raw_size() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2550
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2551
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2552
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2553
/* {{{ mp_toraw(mp, str) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2554
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2555
mp_err mp_toraw(mp_int *mp, char *str)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2556
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2557
  int  ix, jx, pos = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2558
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2559
  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2560
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2561
  str[0] = (char)SIGN(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2562
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2563
  /* Iterate over each digit... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2564
  for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2565
    mp_digit  d = DIGIT(mp, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2566
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2567
    /* Unpack digit bytes, high order first */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2568
    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2569
      str[pos++] = (char)(d >> (jx * CHAR_BIT));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2570
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2571
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2572
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2573
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2574
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2575
} /* end mp_toraw() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2576
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2577
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2578
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2579
/* {{{ mp_read_radix(mp, str, radix) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2580
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2581
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2582
  mp_read_radix(mp, str, radix)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2583
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2584
  Read an integer from the given string, and set mp to the resulting
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2585
  value.  The input is presumed to be in base 10.  Leading non-digit
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2586
  characters are ignored, and the function reads until a non-digit
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2587
  character or the end of the string.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2588
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2589
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2590
mp_err  mp_read_radix(mp_int *mp, const char *str, int radix)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2591
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2592
  int     ix = 0, val = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2593
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2594
  mp_sign sig = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2595
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2596
  ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2597
         MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2598
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2599
  mp_zero(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2600
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2601
  /* Skip leading non-digit characters until a digit or '-' or '+' */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2602
  while(str[ix] &&
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2603
        (s_mp_tovalue(str[ix], radix) < 0) &&
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2604
        str[ix] != '-' &&
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2605
        str[ix] != '+') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2606
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2607
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2608
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2609
  if(str[ix] == '-') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2610
    sig = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2611
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2612
  } else if(str[ix] == '+') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2613
    sig = ZPOS; /* this is the default anyway... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2614
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2615
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2616
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2617
  while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2618
    if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2619
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2620
    if((res = s_mp_add_d(mp, val)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2621
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2622
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2623
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2624
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2625
  if(s_mp_cmp_d(mp, 0) == MP_EQ)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2626
    SIGN(mp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2627
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2628
    SIGN(mp) = sig;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2629
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2630
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2631
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2632
} /* end mp_read_radix() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2633
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2634
mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2635
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2636
  int     radix = default_radix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2637
  int     cx;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2638
  mp_sign sig   = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2639
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2640
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2641
  /* Skip leading non-digit characters until a digit or '-' or '+' */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2642
  while ((cx = *str) != 0 &&
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2643
        (s_mp_tovalue(cx, radix) < 0) &&
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2644
        cx != '-' &&
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2645
        cx != '+') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2646
    ++str;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2647
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2648
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2649
  if (cx == '-') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2650
    sig = NEG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2651
    ++str;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2652
  } else if (cx == '+') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2653
    sig = ZPOS; /* this is the default anyway... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2654
    ++str;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2655
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2656
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2657
  if (str[0] == '0') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2658
    if ((str[1] | 0x20) == 'x') {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2659
      radix = 16;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2660
      str += 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2661
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2662
      radix = 8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2663
      str++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2664
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2665
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2666
  res = mp_read_radix(a, str, radix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2667
  if (res == MP_OKAY) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2668
    MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2669
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2670
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2671
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2672
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2673
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2674
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2675
/* {{{ mp_radix_size(mp, radix) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2676
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2677
int    mp_radix_size(mp_int *mp, int radix)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2678
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2679
  int  bits;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2680
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2681
  if(!mp || radix < 2 || radix > MAX_RADIX)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2682
    return 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2683
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2684
  bits = USED(mp) * DIGIT_BIT - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2685
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2686
  return s_mp_outlen(bits, radix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2687
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2688
} /* end mp_radix_size() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2689
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2690
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2691
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2692
/* {{{ mp_toradix(mp, str, radix) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2693
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2694
mp_err mp_toradix(mp_int *mp, char *str, int radix)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2695
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2696
  int  ix, pos = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2697
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2698
  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2699
  ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2700
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2701
  if(mp_cmp_z(mp) == MP_EQ) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2702
    str[0] = '0';
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2703
    str[1] = '\0';
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2704
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2705
    mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2706
    mp_int   tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2707
    mp_sign  sgn;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2708
    mp_digit rem, rdx = (mp_digit)radix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2709
    char     ch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2710
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2711
    if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2712
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2713
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2714
    /* Save sign for later, and take absolute value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2715
    sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2716
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2717
    /* Generate output digits in reverse order      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2718
    while(mp_cmp_z(&tmp) != 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2719
      if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2720
        mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2721
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2722
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2723
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2724
      /* Generate digits, use capital letters */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2725
      ch = s_mp_todigit(rem, radix, 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2726
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2727
      str[pos++] = ch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2728
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2729
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2730
    /* Add - sign if original value was negative */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2731
    if(sgn == NEG)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2732
      str[pos++] = '-';
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2733
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2734
    /* Add trailing NUL to end the string        */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2735
    str[pos--] = '\0';
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2736
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2737
    /* Reverse the digits and sign indicator     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2738
    ix = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2739
    while(ix < pos) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2740
      char tmp = str[ix];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2741
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2742
      str[ix] = str[pos];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2743
      str[pos] = tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2744
      ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2745
      --pos;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2746
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2747
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2748
    mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2749
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2750
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2751
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2752
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2753
} /* end mp_toradix() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2754
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2755
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2756
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2757
/* {{{ mp_tovalue(ch, r) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2758
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2759
int    mp_tovalue(char ch, int r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2760
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2761
  return s_mp_tovalue(ch, r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2762
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2763
} /* end mp_tovalue() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2764
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2765
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2766
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2767
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2768
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2769
/* {{{ mp_strerror(ec) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2770
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2771
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2772
  mp_strerror(ec)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2773
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2774
  Return a string describing the meaning of error code 'ec'.  The
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2775
  string returned is allocated in static memory, so the caller should
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2776
  not attempt to modify or free the memory associated with this
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2777
  string.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2778
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2779
const char  *mp_strerror(mp_err ec)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2780
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2781
  int   aec = (ec < 0) ? -ec : ec;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2782
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2783
  /* Code values are negative, so the senses of these comparisons
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2784
     are accurate */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2785
  if(ec < MP_LAST_CODE || ec > MP_OKAY) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2786
    return mp_err_string[0];  /* unknown error code */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2787
  } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2788
    return mp_err_string[aec + 1];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2789
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2790
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2791
} /* end mp_strerror() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2792
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2793
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2794
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2795
/*========================================================================*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2796
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2797
/* Static function definitions (internal use only)                        */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2798
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2799
/* {{{ Memory management */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2800
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2801
/* {{{ s_mp_grow(mp, min) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2802
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2803
/* Make sure there are at least 'min' digits allocated to mp              */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2804
mp_err   s_mp_grow(mp_int *mp, mp_size min)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2805
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2806
  if(min > ALLOC(mp)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2807
    mp_digit   *tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2808
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2809
    /* Set min to next nearest default precision block size */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2810
    min = MP_ROUNDUP(min, s_mp_defprec);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2811
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2812
    if((tmp = s_mp_alloc(min, sizeof(mp_digit), FLAG(mp))) == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2813
      return MP_MEM;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2814
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2815
    s_mp_copy(DIGITS(mp), tmp, USED(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2816
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2817
#if MP_CRYPTO
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2818
    s_mp_setz(DIGITS(mp), ALLOC(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2819
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2820
    s_mp_free(DIGITS(mp), ALLOC(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2821
    DIGITS(mp) = tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2822
    ALLOC(mp) = min;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2823
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2824
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2825
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2826
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2827
} /* end s_mp_grow() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2828
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2829
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2830
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2831
/* {{{ s_mp_pad(mp, min) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2832
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2833
/* Make sure the used size of mp is at least 'min', growing if needed     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2834
mp_err   s_mp_pad(mp_int *mp, mp_size min)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2835
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2836
  if(min > USED(mp)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2837
    mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2838
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2839
    /* Make sure there is room to increase precision  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2840
    if (min > ALLOC(mp)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2841
      if ((res = s_mp_grow(mp, min)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2842
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2843
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2844
      s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2845
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2846
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2847
    /* Increase precision; should already be 0-filled */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2848
    USED(mp) = min;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2849
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2850
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2851
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2852
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2853
} /* end s_mp_pad() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2854
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2855
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2856
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2857
/* {{{ s_mp_setz(dp, count) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2858
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2859
#if MP_MACRO == 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2860
/* Set 'count' digits pointed to by dp to be zeroes                       */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2861
void s_mp_setz(mp_digit *dp, mp_size count)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2862
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2863
#if MP_MEMSET == 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2864
  int  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2865
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2866
  for(ix = 0; ix < count; ix++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2867
    dp[ix] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2868
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2869
  memset(dp, 0, count * sizeof(mp_digit));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2870
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2871
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2872
} /* end s_mp_setz() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2873
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2874
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2875
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2876
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2877
/* {{{ s_mp_copy(sp, dp, count) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2878
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2879
#if MP_MACRO == 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2880
/* Copy 'count' digits from sp to dp                                      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2881
void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2882
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2883
#if MP_MEMCPY == 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2884
  int  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2885
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2886
  for(ix = 0; ix < count; ix++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2887
    dp[ix] = sp[ix];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2888
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2889
  memcpy(dp, sp, count * sizeof(mp_digit));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2890
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2891
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2892
} /* end s_mp_copy() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2893
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2894
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2895
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2896
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2897
/* {{{ s_mp_alloc(nb, ni, kmflag) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2898
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2899
#if MP_MACRO == 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2900
/* Allocate ni records of nb bytes each, and return a pointer to that     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2901
void    *s_mp_alloc(size_t nb, size_t ni, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2902
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2903
  mp_int *mp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2904
  ++mp_allocs;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2905
#ifdef _KERNEL
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2906
  mp = kmem_zalloc(nb * ni, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2907
  if (mp != NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2908
    FLAG(mp) = kmflag;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2909
  return (mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2910
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2911
  return calloc(nb, ni);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2912
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2913
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2914
} /* end s_mp_alloc() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2915
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2916
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2917
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2918
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2919
/* {{{ s_mp_free(ptr) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2920
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2921
#if MP_MACRO == 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2922
/* Free the memory pointed to by ptr                                      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2923
void     s_mp_free(void *ptr, mp_size alloc)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2924
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2925
  if(ptr) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2926
    ++mp_frees;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2927
#ifdef _KERNEL
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2928
    kmem_free(ptr, alloc * sizeof (mp_digit));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2929
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2930
    free(ptr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2931
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2932
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2933
} /* end s_mp_free() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2934
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2935
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2936
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2937
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2938
/* {{{ s_mp_clamp(mp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2939
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2940
#if MP_MACRO == 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2941
/* Remove leading zeroes from the given value                             */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2942
void     s_mp_clamp(mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2943
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2944
  mp_size used = MP_USED(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2945
  while (used > 1 && DIGIT(mp, used - 1) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2946
    --used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2947
  MP_USED(mp) = used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2948
} /* end s_mp_clamp() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2949
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2950
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2951
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2952
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2953
/* {{{ s_mp_exch(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2954
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2955
/* Exchange the data for a and b; (b, a) = (a, b)                         */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2956
void     s_mp_exch(mp_int *a, mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2957
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2958
  mp_int   tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2959
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2960
  tmp = *a;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2961
  *a = *b;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2962
  *b = tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2963
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2964
} /* end s_mp_exch() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2965
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2966
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2967
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2968
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2969
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2970
/* {{{ Arithmetic helpers */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2971
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2972
/* {{{ s_mp_lshd(mp, p) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2973
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2974
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2975
   Shift mp leftward by p digits, growing if needed, and zero-filling
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2976
   the in-shifted digits at the right end.  This is a convenient
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2977
   alternative to multiplication by powers of the radix
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2978
   The value of USED(mp) must already have been set to the value for
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2979
   the shifted result.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2980
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2981
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2982
mp_err   s_mp_lshd(mp_int *mp, mp_size p)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2983
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2984
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2985
  mp_size pos;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2986
  int     ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2987
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2988
  if(p == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2989
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2990
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2991
  if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2992
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2993
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2994
  if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2995
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2996
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2997
  pos = USED(mp) - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2998
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  2999
  /* Shift all the significant figures over as needed */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3000
  for(ix = pos - p; ix >= 0; ix--)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3001
    DIGIT(mp, ix + p) = DIGIT(mp, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3002
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3003
  /* Fill the bottom digits with zeroes */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3004
  for(ix = 0; ix < p; ix++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3005
    DIGIT(mp, ix) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3006
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3007
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3008
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3009
} /* end s_mp_lshd() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3010
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3011
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3012
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3013
/* {{{ s_mp_mul_2d(mp, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3014
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3015
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3016
  Multiply the integer by 2^d, where d is a number of bits.  This
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3017
  amounts to a bitwise shift of the value.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3018
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3019
mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3020
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3021
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3022
  mp_digit dshift, bshift;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3023
  mp_digit mask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3024
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3025
  ARGCHK(mp != NULL,  MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3026
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3027
  dshift = d / MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3028
  bshift = d % MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3029
  /* bits to be shifted out of the top word */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3030
  mask   = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3031
  mask  &= MP_DIGIT(mp, MP_USED(mp) - 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3032
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3033
  if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3034
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3035
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3036
  if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3037
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3038
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3039
  if (bshift) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3040
    mp_digit *pa = MP_DIGITS(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3041
    mp_digit *alim = pa + MP_USED(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3042
    mp_digit  prev = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3043
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3044
    for (pa += dshift; pa < alim; ) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3045
      mp_digit x = *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3046
      *pa++ = (x << bshift) | prev;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3047
      prev = x >> (DIGIT_BIT - bshift);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3048
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3049
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3050
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3051
  s_mp_clamp(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3052
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3053
} /* end s_mp_mul_2d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3054
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3055
/* {{{ s_mp_rshd(mp, p) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3056
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3057
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3058
   Shift mp rightward by p digits.  Maintains the invariant that
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3059
   digits above the precision are all zero.  Digits shifted off the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3060
   end are lost.  Cannot fail.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3061
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3062
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3063
void     s_mp_rshd(mp_int *mp, mp_size p)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3064
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3065
  mp_size  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3066
  mp_digit *src, *dst;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3067
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3068
  if(p == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3069
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3070
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3071
  /* Shortcut when all digits are to be shifted off */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3072
  if(p >= USED(mp)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3073
    s_mp_setz(DIGITS(mp), ALLOC(mp));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3074
    USED(mp) = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3075
    SIGN(mp) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3076
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3077
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3078
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3079
  /* Shift all the significant figures over as needed */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3080
  dst = MP_DIGITS(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3081
  src = dst + p;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3082
  for (ix = USED(mp) - p; ix > 0; ix--)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3083
    *dst++ = *src++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3084
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3085
  MP_USED(mp) -= p;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3086
  /* Fill the top digits with zeroes */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3087
  while (p-- > 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3088
    *dst++ = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3089
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3090
#if 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3091
  /* Strip off any leading zeroes    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3092
  s_mp_clamp(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3093
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3094
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3095
} /* end s_mp_rshd() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3096
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3097
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3098
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3099
/* {{{ s_mp_div_2(mp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3100
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3101
/* Divide by two -- take advantage of radix properties to do it fast      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3102
void     s_mp_div_2(mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3103
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3104
  s_mp_div_2d(mp, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3105
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3106
} /* end s_mp_div_2() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3107
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3108
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3109
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3110
/* {{{ s_mp_mul_2(mp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3111
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3112
mp_err s_mp_mul_2(mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3113
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3114
  mp_digit *pd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3115
  int      ix, used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3116
  mp_digit kin = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3117
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3118
  /* Shift digits leftward by 1 bit */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3119
  used = MP_USED(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3120
  pd = MP_DIGITS(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3121
  for (ix = 0; ix < used; ix++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3122
    mp_digit d = *pd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3123
    *pd++ = (d << 1) | kin;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3124
    kin = (d >> (DIGIT_BIT - 1));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3125
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3126
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3127
  /* Deal with rollover from last digit */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3128
  if (kin) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3129
    if (ix >= ALLOC(mp)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3130
      mp_err res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3131
      if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3132
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3133
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3134
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3135
    DIGIT(mp, ix) = kin;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3136
    USED(mp) += 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3137
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3138
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3139
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3140
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3141
} /* end s_mp_mul_2() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3142
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3143
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3144
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3145
/* {{{ s_mp_mod_2d(mp, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3146
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3147
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3148
  Remainder the integer by 2^d, where d is a number of bits.  This
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3149
  amounts to a bitwise AND of the value, and does not require the full
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3150
  division code
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3151
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3152
void     s_mp_mod_2d(mp_int *mp, mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3153
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3154
  mp_size  ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3155
  mp_size  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3156
  mp_digit dmask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3157
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3158
  if(ndig >= USED(mp))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3159
    return;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3160
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3161
  /* Flush all the bits above 2^d in its digit */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3162
  dmask = ((mp_digit)1 << nbit) - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3163
  DIGIT(mp, ndig) &= dmask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3164
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3165
  /* Flush all digits above the one with 2^d in it */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3166
  for(ix = ndig + 1; ix < USED(mp); ix++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3167
    DIGIT(mp, ix) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3168
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3169
  s_mp_clamp(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3170
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3171
} /* end s_mp_mod_2d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3172
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3173
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3174
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3175
/* {{{ s_mp_div_2d(mp, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3176
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3177
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3178
  Divide the integer by 2^d, where d is a number of bits.  This
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3179
  amounts to a bitwise shift of the value, and does not require the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3180
  full division code (used in Barrett reduction, see below)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3181
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3182
void     s_mp_div_2d(mp_int *mp, mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3183
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3184
  int       ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3185
  mp_digit  save, next, mask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3186
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3187
  s_mp_rshd(mp, d / DIGIT_BIT);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3188
  d %= DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3189
  if (d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3190
    mask = ((mp_digit)1 << d) - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3191
    save = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3192
    for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3193
      next = DIGIT(mp, ix) & mask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3194
      DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3195
      save = next;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3196
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3197
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3198
  s_mp_clamp(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3199
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3200
} /* end s_mp_div_2d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3201
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3202
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3203
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3204
/* {{{ s_mp_norm(a, b, *d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3205
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3206
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3207
  s_mp_norm(a, b, *d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3208
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3209
  Normalize a and b for division, where b is the divisor.  In order
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3210
  that we might make good guesses for quotient digits, we want the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3211
  leading digit of b to be at least half the radix, which we
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3212
  accomplish by multiplying a and b by a power of 2.  The exponent
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3213
  (shift count) is placed in *pd, so that the remainder can be shifted
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3214
  back at the end of the division process.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3215
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3216
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3217
mp_err   s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3218
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3219
  mp_digit  d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3220
  mp_digit  mask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3221
  mp_digit  b_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3222
  mp_err    res    = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3223
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3224
  d = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3225
  mask  = DIGIT_MAX & ~(DIGIT_MAX >> 1);        /* mask is msb of digit */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3226
  b_msd = DIGIT(b, USED(b) - 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3227
  while (!(b_msd & mask)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3228
    b_msd <<= 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3229
    ++d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3230
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3231
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3232
  if (d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3233
    MP_CHECKOK( s_mp_mul_2d(a, d) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3234
    MP_CHECKOK( s_mp_mul_2d(b, d) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3235
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3236
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3237
  *pd = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3238
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3239
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3240
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3241
} /* end s_mp_norm() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3242
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3243
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3244
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3245
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3246
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3247
/* {{{ Primitive digit arithmetic */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3248
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3249
/* {{{ s_mp_add_d(mp, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3250
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3251
/* Add d to |mp| in place                                                 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3252
mp_err   s_mp_add_d(mp_int *mp, mp_digit d)    /* unsigned digit addition */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3253
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3254
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3255
  mp_word   w, k = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3256
  mp_size   ix = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3257
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3258
  w = (mp_word)DIGIT(mp, 0) + d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3259
  DIGIT(mp, 0) = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3260
  k = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3261
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3262
  while(ix < USED(mp) && k) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3263
    w = (mp_word)DIGIT(mp, ix) + k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3264
    DIGIT(mp, ix) = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3265
    k = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3266
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3267
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3268
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3269
  if(k != 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3270
    mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3271
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3272
    if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3273
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3274
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3275
    DIGIT(mp, ix) = (mp_digit)k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3276
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3277
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3278
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3279
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3280
  mp_digit * pmp = MP_DIGITS(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3281
  mp_digit sum, mp_i, carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3282
  mp_err   res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3283
  int used = (int)MP_USED(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3284
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3285
  mp_i = *pmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3286
  *pmp++ = sum = d + mp_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3287
  carry = (sum < d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3288
  while (carry && --used > 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3289
    mp_i = *pmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3290
    *pmp++ = sum = carry + mp_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3291
    carry = !sum;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3292
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3293
  if (carry && !used) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3294
    /* mp is growing */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3295
    used = MP_USED(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3296
    MP_CHECKOK( s_mp_pad(mp, used + 1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3297
    MP_DIGIT(mp, used) = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3298
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3299
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3300
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3301
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3302
} /* end s_mp_add_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3303
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3304
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3305
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3306
/* {{{ s_mp_sub_d(mp, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3307
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3308
/* Subtract d from |mp| in place, assumes |mp| > d                        */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3309
mp_err   s_mp_sub_d(mp_int *mp, mp_digit d)    /* unsigned digit subtract */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3310
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3311
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3312
  mp_word   w, b = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3313
  mp_size   ix = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3314
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3315
  /* Compute initial subtraction    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3316
  w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3317
  b = CARRYOUT(w) ? 0 : 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3318
  DIGIT(mp, 0) = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3319
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3320
  /* Propagate borrows leftward     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3321
  while(b && ix < USED(mp)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3322
    w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3323
    b = CARRYOUT(w) ? 0 : 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3324
    DIGIT(mp, ix) = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3325
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3326
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3327
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3328
  /* Remove leading zeroes          */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3329
  s_mp_clamp(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3330
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3331
  /* If we have a borrow out, it's a violation of the input invariant */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3332
  if(b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3333
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3334
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3335
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3336
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3337
  mp_digit *pmp = MP_DIGITS(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3338
  mp_digit mp_i, diff, borrow;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3339
  mp_size  used = MP_USED(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3340
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3341
  mp_i = *pmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3342
  *pmp++ = diff = mp_i - d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3343
  borrow = (diff > mp_i);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3344
  while (borrow && --used) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3345
    mp_i = *pmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3346
    *pmp++ = diff = mp_i - borrow;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3347
    borrow = (diff > mp_i);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3348
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3349
  s_mp_clamp(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3350
  return (borrow && !used) ? MP_RANGE : MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3351
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3352
} /* end s_mp_sub_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3353
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3354
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3355
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3356
/* {{{ s_mp_mul_d(a, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3357
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3358
/* Compute a = a * d, single digit multiplication                         */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3359
mp_err   s_mp_mul_d(mp_int *a, mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3360
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3361
  mp_err  res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3362
  mp_size used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3363
  int     pow;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3364
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3365
  if (!d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3366
    mp_zero(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3367
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3368
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3369
  if (d == 1)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3370
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3371
  if (0 <= (pow = s_mp_ispow2d(d))) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3372
    return s_mp_mul_2d(a, (mp_digit)pow);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3373
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3374
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3375
  used = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3376
  MP_CHECKOK( s_mp_pad(a, used + 1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3377
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3378
  s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3379
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3380
  s_mp_clamp(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3381
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3382
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3383
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3384
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3385
} /* end s_mp_mul_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3386
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3387
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3388
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3389
/* {{{ s_mp_div_d(mp, d, r) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3390
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3391
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3392
  s_mp_div_d(mp, d, r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3393
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3394
  Compute the quotient mp = mp / d and remainder r = mp mod d, for a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3395
  single digit d.  If r is null, the remainder will be discarded.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3396
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3397
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3398
mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3399
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3400
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3401
  mp_word   w = 0, q;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3402
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3403
  mp_digit  w, q;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3404
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3405
  int       ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3406
  mp_err    res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3407
  mp_int    quot;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3408
  mp_int    rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3409
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3410
  if(d == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3411
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3412
  if (d == 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3413
    if (r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3414
      *r = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3415
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3416
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3417
  /* could check for power of 2 here, but mp_div_d does that. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3418
  if (MP_USED(mp) == 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3419
    mp_digit n   = MP_DIGIT(mp,0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3420
    mp_digit rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3421
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3422
    q   = n / d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3423
    rem = n % d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3424
    MP_DIGIT(mp,0) = q;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3425
    if (r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3426
      *r = rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3427
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3428
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3429
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3430
  MP_DIGITS(&rem)  = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3431
  MP_DIGITS(&quot) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3432
  /* Make room for the quotient */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3433
  MP_CHECKOK( mp_init_size(&quot, USED(mp), FLAG(mp)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3434
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3435
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3436
  for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3437
    w = (w << DIGIT_BIT) | DIGIT(mp, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3438
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3439
    if(w >= d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3440
      q = w / d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3441
      w = w % d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3442
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3443
      q = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3444
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3445
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3446
    s_mp_lshd(&quot, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3447
    DIGIT(&quot, 0) = (mp_digit)q;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3448
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3449
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3450
  {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3451
    mp_digit p;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3452
#if !defined(MP_ASSEMBLY_DIV_2DX1D)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3453
    mp_digit norm;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3454
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3455
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3456
    MP_CHECKOK( mp_init_copy(&rem, mp) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3457
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3458
#if !defined(MP_ASSEMBLY_DIV_2DX1D)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3459
    MP_DIGIT(&quot, 0) = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3460
    MP_CHECKOK( s_mp_norm(&rem, &quot, &norm) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3461
    if (norm)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3462
      d <<= norm;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3463
    MP_DIGIT(&quot, 0) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3464
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3465
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3466
    p = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3467
    for (ix = USED(&rem) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3468
      w = DIGIT(&rem, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3469
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3470
      if (p) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3471
        MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3472
      } else if (w >= d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3473
        q = w / d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3474
        w = w % d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3475
      } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3476
        q = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3477
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3478
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3479
      MP_CHECKOK( s_mp_lshd(&quot, 1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3480
      DIGIT(&quot, 0) = q;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3481
      p = w;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3482
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3483
#if !defined(MP_ASSEMBLY_DIV_2DX1D)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3484
    if (norm)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3485
      w >>= norm;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3486
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3487
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3488
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3489
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3490
  /* Deliver the remainder, if desired */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3491
  if(r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3492
    *r = (mp_digit)w;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3493
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3494
  s_mp_clamp(&quot);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3495
  mp_exch(&quot, mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3496
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3497
  mp_clear(&quot);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3498
  mp_clear(&rem);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3499
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3500
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3501
} /* end s_mp_div_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3502
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3503
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3504
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3505
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3506
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3507
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3508
/* {{{ Primitive full arithmetic */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3509
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3510
/* {{{ s_mp_add(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3511
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3512
/* Compute a = |a| + |b|                                                  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3513
mp_err   s_mp_add(mp_int *a, const mp_int *b)  /* magnitude addition      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3514
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3515
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3516
  mp_word   w = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3517
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3518
  mp_digit  d, sum, carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3519
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3520
  mp_digit *pa, *pb;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3521
  mp_size   ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3522
  mp_size   used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3523
  mp_err    res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3524
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3525
  /* Make sure a has enough precision for the output value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3526
  if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3527
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3528
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3529
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3530
    Add up all digits up to the precision of b.  If b had initially
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3531
    the same precision as a, or greater, we took care of it by the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3532
    padding step above, so there is no problem.  If b had initially
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3533
    less precision, we'll have to make sure the carry out is duly
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3534
    propagated upward among the higher-order digits of the sum.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3535
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3536
  pa = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3537
  pb = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3538
  used = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3539
  for(ix = 0; ix < used; ix++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3540
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3541
    w = w + *pa + *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3542
    *pa++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3543
    w = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3544
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3545
    d = *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3546
    sum = d + *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3547
    d = (sum < d);                      /* detect overflow */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3548
    *pa++ = sum += carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3549
    carry = d + (sum < carry);          /* detect overflow */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3550
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3551
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3552
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3553
  /* If we run out of 'b' digits before we're actually done, make
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3554
     sure the carries get propagated upward...
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3555
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3556
  used = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3557
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3558
  while (w && ix < used) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3559
    w = w + *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3560
    *pa++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3561
    w = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3562
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3563
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3564
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3565
  while (carry && ix < used) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3566
    sum = carry + *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3567
    *pa++ = sum;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3568
    carry = !sum;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3569
    ++ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3570
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3571
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3572
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3573
  /* If there's an overall carry out, increase precision and include
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3574
     it.  We could have done this initially, but why touch the memory
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3575
     allocator unless we're sure we have to?
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3576
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3577
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3578
  if (w) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3579
    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3580
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3581
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3582
    DIGIT(a, ix) = (mp_digit)w;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3583
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3584
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3585
  if (carry) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3586
    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3587
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3588
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3589
    DIGIT(a, used) = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3590
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3591
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3592
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3593
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3594
} /* end s_mp_add() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3595
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3596
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3597
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3598
/* Compute c = |a| + |b|         */ /* magnitude addition      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3599
mp_err   s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3600
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3601
  mp_digit *pa, *pb, *pc;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3602
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3603
  mp_word   w = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3604
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3605
  mp_digit  sum, carry = 0, d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3606
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3607
  mp_size   ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3608
  mp_size   used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3609
  mp_err    res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3610
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3611
  MP_SIGN(c) = MP_SIGN(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3612
  if (MP_USED(a) < MP_USED(b)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3613
    const mp_int *xch = a;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3614
    a = b;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3615
    b = xch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3616
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3617
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3618
  /* Make sure a has enough precision for the output value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3619
  if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3620
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3621
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3622
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3623
    Add up all digits up to the precision of b.  If b had initially
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3624
    the same precision as a, or greater, we took care of it by the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3625
    exchange step above, so there is no problem.  If b had initially
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3626
    less precision, we'll have to make sure the carry out is duly
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3627
    propagated upward among the higher-order digits of the sum.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3628
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3629
  pa = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3630
  pb = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3631
  pc = MP_DIGITS(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3632
  used = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3633
  for (ix = 0; ix < used; ix++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3634
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3635
    w = w + *pa++ + *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3636
    *pc++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3637
    w = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3638
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3639
    d = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3640
    sum = d + *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3641
    d = (sum < d);                      /* detect overflow */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3642
    *pc++ = sum += carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3643
    carry = d + (sum < carry);          /* detect overflow */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3644
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3645
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3646
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3647
  /* If we run out of 'b' digits before we're actually done, make
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3648
     sure the carries get propagated upward...
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3649
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3650
  for (used = MP_USED(a); ix < used; ++ix) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3651
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3652
    w = w + *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3653
    *pc++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3654
    w = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3655
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3656
    *pc++ = sum = carry + *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3657
    carry = (sum < carry);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3658
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3659
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3660
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3661
  /* If there's an overall carry out, increase precision and include
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3662
     it.  We could have done this initially, but why touch the memory
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3663
     allocator unless we're sure we have to?
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3664
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3665
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3666
  if (w) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3667
    if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3668
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3669
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3670
    DIGIT(c, used) = (mp_digit)w;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3671
    ++used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3672
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3673
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3674
  if (carry) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3675
    if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3676
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3677
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3678
    DIGIT(c, used) = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3679
    ++used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3680
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3681
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3682
  MP_USED(c) = used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3683
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3684
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3685
/* {{{ s_mp_add_offset(a, b, offset) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3686
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3687
/* Compute a = |a| + ( |b| * (RADIX ** offset) )             */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3688
mp_err   s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3689
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3690
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3691
  mp_word   w, k = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3692
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3693
  mp_digit  d, sum, carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3694
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3695
  mp_size   ib;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3696
  mp_size   ia;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3697
  mp_size   lim;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3698
  mp_err    res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3699
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3700
  /* Make sure a has enough precision for the output value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3701
  lim = MP_USED(b) + offset;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3702
  if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3703
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3704
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3705
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3706
    Add up all digits up to the precision of b.  If b had initially
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3707
    the same precision as a, or greater, we took care of it by the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3708
    padding step above, so there is no problem.  If b had initially
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3709
    less precision, we'll have to make sure the carry out is duly
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3710
    propagated upward among the higher-order digits of the sum.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3711
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3712
  lim = USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3713
  for(ib = 0, ia = offset; ib < lim; ib++, ia++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3714
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3715
    w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3716
    DIGIT(a, ia) = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3717
    k = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3718
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3719
    d = MP_DIGIT(a, ia);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3720
    sum = d + MP_DIGIT(b, ib);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3721
    d = (sum < d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3722
    MP_DIGIT(a,ia) = sum += carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3723
    carry = d + (sum < carry);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3724
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3725
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3726
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3727
  /* If we run out of 'b' digits before we're actually done, make
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3728
     sure the carries get propagated upward...
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3729
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3730
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3731
  for (lim = MP_USED(a); k && (ia < lim); ++ia) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3732
    w = (mp_word)DIGIT(a, ia) + k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3733
    DIGIT(a, ia) = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3734
    k = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3735
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3736
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3737
  for (lim = MP_USED(a); carry && (ia < lim); ++ia) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3738
    d = MP_DIGIT(a, ia);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3739
    MP_DIGIT(a,ia) = sum = d + carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3740
    carry = (sum < d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3741
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3742
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3743
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3744
  /* If there's an overall carry out, increase precision and include
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3745
     it.  We could have done this initially, but why touch the memory
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3746
     allocator unless we're sure we have to?
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3747
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3748
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3749
  if(k) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3750
    if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3751
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3752
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3753
    DIGIT(a, ia) = (mp_digit)k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3754
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3755
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3756
  if (carry) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3757
    if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3758
      return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3759
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3760
    DIGIT(a, lim) = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3761
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3762
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3763
  s_mp_clamp(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3764
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3765
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3766
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3767
} /* end s_mp_add_offset() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3768
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3769
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3770
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3771
/* {{{ s_mp_sub(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3772
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3773
/* Compute a = |a| - |b|, assumes |a| >= |b|                              */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3774
mp_err   s_mp_sub(mp_int *a, const mp_int *b)  /* magnitude subtract      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3775
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3776
  mp_digit *pa, *pb, *limit;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3777
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3778
  mp_sword  w = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3779
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3780
  mp_digit  d, diff, borrow = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3781
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3782
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3783
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3784
    Subtract and propagate borrow.  Up to the precision of b, this
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3785
    accounts for the digits of b; after that, we just make sure the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3786
    carries get to the right place.  This saves having to pad b out to
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3787
    the precision of a just to make the loops work right...
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3788
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3789
  pa = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3790
  pb = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3791
  limit = pb + MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3792
  while (pb < limit) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3793
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3794
    w = w + *pa - *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3795
    *pa++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3796
    w >>= MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3797
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3798
    d = *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3799
    diff = d - *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3800
    d = (diff > d);                             /* detect borrow */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3801
    if (borrow && --diff == MP_DIGIT_MAX)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3802
      ++d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3803
    *pa++ = diff;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3804
    borrow = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3805
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3806
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3807
  limit = MP_DIGITS(a) + MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3808
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3809
  while (w && pa < limit) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3810
    w = w + *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3811
    *pa++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3812
    w >>= MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3813
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3814
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3815
  while (borrow && pa < limit) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3816
    d = *pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3817
    *pa++ = diff = d - borrow;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3818
    borrow = (diff > d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3819
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3820
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3821
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3822
  /* Clobber any leading zeroes we created    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3823
  s_mp_clamp(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3824
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3825
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3826
     If there was a borrow out, then |b| > |a| in violation
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3827
     of our input invariant.  We've already done the work,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3828
     but we'll at least complain about it...
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3829
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3830
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3831
  return w ? MP_RANGE : MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3832
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3833
  return borrow ? MP_RANGE : MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3834
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3835
} /* end s_mp_sub() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3836
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3837
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3838
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3839
/* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3840
mp_err   s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3841
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3842
  mp_digit *pa, *pb, *pc;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3843
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3844
  mp_sword  w = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3845
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3846
  mp_digit  d, diff, borrow = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3847
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3848
  int       ix, limit;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3849
  mp_err    res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3850
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3851
  MP_SIGN(c) = MP_SIGN(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3852
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3853
  /* Make sure a has enough precision for the output value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3854
  if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3855
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3856
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3857
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3858
    Subtract and propagate borrow.  Up to the precision of b, this
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3859
    accounts for the digits of b; after that, we just make sure the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3860
    carries get to the right place.  This saves having to pad b out to
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3861
    the precision of a just to make the loops work right...
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3862
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3863
  pa = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3864
  pb = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3865
  pc = MP_DIGITS(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3866
  limit = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3867
  for (ix = 0; ix < limit; ++ix) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3868
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3869
    w = w + *pa++ - *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3870
    *pc++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3871
    w >>= MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3872
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3873
    d = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3874
    diff = d - *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3875
    d = (diff > d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3876
    if (borrow && --diff == MP_DIGIT_MAX)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3877
      ++d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3878
    *pc++ = diff;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3879
    borrow = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3880
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3881
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3882
  for (limit = MP_USED(a); ix < limit; ++ix) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3883
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3884
    w = w + *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3885
    *pc++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3886
    w >>= MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3887
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3888
    d = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3889
    *pc++ = diff = d - borrow;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3890
    borrow = (diff > d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3891
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3892
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3893
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3894
  /* Clobber any leading zeroes we created    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3895
  MP_USED(c) = ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3896
  s_mp_clamp(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3897
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3898
  /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3899
     If there was a borrow out, then |b| > |a| in violation
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3900
     of our input invariant.  We've already done the work,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3901
     but we'll at least complain about it...
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3902
   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3903
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3904
  return w ? MP_RANGE : MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3905
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3906
  return borrow ? MP_RANGE : MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3907
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3908
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3909
/* {{{ s_mp_mul(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3910
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3911
/* Compute a = |a| * |b|                                                  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3912
mp_err   s_mp_mul(mp_int *a, const mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3913
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3914
  return mp_mul(a, b, a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3915
} /* end s_mp_mul() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3916
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3917
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3918
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3919
#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3920
/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3921
#define MP_MUL_DxD(a, b, Phi, Plo) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3922
  { unsigned long long product = (unsigned long long)a * b; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3923
    Plo = (mp_digit)product; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3924
    Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3925
#elif defined(OSF1)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3926
#define MP_MUL_DxD(a, b, Phi, Plo) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3927
  { Plo = asm ("mulq %a0, %a1, %v0", a, b);\
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3928
    Phi = asm ("umulh %a0, %a1, %v0", a, b); }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3929
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3930
#define MP_MUL_DxD(a, b, Phi, Plo) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3931
  { mp_digit a0b1, a1b0; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3932
    Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3933
    Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3934
    a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3935
    a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3936
    a1b0 += a0b1; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3937
    Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3938
    if (a1b0 < a0b1)  \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3939
      Phi += MP_HALF_RADIX; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3940
    a1b0 <<= MP_HALF_DIGIT_BIT; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3941
    Plo += a1b0; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3942
    if (Plo < a1b0) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3943
      ++Phi; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3944
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3945
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3946
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3947
#if !defined(MP_ASSEMBLY_MULTIPLY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3948
/* c = a * b */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3949
void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3950
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3951
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3952
  mp_digit   d = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3953
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3954
  /* Inner product:  Digits of a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3955
  while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3956
    mp_word w = ((mp_word)b * *a++) + d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3957
    *c++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3958
    d = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3959
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3960
  *c = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3961
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3962
  mp_digit carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3963
  while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3964
    mp_digit a_i = *a++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3965
    mp_digit a0b0, a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3966
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3967
    MP_MUL_DxD(a_i, b, a1b1, a0b0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3968
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3969
    a0b0 += carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3970
    if (a0b0 < carry)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3971
      ++a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3972
    *c++ = a0b0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3973
    carry = a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3974
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3975
  *c = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3976
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3977
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3978
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3979
/* c += a * b */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3980
void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3981
                              mp_digit *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3982
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3983
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3984
  mp_digit   d = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3985
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3986
  /* Inner product:  Digits of a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3987
  while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3988
    mp_word w = ((mp_word)b * *a++) + *c + d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3989
    *c++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3990
    d = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3991
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3992
  *c = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3993
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3994
  mp_digit carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3995
  while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3996
    mp_digit a_i = *a++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3997
    mp_digit a0b0, a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3998
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  3999
    MP_MUL_DxD(a_i, b, a1b1, a0b0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4000
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4001
    a0b0 += carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4002
    if (a0b0 < carry)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4003
      ++a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4004
    a0b0 += a_i = *c;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4005
    if (a0b0 < a_i)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4006
      ++a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4007
    *c++ = a0b0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4008
    carry = a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4009
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4010
  *c = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4011
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4012
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4013
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4014
/* Presently, this is only used by the Montgomery arithmetic code. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4015
/* c += a * b */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4016
void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4017
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4018
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4019
  mp_digit   d = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4020
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4021
  /* Inner product:  Digits of a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4022
  while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4023
    mp_word w = ((mp_word)b * *a++) + *c + d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4024
    *c++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4025
    d = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4026
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4027
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4028
  while (d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4029
    mp_word w = (mp_word)*c + d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4030
    *c++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4031
    d = CARRYOUT(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4032
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4033
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4034
  mp_digit carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4035
  while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4036
    mp_digit a_i = *a++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4037
    mp_digit a0b0, a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4038
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4039
    MP_MUL_DxD(a_i, b, a1b1, a0b0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4040
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4041
    a0b0 += carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4042
    if (a0b0 < carry)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4043
      ++a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4044
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4045
    a0b0 += a_i = *c;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4046
    if (a0b0 < a_i)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4047
      ++a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4048
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4049
    *c++ = a0b0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4050
    carry = a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4051
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4052
  while (carry) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4053
    mp_digit c_i = *c;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4054
    carry += c_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4055
    *c++ = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4056
    carry = carry < c_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4057
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4058
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4059
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4060
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4061
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4062
#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4063
/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4064
#define MP_SQR_D(a, Phi, Plo) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4065
  { unsigned long long square = (unsigned long long)a * a; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4066
    Plo = (mp_digit)square; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4067
    Phi = (mp_digit)(square >> MP_DIGIT_BIT); }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4068
#elif defined(OSF1)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4069
#define MP_SQR_D(a, Phi, Plo) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4070
  { Plo = asm ("mulq  %a0, %a0, %v0", a);\
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4071
    Phi = asm ("umulh %a0, %a0, %v0", a); }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4072
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4073
#define MP_SQR_D(a, Phi, Plo) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4074
  { mp_digit Pmid; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4075
    Plo  = (a  & MP_HALF_DIGIT_MAX) * (a  & MP_HALF_DIGIT_MAX); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4076
    Phi  = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4077
    Pmid = (a  & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4078
    Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1);  \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4079
    Pmid <<= (MP_HALF_DIGIT_BIT + 1);  \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4080
    Plo += Pmid;  \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4081
    if (Plo < Pmid)  \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4082
      ++Phi;  \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4083
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4084
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4085
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4086
#if !defined(MP_ASSEMBLY_SQUARE)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4087
/* Add the squares of the digits of a to the digits of b. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4088
void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4089
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4090
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4091
  mp_word  w;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4092
  mp_digit d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4093
  mp_size  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4094
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4095
  w  = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4096
#define ADD_SQUARE(n) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4097
    d = pa[n]; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4098
    w += (d * (mp_word)d) + ps[2*n]; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4099
    ps[2*n] = ACCUM(w); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4100
    w = (w >> DIGIT_BIT) + ps[2*n+1]; \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4101
    ps[2*n+1] = ACCUM(w); \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4102
    w = (w >> DIGIT_BIT)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4103
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4104
  for (ix = a_len; ix >= 4; ix -= 4) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4105
    ADD_SQUARE(0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4106
    ADD_SQUARE(1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4107
    ADD_SQUARE(2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4108
    ADD_SQUARE(3);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4109
    pa += 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4110
    ps += 8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4111
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4112
  if (ix) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4113
    ps += 2*ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4114
    pa += ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4115
    switch (ix) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4116
    case 3: ADD_SQUARE(-3); /* FALLTHRU */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4117
    case 2: ADD_SQUARE(-2); /* FALLTHRU */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4118
    case 1: ADD_SQUARE(-1); /* FALLTHRU */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4119
    case 0: break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4120
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4121
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4122
  while (w) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4123
    w += *ps;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4124
    *ps++ = ACCUM(w);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4125
    w = (w >> DIGIT_BIT);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4126
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4127
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4128
  mp_digit carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4129
  while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4130
    mp_digit a_i = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4131
    mp_digit a0a0, a1a1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4132
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4133
    MP_SQR_D(a_i, a1a1, a0a0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4134
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4135
    /* here a1a1 and a0a0 constitute a_i ** 2 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4136
    a0a0 += carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4137
    if (a0a0 < carry)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4138
      ++a1a1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4139
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4140
    /* now add to ps */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4141
    a0a0 += a_i = *ps;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4142
    if (a0a0 < a_i)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4143
      ++a1a1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4144
    *ps++ = a0a0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4145
    a1a1 += a_i = *ps;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4146
    carry = (a1a1 < a_i);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4147
    *ps++ = a1a1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4148
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4149
  while (carry) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4150
    mp_digit s_i = *ps;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4151
    carry += s_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4152
    *ps++ = carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4153
    carry = carry < s_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4154
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4155
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4156
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4157
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4158
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4159
#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4160
&& !defined(MP_ASSEMBLY_DIV_2DX1D)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4161
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4162
** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4163
** so its high bit is 1.   This code is from NSPR.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4164
*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4165
mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4166
                       mp_digit *qp, mp_digit *rp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4167
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4168
    mp_digit d1, d0, q1, q0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4169
    mp_digit r1, r0, m;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4170
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4171
    d1 = divisor >> MP_HALF_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4172
    d0 = divisor & MP_HALF_DIGIT_MAX;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4173
    r1 = Nhi % d1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4174
    q1 = Nhi / d1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4175
    m = q1 * d0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4176
    r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4177
    if (r1 < m) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4178
        q1--, r1 += divisor;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4179
        if (r1 >= divisor && r1 < m) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4180
            q1--, r1 += divisor;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4181
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4182
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4183
    r1 -= m;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4184
    r0 = r1 % d1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4185
    q0 = r1 / d1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4186
    m = q0 * d0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4187
    r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4188
    if (r0 < m) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4189
        q0--, r0 += divisor;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4190
        if (r0 >= divisor && r0 < m) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4191
            q0--, r0 += divisor;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4192
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4193
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4194
    if (qp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4195
        *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4196
    if (rp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4197
        *rp = r0 - m;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4198
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4199
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4200
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4201
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4202
#if MP_SQUARE
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4203
/* {{{ s_mp_sqr(a) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4204
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4205
mp_err   s_mp_sqr(mp_int *a)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4206
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4207
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4208
  mp_int   tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4209
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4210
  if((res = mp_init_size(&tmp, 2 * USED(a), FLAG(a))) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4211
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4212
  res = mp_sqr(a, &tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4213
  if (res == MP_OKAY) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4214
    s_mp_exch(&tmp, a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4215
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4216
  mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4217
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4218
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4219
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4220
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4221
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4222
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4223
/* {{{ s_mp_div(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4224
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4225
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4226
  s_mp_div(a, b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4227
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4228
  Compute a = a / b and b = a mod b.  Assumes b > a.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4229
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4230
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4231
mp_err   s_mp_div(mp_int *rem,  /* i: dividend, o: remainder */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4232
                  mp_int *div,  /* i: divisor                */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4233
                  mp_int *quot) /* i: 0;        o: quotient  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4234
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4235
  mp_int   part, t;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4236
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4237
  mp_word  q_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4238
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4239
  mp_digit q_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4240
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4241
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4242
  mp_digit d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4243
  mp_digit div_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4244
  int      ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4245
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4246
  if(mp_cmp_z(div) == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4247
    return MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4248
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4249
  /* Shortcut if divisor is power of two */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4250
  if((ix = s_mp_ispow2(div)) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4251
    MP_CHECKOK( mp_copy(rem, quot) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4252
    s_mp_div_2d(quot, (mp_digit)ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4253
    s_mp_mod_2d(rem,  (mp_digit)ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4254
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4255
    return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4256
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4257
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4258
  DIGITS(&t) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4259
  MP_SIGN(rem) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4260
  MP_SIGN(div) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4261
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4262
  /* A working temporary for division     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4263
  MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem), FLAG(rem)));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4264
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4265
  /* Normalize to optimize guessing       */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4266
  MP_CHECKOK( s_mp_norm(rem, div, &d) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4267
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4268
  part = *rem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4269
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4270
  /* Perform the division itself...woo!   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4271
  MP_USED(quot) = MP_ALLOC(quot);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4272
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4273
  /* Find a partial substring of rem which is at least div */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4274
  /* If we didn't find one, we're finished dividing    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4275
  while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4276
    int i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4277
    int unusedRem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4278
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4279
    unusedRem = MP_USED(rem) - MP_USED(div);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4280
    MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4281
    MP_ALLOC(&part)  = MP_ALLOC(rem)  - unusedRem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4282
    MP_USED(&part)   = MP_USED(div);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4283
    if (s_mp_cmp(&part, div) < 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4284
      -- unusedRem;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4285
#if MP_ARGCHK == 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4286
      assert(unusedRem >= 0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4287
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4288
      -- MP_DIGITS(&part);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4289
      ++ MP_USED(&part);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4290
      ++ MP_ALLOC(&part);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4291
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4292
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4293
    /* Compute a guess for the next quotient digit       */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4294
    q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4295
    div_msd = MP_DIGIT(div, MP_USED(div) - 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4296
    if (q_msd >= div_msd) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4297
      q_msd = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4298
    } else if (MP_USED(&part) > 1) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4299
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4300
      q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4301
      q_msd /= div_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4302
      if (q_msd == RADIX)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4303
        --q_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4304
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4305
      mp_digit r;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4306
      MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4307
                                  div_msd, &q_msd, &r) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4308
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4309
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4310
      q_msd = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4311
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4312
#if MP_ARGCHK == 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4313
    assert(q_msd > 0); /* This case should never occur any more. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4314
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4315
    if (q_msd <= 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4316
      break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4317
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4318
    /* See what that multiplies out to                   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4319
    mp_copy(div, &t);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4320
    MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4321
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4322
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4323
       If it's too big, back it off.  We should not have to do this
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4324
       more than once, or, in rare cases, twice.  Knuth describes a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4325
       method by which this could be reduced to a maximum of once, but
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4326
       I didn't implement that here.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4327
     * When using s_mpv_div_2dx1d, we may have to do this 3 times.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4328
     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4329
    for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4330
      --q_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4331
      s_mp_sub(&t, div);        /* t -= div */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4332
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4333
    if (i < 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4334
      res = MP_RANGE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4335
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4336
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4337
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4338
    /* At this point, q_msd should be the right next digit   */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4339
    MP_CHECKOK( s_mp_sub(&part, &t) );  /* part -= t */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4340
    s_mp_clamp(rem);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4341
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4342
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4343
      Include the digit in the quotient.  We allocated enough memory
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4344
      for any quotient we could ever possibly get, so we should not
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4345
      have to check for failures here
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4346
     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4347
    MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4348
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4349
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4350
  /* Denormalize remainder                */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4351
  if (d) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4352
    s_mp_div_2d(rem, d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4353
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4354
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4355
  s_mp_clamp(quot);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4356
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4357
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4358
  mp_clear(&t);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4359
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4360
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4361
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4362
} /* end s_mp_div() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4363
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4364
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4365
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4366
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4367
/* {{{ s_mp_2expt(a, k) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4368
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4369
mp_err   s_mp_2expt(mp_int *a, mp_digit k)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4370
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4371
  mp_err    res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4372
  mp_size   dig, bit;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4373
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4374
  dig = k / DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4375
  bit = k % DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4376
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4377
  mp_zero(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4378
  if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4379
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4380
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4381
  DIGIT(a, dig) |= ((mp_digit)1 << bit);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4382
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4383
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4384
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4385
} /* end s_mp_2expt() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4386
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4387
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4388
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4389
/* {{{ s_mp_reduce(x, m, mu) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4390
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4391
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4392
  Compute Barrett reduction, x (mod m), given a precomputed value for
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4393
  mu = b^2k / m, where b = RADIX and k = #digits(m).  This should be
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4394
  faster than straight division, when many reductions by the same
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4395
  value of m are required (such as in modular exponentiation).  This
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4396
  can nearly halve the time required to do modular exponentiation,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4397
  as compared to using the full integer divide to reduce.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4398
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4399
  This algorithm was derived from the _Handbook of Applied
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4400
  Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4401
  pp. 603-604.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4402
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4403
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4404
mp_err   s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4405
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4406
  mp_int   q;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4407
  mp_err   res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4408
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4409
  if((res = mp_init_copy(&q, x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4410
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4411
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4412
  s_mp_rshd(&q, USED(m) - 1);  /* q1 = x / b^(k-1)  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4413
  s_mp_mul(&q, mu);            /* q2 = q1 * mu      */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4414
  s_mp_rshd(&q, USED(m) + 1);  /* q3 = q2 / b^(k+1) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4415
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4416
  /* x = x mod b^(k+1), quick (no division) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4417
  s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4418
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4419
  /* q = q * m mod b^(k+1), quick (no division) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4420
  s_mp_mul(&q, m);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4421
  s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4422
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4423
  /* x = x - q */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4424
  if((res = mp_sub(x, &q, x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4425
    goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4426
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4427
  /* If x < 0, add b^(k+1) to it */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4428
  if(mp_cmp_z(x) < 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4429
    mp_set(&q, 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4430
    if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4431
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4432
    if((res = mp_add(x, &q, x)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4433
      goto CLEANUP;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4434
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4435
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4436
  /* Back off if it's too big */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4437
  while(mp_cmp(x, m) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4438
    if((res = s_mp_sub(x, m)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4439
      break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4440
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4441
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4442
 CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4443
  mp_clear(&q);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4444
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4445
  return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4446
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4447
} /* end s_mp_reduce() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4448
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4449
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4450
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4451
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4452
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4453
/* {{{ Primitive comparisons */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4454
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4455
/* {{{ s_mp_cmp(a, b) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4456
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4457
/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b           */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4458
int      s_mp_cmp(const mp_int *a, const mp_int *b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4459
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4460
  mp_size used_a = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4461
  {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4462
    mp_size used_b = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4463
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4464
    if (used_a > used_b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4465
      goto IS_GT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4466
    if (used_a < used_b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4467
      goto IS_LT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4468
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4469
  {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4470
    mp_digit *pa, *pb;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4471
    mp_digit da = 0, db = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4472
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4473
#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4474
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4475
    pa = MP_DIGITS(a) + used_a;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4476
    pb = MP_DIGITS(b) + used_a;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4477
    while (used_a >= 4) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4478
      pa     -= 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4479
      pb     -= 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4480
      used_a -= 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4481
      CMP_AB(3);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4482
      CMP_AB(2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4483
      CMP_AB(1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4484
      CMP_AB(0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4485
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4486
    while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4487
      /* do nothing */;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4488
done:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4489
    if (da > db)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4490
      goto IS_GT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4491
    if (da < db)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4492
      goto IS_LT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4493
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4494
  return MP_EQ;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4495
IS_LT:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4496
  return MP_LT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4497
IS_GT:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4498
  return MP_GT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4499
} /* end s_mp_cmp() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4500
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4501
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4502
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4503
/* {{{ s_mp_cmp_d(a, d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4504
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4505
/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d             */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4506
int      s_mp_cmp_d(const mp_int *a, mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4507
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4508
  if(USED(a) > 1)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4509
    return MP_GT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4510
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4511
  if(DIGIT(a, 0) < d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4512
    return MP_LT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4513
  else if(DIGIT(a, 0) > d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4514
    return MP_GT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4515
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4516
    return MP_EQ;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4517
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4518
} /* end s_mp_cmp_d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4519
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4520
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4521
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4522
/* {{{ s_mp_ispow2(v) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4523
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4524
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4525
  Returns -1 if the value is not a power of two; otherwise, it returns
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4526
  k such that v = 2^k, i.e. lg(v).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4527
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4528
int      s_mp_ispow2(const mp_int *v)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4529
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4530
  mp_digit d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4531
  int      extra = 0, ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4532
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4533
  ix = MP_USED(v) - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4534
  d = MP_DIGIT(v, ix); /* most significant digit of v */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4535
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4536
  extra = s_mp_ispow2d(d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4537
  if (extra < 0 || ix == 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4538
    return extra;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4539
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4540
  while (--ix >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4541
    if (DIGIT(v, ix) != 0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4542
      return -1; /* not a power of two */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4543
    extra += MP_DIGIT_BIT;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4544
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4545
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4546
  return extra;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4547
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4548
} /* end s_mp_ispow2() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4549
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4550
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4551
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4552
/* {{{ s_mp_ispow2d(d) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4553
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4554
int      s_mp_ispow2d(mp_digit d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4555
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4556
  if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4557
    int pow = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4558
#if defined (MP_USE_UINT_DIGIT)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4559
    if (d & 0xffff0000U)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4560
      pow += 16;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4561
    if (d & 0xff00ff00U)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4562
      pow += 8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4563
    if (d & 0xf0f0f0f0U)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4564
      pow += 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4565
    if (d & 0xccccccccU)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4566
      pow += 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4567
    if (d & 0xaaaaaaaaU)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4568
      pow += 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4569
#elif defined(MP_USE_LONG_LONG_DIGIT)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4570
    if (d & 0xffffffff00000000ULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4571
      pow += 32;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4572
    if (d & 0xffff0000ffff0000ULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4573
      pow += 16;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4574
    if (d & 0xff00ff00ff00ff00ULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4575
      pow += 8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4576
    if (d & 0xf0f0f0f0f0f0f0f0ULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4577
      pow += 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4578
    if (d & 0xccccccccccccccccULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4579
      pow += 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4580
    if (d & 0xaaaaaaaaaaaaaaaaULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4581
      pow += 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4582
#elif defined(MP_USE_LONG_DIGIT)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4583
    if (d & 0xffffffff00000000UL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4584
      pow += 32;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4585
    if (d & 0xffff0000ffff0000UL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4586
      pow += 16;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4587
    if (d & 0xff00ff00ff00ff00UL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4588
      pow += 8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4589
    if (d & 0xf0f0f0f0f0f0f0f0UL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4590
      pow += 4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4591
    if (d & 0xccccccccccccccccUL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4592
      pow += 2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4593
    if (d & 0xaaaaaaaaaaaaaaaaUL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4594
      pow += 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4595
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4596
#error "unknown type for mp_digit"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4597
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4598
    return pow;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4599
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4600
  return -1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4601
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4602
} /* end s_mp_ispow2d() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4603
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4604
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4605
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4606
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4607
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4608
/* {{{ Primitive I/O helpers */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4609
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4610
/* {{{ s_mp_tovalue(ch, r) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4611
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4612
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4613
  Convert the given character to its digit value, in the given radix.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4614
  If the given character is not understood in the given radix, -1 is
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4615
  returned.  Otherwise the digit's numeric value is returned.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4616
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4617
  The results will be odd if you use a radix < 2 or > 62, you are
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4618
  expected to know what you're up to.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4619
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4620
int      s_mp_tovalue(char ch, int r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4621
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4622
  int    val, xch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4623
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4624
  if(r > 36)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4625
    xch = ch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4626
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4627
    xch = toupper(ch);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4628
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4629
  if(isdigit(xch))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4630
    val = xch - '0';
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4631
  else if(isupper(xch))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4632
    val = xch - 'A' + 10;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4633
  else if(islower(xch))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4634
    val = xch - 'a' + 36;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4635
  else if(xch == '+')
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4636
    val = 62;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4637
  else if(xch == '/')
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4638
    val = 63;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4639
  else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4640
    return -1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4641
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4642
  if(val < 0 || val >= r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4643
    return -1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4644
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4645
  return val;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4646
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4647
} /* end s_mp_tovalue() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4648
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4649
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4650
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4651
/* {{{ s_mp_todigit(val, r, low) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4652
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4653
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4654
  Convert val to a radix-r digit, if possible.  If val is out of range
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4655
  for r, returns zero.  Otherwise, returns an ASCII character denoting
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4656
  the value in the given radix.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4657
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4658
  The results may be odd if you use a radix < 2 or > 64, you are
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4659
  expected to know what you're doing.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4660
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4661
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4662
char     s_mp_todigit(mp_digit val, int r, int low)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4663
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4664
  char   ch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4665
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4666
  if(val >= r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4667
    return 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4668
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4669
  ch = s_dmap_1[val];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4670
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4671
  if(r <= 36 && low)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4672
    ch = tolower(ch);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4673
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4674
  return ch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4675
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4676
} /* end s_mp_todigit() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4677
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4678
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4679
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4680
/* {{{ s_mp_outlen(bits, radix) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4681
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4682
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4683
   Return an estimate for how long a string is needed to hold a radix
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4684
   r representation of a number with 'bits' significant bits, plus an
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4685
   extra for a zero terminator (assuming C style strings here)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4686
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4687
int      s_mp_outlen(int bits, int r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4688
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4689
  return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4690
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4691
} /* end s_mp_outlen() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4692
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4693
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4694
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4695
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4696
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4697
/* {{{ mp_read_unsigned_octets(mp, str, len) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4698
/* mp_read_unsigned_octets(mp, str, len)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4699
   Read in a raw value (base 256) into the given mp_int
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4700
   No sign bit, number is positive.  Leading zeros ignored.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4701
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4702
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4703
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4704
mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4705
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4706
  int            count;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4707
  mp_err         res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4708
  mp_digit       d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4709
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4710
  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4711
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4712
  mp_zero(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4713
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4714
  count = len % sizeof(mp_digit);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4715
  if (count) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4716
    for (d = 0; count-- > 0; --len) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4717
      d = (d << 8) | *str++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4718
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4719
    MP_DIGIT(mp, 0) = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4720
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4721
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4722
  /* Read the rest of the digits */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4723
  for(; len > 0; len -= sizeof(mp_digit)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4724
    for (d = 0, count = sizeof(mp_digit); count > 0; --count) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4725
      d = (d << 8) | *str++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4726
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4727
    if (MP_EQ == mp_cmp_z(mp)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4728
      if (!d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4729
        continue;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4730
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4731
      if((res = s_mp_lshd(mp, 1)) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4732
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4733
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4734
    MP_DIGIT(mp, 0) = d;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4735
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4736
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4737
} /* end mp_read_unsigned_octets() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4738
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4739
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4740
/* {{{ mp_unsigned_octet_size(mp) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4741
int
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4742
mp_unsigned_octet_size(const mp_int *mp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4743
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4744
  int  bytes;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4745
  int  ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4746
  mp_digit  d = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4747
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4748
  ARGCHK(mp != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4749
  ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4750
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4751
  bytes = (USED(mp) * sizeof(mp_digit));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4752
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4753
  /* subtract leading zeros. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4754
  /* Iterate over each digit... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4755
  for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4756
    d = DIGIT(mp, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4757
    if (d)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4758
        break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4759
    bytes -= sizeof(d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4760
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4761
  if (!bytes)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4762
    return 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4763
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4764
  /* Have MSD, check digit bytes, high order first */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4765
  for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4766
    unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4767
    if (x)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4768
        break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4769
    --bytes;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4770
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4771
  return bytes;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4772
} /* end mp_unsigned_octet_size() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4773
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4774
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4775
/* {{{ mp_to_unsigned_octets(mp, str) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4776
/* output a buffer of big endian octets no longer than specified. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4777
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4778
mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4779
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4780
  int  ix, pos = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4781
  int  bytes;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4782
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4783
  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4784
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4785
  bytes = mp_unsigned_octet_size(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4786
  ARGCHK(bytes <= maxlen, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4787
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4788
  /* Iterate over each digit... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4789
  for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4790
    mp_digit  d = DIGIT(mp, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4791
    int       jx;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4792
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4793
    /* Unpack digit bytes, high order first */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4794
    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4795
      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4796
      if (!pos && !x)   /* suppress leading zeros */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4797
        continue;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4798
      str[pos++] = x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4799
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4800
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4801
  if (!pos)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4802
    str[pos++] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4803
  return pos;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4804
} /* end mp_to_unsigned_octets() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4805
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4806
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4807
/* {{{ mp_to_signed_octets(mp, str) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4808
/* output a buffer of big endian octets no longer than specified. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4809
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4810
mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4811
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4812
  int  ix, pos = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4813
  int  bytes;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4814
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4815
  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4816
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4817
  bytes = mp_unsigned_octet_size(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4818
  ARGCHK(bytes <= maxlen, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4819
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4820
  /* Iterate over each digit... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4821
  for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4822
    mp_digit  d = DIGIT(mp, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4823
    int       jx;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4824
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4825
    /* Unpack digit bytes, high order first */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4826
    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4827
      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4828
      if (!pos) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4829
        if (!x)         /* suppress leading zeros */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4830
          continue;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4831
        if (x & 0x80) { /* add one leading zero to make output positive.  */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4832
          ARGCHK(bytes + 1 <= maxlen, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4833
          if (bytes + 1 > maxlen)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4834
            return MP_BADARG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4835
          str[pos++] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4836
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4837
      }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4838
      str[pos++] = x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4839
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4840
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4841
  if (!pos)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4842
    str[pos++] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4843
  return pos;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4844
} /* end mp_to_signed_octets() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4845
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4846
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4847
/* {{{ mp_to_fixlen_octets(mp, str) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4848
/* output a buffer of big endian octets exactly as long as requested. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4849
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4850
mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4851
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4852
  int  ix, pos = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4853
  int  bytes;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4854
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4855
  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4856
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4857
  bytes = mp_unsigned_octet_size(mp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4858
  ARGCHK(bytes <= length, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4859
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4860
  /* place any needed leading zeros */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4861
  for (;length > bytes; --length) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4862
        *str++ = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4863
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4864
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4865
  /* Iterate over each digit... */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4866
  for(ix = USED(mp) - 1; ix >= 0; ix--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4867
    mp_digit  d = DIGIT(mp, ix);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4868
    int       jx;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4869
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4870
    /* Unpack digit bytes, high order first */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4871
    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4872
      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4873
      if (!pos && !x)   /* suppress leading zeros */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4874
        continue;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4875
      str[pos++] = x;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4876
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4877
  }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4878
  if (!pos)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4879
    str[pos++] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4880
  return MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4881
} /* end mp_to_fixlen_octets() */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4882
/* }}} */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4883
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4884
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4885
/*------------------------------------------------------------------------*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  4886
/* HERE THERE BE DRAGONS                                                  */