jdk/src/share/native/sun/security/ec/mp_gf2m.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
 * 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
    18
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    19
 * 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
    20
 * 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
    21
 * 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
    22
 * http://www.mozilla.org/MPL/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    23
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    24
 * 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
    25
 * 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
    26
 * 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
    27
 * License.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    28
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    29
 * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    30
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    31
 * The Initial Developer of the Original Code is
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    32
 * Sun Microsystems, Inc.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    33
 * Portions created by the Initial Developer are Copyright (C) 2003
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    34
 * the Initial Developer. All Rights Reserved.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    35
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    36
 * Contributor(s):
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    37
 *   Sheueling Chang Shantz <sheueling.chang@sun.com> and
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    38
 *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    39
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    40
 * 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
    41
 * 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
    42
 * 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
    43
 * 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
    44
 * 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
    45
 * 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
    46
 * 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
    47
 * 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
    48
 * 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
    49
 * 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
    50
 * 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
    51
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    52
 *********************************************************************** */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    53
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    54
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    55
 * Use is subject to license terms.
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    58
#pragma ident   "%Z%%M% %I%     %E% SMI"
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
#include "mp_gf2m.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    61
#include "mp_gf2m-priv.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    62
#include "mplogic.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    63
#include "mpi-priv.h"
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
const mp_digit mp_gf2m_sqr_tb[16] =
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    66
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    67
      0,     1,     4,     5,    16,    17,    20,    21,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    68
     64,    65,    68,    69,    80,    81,    84,    85
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    71
/* Multiply two binary polynomials mp_digits a, b.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    72
 * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    73
 * Output in two mp_digits rh, rl.
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
#if MP_DIGIT_BITS == 32
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    76
void
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    77
s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    78
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    79
    register mp_digit h, l, s;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    80
    mp_digit tab[8], top2b = a >> 30;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    81
    register mp_digit a1, a2, a4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    82
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    83
    a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
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
    tab[0] =  0; tab[1] = a1;    tab[2] = a2;    tab[3] = a1^a2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    86
    tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
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
    s = tab[b       & 0x7]; l  = s;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    89
    s = tab[b >>  3 & 0x7]; l ^= s <<  3; h  = s >> 29;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    90
    s = tab[b >>  6 & 0x7]; l ^= s <<  6; h ^= s >> 26;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    91
    s = tab[b >>  9 & 0x7]; l ^= s <<  9; h ^= s >> 23;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    92
    s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    93
    s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    94
    s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    95
    s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    96
    s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >>  8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    97
    s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >>  5;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    98
    s = tab[b >> 30      ]; l ^= s << 30; h ^= s >>  2;
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
    /* compensate for the top two bits of a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   101
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   102
    if (top2b & 01) { l ^= b << 30; h ^= b >> 2; }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   103
    if (top2b & 02) { l ^= b << 31; h ^= b >> 1; }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   104
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   105
    *rh = h; *rl = l;
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
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   108
void
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   109
s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   110
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   111
    register mp_digit h, l, s;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   112
    mp_digit tab[16], top3b = a >> 61;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   113
    register mp_digit a1, a2, a4, a8;
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
    a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   116
    a4 = a2 << 1; a8 = a4 << 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   117
    tab[ 0] = 0;     tab[ 1] = a1;       tab[ 2] = a2;       tab[ 3] = a1^a2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   118
    tab[ 4] = a4;    tab[ 5] = a1^a4;    tab[ 6] = a2^a4;    tab[ 7] = a1^a2^a4;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   119
    tab[ 8] = a8;    tab[ 9] = a1^a8;    tab[10] = a2^a8;    tab[11] = a1^a2^a8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   120
    tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
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
    s = tab[b       & 0xF]; l  = s;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   123
    s = tab[b >>  4 & 0xF]; l ^= s <<  4; h  = s >> 60;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   124
    s = tab[b >>  8 & 0xF]; l ^= s <<  8; h ^= s >> 56;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   125
    s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   126
    s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   127
    s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   128
    s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   129
    s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   130
    s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   131
    s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   132
    s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   133
    s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   134
    s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   135
    s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   136
    s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >>  8;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   137
    s = tab[b >> 60      ]; l ^= s << 60; h ^= s >>  4;
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
    /* compensate for the top three bits of a */
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
    if (top3b & 01) { l ^= b << 61; h ^= b >> 3; }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   142
    if (top3b & 02) { l ^= b << 62; h ^= b >> 2; }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   143
    if (top3b & 04) { l ^= b << 63; h ^= b >> 1; }
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
    *rh = h; *rl = l;
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
#endif
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
/* Compute xor-multiply of two binary polynomials  (a1, a0) x (b1, b0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   150
 * result is a binary polynomial in 4 mp_digits r[4].
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   151
 * The caller MUST ensure that r has the right amount of space allocated.
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
void
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   154
s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   155
           const mp_digit b0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   156
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   157
    mp_digit m1, m0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   158
    /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   159
    s_bmul_1x1(r+3, r+2, a1, b1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   160
    s_bmul_1x1(r+1, r, a0, b0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   161
    s_bmul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   162
    /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   163
    r[2] ^= m1 ^ r[1] ^ r[3];  /* h0 ^= m1 ^ l1 ^ h1; */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   164
    r[1]  = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0;  /* l1 ^= l0 ^ h0 ^ m0; */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   165
}
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
/* Compute xor-multiply of two binary polynomials  (a2, a1, a0) x (b2, b1, b0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   168
 * result is a binary polynomial in 6 mp_digits r[6].
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   169
 * The caller MUST ensure that r has the right amount of space allocated.
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
void
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   172
s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   173
        const mp_digit b2, const mp_digit b1, const mp_digit b0)
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
        mp_digit zm[4];
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
        s_bmul_1x1(r+5, r+4, a2, b2);         /* fill top 2 words */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   178
        s_bmul_2x2(zm, a1, a2^a0, b1, b2^b0); /* fill middle 4 words */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   179
        s_bmul_2x2(r, a1, a0, b1, b0);        /* fill bottom 4 words */
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
        zm[3] ^= r[3];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   182
        zm[2] ^= r[2];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   183
        zm[1] ^= r[1] ^ r[5];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   184
        zm[0] ^= r[0] ^ r[4];
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
        r[5]  ^= zm[3];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   187
        r[4]  ^= zm[2];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   188
        r[3]  ^= zm[1];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   189
        r[2]  ^= zm[0];
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   192
/* Compute xor-multiply of two binary polynomials  (a3, a2, a1, a0) x (b3, b2, b1, b0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   193
 * result is a binary polynomial in 8 mp_digits r[8].
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   194
 * The caller MUST ensure that r has the right amount of space allocated.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   195
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   196
void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   197
        const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   198
        const mp_digit b0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   199
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   200
        mp_digit zm[4];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   201
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   202
        s_bmul_2x2(r+4, a3, a2, b3, b2);            /* fill top 4 words */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   203
        s_bmul_2x2(zm, a3^a1, a2^a0, b3^b1, b2^b0); /* fill middle 4 words */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   204
        s_bmul_2x2(r, a1, a0, b1, b0);              /* fill bottom 4 words */
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
        zm[3] ^= r[3] ^ r[7];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   207
        zm[2] ^= r[2] ^ r[6];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   208
        zm[1] ^= r[1] ^ r[5];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   209
        zm[0] ^= r[0] ^ r[4];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   210
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   211
        r[5]  ^= zm[3];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   212
        r[4]  ^= zm[2];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   213
        r[3]  ^= zm[1];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   214
        r[2]  ^= zm[0];
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   217
/* Compute addition of two binary polynomials a and b,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   218
 * store result in c; c could be a or b, a and b could be equal;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   219
 * c is the bitwise XOR of a and b.
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
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   222
mp_badd(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
   223
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   224
    mp_digit *pa, *pb, *pc;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   225
    mp_size ix;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   226
    mp_size used_pa, used_pb;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   227
    mp_err res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   228
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   229
    /* Add all digits up to the precision of b.  If b had more
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   230
     * precision than a initially, swap a, b first
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   231
     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   232
    if (MP_USED(a) >= MP_USED(b)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   233
        pa = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   234
        pb = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   235
        used_pa = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   236
        used_pb = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   237
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   238
        pa = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   239
        pb = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   240
        used_pa = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   241
        used_pb = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   242
    }
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
    /* Make sure c has enough precision for the output value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   245
    MP_CHECKOK( s_mp_pad(c, used_pa) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   246
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   247
    /* Do word-by-word xor */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   248
    pc = MP_DIGITS(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   249
    for (ix = 0; ix < used_pb; ix++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   250
        (*pc++) = (*pa++) ^ (*pb++);
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   253
    /* Finish the rest of digits until we're actually done */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   254
    for (; ix < used_pa; ++ix) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   255
        *pc++ = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   256
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   257
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   258
    MP_USED(c) = used_pa;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   259
    MP_SIGN(c) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   260
    s_mp_clamp(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   261
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   262
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   263
    return res;
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   266
#define s_mp_div2(a) MP_CHECKOK( mpl_rsh((a), (a), 1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   267
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   268
/* Compute binary polynomial multiply d = a * b */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   269
static void
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   270
s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
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
    mp_digit a_i, a0b0, a1b1, carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   273
    while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   274
        a_i = *a++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   275
        s_bmul_1x1(&a1b1, &a0b0, a_i, b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   276
        *d++ = a0b0 ^ carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   277
        carry = a1b1;
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
    *d = carry;
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   282
/* Compute binary polynomial xor multiply accumulate d ^= a * b */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   283
static void
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   284
s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
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
    mp_digit a_i, a0b0, a1b1, carry = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   287
    while (a_len--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   288
        a_i = *a++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   289
        s_bmul_1x1(&a1b1, &a0b0, a_i, b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   290
        *d++ ^= a0b0 ^ carry;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   291
        carry = a1b1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   292
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   293
    *d ^= carry;
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   296
/* Compute binary polynomial xor multiply c = a * b.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   297
 * All parameters may be identical.
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
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   300
mp_bmul(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
   301
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   302
    mp_digit *pb, b_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   303
    mp_int tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   304
    mp_size ib, a_used, b_used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   305
    mp_err res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   306
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   307
    MP_DIGITS(&tmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   308
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   309
    ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
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
    if (a == c) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   312
        MP_CHECKOK( mp_init_copy(&tmp, a) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   313
        if (a == b)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   314
            b = &tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   315
        a = &tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   316
    } else if (b == c) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   317
        MP_CHECKOK( mp_init_copy(&tmp, b) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   318
        b = &tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   319
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   320
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   321
    if (MP_USED(a) < MP_USED(b)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   322
        const mp_int *xch = b;      /* switch a and b if b longer */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   323
        b = a;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   324
        a = xch;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   325
    }
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
    MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   328
    MP_CHECKOK( s_mp_pad(c, USED(a) + USED(b)) );
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
    pb = MP_DIGITS(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   331
    s_bmul_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
   332
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   333
    /* Outer loop:  Digits of b */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   334
    a_used = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   335
    b_used = MP_USED(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   336
        MP_USED(c) = a_used + b_used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   337
    for (ib = 1; ib < b_used; ib++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   338
        b_i = *pb++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   339
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   340
        /* Inner product:  Digits of a */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   341
        if (b_i)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   342
            s_bmul_d_add(MP_DIGITS(a), a_used, b_i, MP_DIGITS(c) + ib);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   343
        else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   344
            MP_DIGIT(c, ib + a_used) = b_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   345
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   346
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   347
    s_mp_clamp(c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   348
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   349
    SIGN(c) = ZPOS;
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
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   352
    mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   353
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   354
}
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   357
/* Compute modular reduction of a and store result in r.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   358
 * r could be a.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   359
 * For modular arithmetic, the irreducible polynomial f(t) is represented
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   360
 * as an array of int[], where f(t) is of the form:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   361
 *     f(t) = t^p[0] + t^p[1] + ... + t^p[k]
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   362
 * where m = p[0] > p[1] > ... > p[k] = 0.
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
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   365
mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   366
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   367
    int j, k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   368
    int n, dN, d0, d1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   369
    mp_digit zz, *z, tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   370
    mp_size used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   371
    mp_err res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   372
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   373
    /* The algorithm does the reduction in place in r,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   374
     * if a != r, copy a into r first so reduction can be done in r
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
    if (a != r) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   377
        MP_CHECKOK( mp_copy(a, r) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   378
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   379
    z = MP_DIGITS(r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   380
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   381
    /* start reduction */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   382
    dN = p[0] / MP_DIGIT_BITS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   383
    used = MP_USED(r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   384
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   385
    for (j = used - 1; j > dN;) {
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
        zz = z[j];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   388
        if (zz == 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   389
            j--; continue;
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
        z[j] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   392
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   393
        for (k = 1; p[k] > 0; k++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   394
            /* reducing component t^p[k] */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   395
            n = p[0] - p[k];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   396
            d0 = n % MP_DIGIT_BITS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   397
            d1 = MP_DIGIT_BITS - d0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   398
            n /= MP_DIGIT_BITS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   399
            z[j-n] ^= (zz>>d0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   400
            if (d0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   401
                z[j-n-1] ^= (zz<<d1);
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   404
        /* reducing component t^0 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   405
        n = dN;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   406
        d0 = p[0] % MP_DIGIT_BITS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   407
        d1 = MP_DIGIT_BITS - d0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   408
        z[j-n] ^= (zz >> d0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   409
        if (d0)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   410
            z[j-n-1] ^= (zz << d1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   411
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   412
    }
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
    /* final round of reduction */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   415
    while (j == dN) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   416
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   417
        d0 = p[0] % MP_DIGIT_BITS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   418
        zz = z[dN] >> d0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   419
        if (zz == 0) break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   420
        d1 = MP_DIGIT_BITS - d0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   421
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   422
        /* clear up the top d1 bits */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   423
        if (d0) z[dN] = (z[dN] << d1) >> d1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   424
        *z ^= zz; /* reduction t^0 component */
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
        for (k = 1; p[k] > 0; k++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   427
            /* reducing component t^p[k]*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   428
            n = p[k] / MP_DIGIT_BITS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   429
            d0 = p[k] % MP_DIGIT_BITS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   430
            d1 = MP_DIGIT_BITS - d0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   431
            z[n] ^= (zz << d0);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   432
            tmp = zz >> d1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   433
            if (d0 && tmp)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   434
                z[n+1] ^= tmp;
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   438
    s_mp_clamp(r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   439
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   440
    return res;
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
/* Compute the product of two polynomials a and b, reduce modulo p,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   444
 * Store the result in r.  r could be a or b; a could be b.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   445
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   446
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   447
mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], mp_int *r)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   448
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   449
    mp_err res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   450
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   451
    if (a == b) return mp_bsqrmod(a, p, r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   452
    if ((res = mp_bmul(a, b, r) ) != MP_OKAY)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   453
        return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   454
    return mp_bmod(r, p, r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   455
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   456
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   457
/* Compute binary polynomial squaring c = a*a mod p .
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   458
 * Parameter r and a can be identical.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   459
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   460
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   461
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   462
mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
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
    mp_digit *pa, *pr, a_i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   465
    mp_int tmp;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   466
    mp_size ia, a_used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   467
    mp_err res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   468
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   469
    ARGCHK(a != NULL && r != NULL, MP_BADARG);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   470
    MP_DIGITS(&tmp) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   471
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   472
    if (a == r) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   473
        MP_CHECKOK( mp_init_copy(&tmp, a) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   474
        a = &tmp;
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
    MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   478
    MP_CHECKOK( s_mp_pad(r, 2*USED(a)) );
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
    pa = MP_DIGITS(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   481
    pr = MP_DIGITS(r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   482
    a_used = MP_USED(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   483
        MP_USED(r) = 2 * a_used;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   484
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   485
    for (ia = 0; ia < a_used; ia++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   486
        a_i = *pa++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   487
        *pr++ = gf2m_SQR0(a_i);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   488
        *pr++ = gf2m_SQR1(a_i);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   489
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   490
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   491
    MP_CHECKOK( mp_bmod(r, p, r) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   492
    s_mp_clamp(r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   493
    SIGN(r) = ZPOS;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   494
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   495
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   496
    mp_clear(&tmp);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   497
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   498
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   499
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   500
/* Compute binary polynomial y/x mod p, y divided by x, reduce modulo p.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   501
 * Store the result in r. r could be x or y, and x could equal y.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   502
 * Uses algorithm Modular_Division_GF(2^m) from
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   503
 *     Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   504
 *     the Great Divide".
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
int
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   507
mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   508
    const unsigned int p[], mp_int *r)
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
    mp_int aa, bb, uu;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   511
    mp_int *a, *b, *u, *v;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   512
    mp_err res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   513
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   514
    MP_DIGITS(&aa) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   515
    MP_DIGITS(&bb) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   516
    MP_DIGITS(&uu) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   517
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   518
    MP_CHECKOK( mp_init_copy(&aa, x) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   519
    MP_CHECKOK( mp_init_copy(&uu, y) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   520
    MP_CHECKOK( mp_init_copy(&bb, pp) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   521
    MP_CHECKOK( s_mp_pad(r, USED(pp)) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   522
    MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   523
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   524
    a = &aa; b= &bb; u=&uu; v=r;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   525
    /* reduce x and y mod p */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   526
    MP_CHECKOK( mp_bmod(a, p, a) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   527
    MP_CHECKOK( mp_bmod(u, p, u) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   528
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   529
    while (!mp_isodd(a)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   530
        s_mp_div2(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   531
        if (mp_isodd(u)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   532
            MP_CHECKOK( mp_badd(u, pp, u) );
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
        s_mp_div2(u);
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   537
    do {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   538
        if (mp_cmp_mag(b, a) > 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   539
            MP_CHECKOK( mp_badd(b, a, b) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   540
            MP_CHECKOK( mp_badd(v, u, v) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   541
            do {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   542
                s_mp_div2(b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   543
                if (mp_isodd(v)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   544
                    MP_CHECKOK( mp_badd(v, pp, v) );
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
                s_mp_div2(v);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   547
            } while (!mp_isodd(b));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   548
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   549
        else if ((MP_DIGIT(a,0) == 1) && (MP_USED(a) == 1))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   550
            break;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   551
        else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   552
            MP_CHECKOK( mp_badd(a, b, a) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   553
            MP_CHECKOK( mp_badd(u, v, u) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   554
            do {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   555
                s_mp_div2(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   556
                if (mp_isodd(u)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   557
                    MP_CHECKOK( mp_badd(u, pp, u) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   558
                }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   559
                s_mp_div2(u);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   560
            } while (!mp_isodd(a));
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
    } while (1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   563
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   564
    MP_CHECKOK( mp_copy(u, r) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   565
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   566
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   567
    /* XXX this appears to be a memory leak in the NSS code */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   568
    mp_clear(&aa);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   569
    mp_clear(&bb);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   570
    mp_clear(&uu);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   571
    return res;
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   575
/* Convert the bit-string representation of a polynomial a into an array
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   576
 * of integers corresponding to the bits with non-zero coefficient.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   577
 * Up to max elements of the array will be filled.  Return value is total
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   578
 * number of coefficients that would be extracted if array was large enough.
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
int
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   581
mp_bpoly2arr(const mp_int *a, unsigned int p[], int max)
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
    int i, j, k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   584
    mp_digit top_bit, mask;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   585
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   586
    top_bit = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   587
    top_bit <<= MP_DIGIT_BIT - 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   588
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   589
    for (k = 0; k < max; k++) p[k] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   590
    k = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   591
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   592
    for (i = MP_USED(a) - 1; i >= 0; i--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   593
        mask = top_bit;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   594
        for (j = MP_DIGIT_BIT - 1; j >= 0; j--) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   595
            if (MP_DIGITS(a)[i] & mask) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   596
                if (k < max) p[k] = MP_DIGIT_BIT * i + j;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   597
                k++;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   598
            }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   599
            mask >>= 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   600
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   601
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   602
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   603
    return k;
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
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   606
/* Convert the coefficient array representation of a polynomial to a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   607
 * bit-string.  The array must be terminated by 0.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   608
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   609
mp_err
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   610
mp_barr2poly(const unsigned int p[], mp_int *a)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   611
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   612
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   613
    mp_err res = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   614
    int i;
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
    mp_zero(a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   617
    for (i = 0; p[i] > 0; i++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   618
        MP_CHECKOK( mpl_set_bit(a, p[i], 1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   619
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   620
    MP_CHECKOK( mpl_set_bit(a, 0, 1) );
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
CLEANUP:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   623
    return res;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   624
}