1.1 --- a/src/share/native/sun/security/ec/ec.h Tue Oct 13 15:25:58 2009 -0700
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,72 +0,0 @@
1.4 -/* *********************************************************************
1.5 - *
1.6 - * Sun elects to have this file available under and governed by the
1.7 - * Mozilla Public License Version 1.1 ("MPL") (see
1.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
1.9 - * of doubt and subject to the following, Sun also elects to allow
1.10 - * licensees to use this file under the MPL, the GNU General Public
1.11 - * License version 2 only or the Lesser General Public License version
1.12 - * 2.1 only. Any references to the "GNU General Public License version 2
1.13 - * or later" or "GPL" in the following shall be construed to mean the
1.14 - * GNU General Public License version 2 only. Any references to the "GNU
1.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
1.16 - * following shall be construed to mean the GNU Lesser General Public
1.17 - * License version 2.1 only. However, the following notice accompanied
1.18 - * the original version of this file:
1.19 - *
1.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.21 - *
1.22 - * The contents of this file are subject to the Mozilla Public License Version
1.23 - * 1.1 (the "License"); you may not use this file except in compliance with
1.24 - * the License. You may obtain a copy of the License at
1.25 - * http://www.mozilla.org/MPL/
1.26 - *
1.27 - * Software distributed under the License is distributed on an "AS IS" basis,
1.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.29 - * for the specific language governing rights and limitations under the
1.30 - * License.
1.31 - *
1.32 - * The Original Code is the Elliptic Curve Cryptography library.
1.33 - *
1.34 - * The Initial Developer of the Original Code is
1.35 - * Sun Microsystems, Inc.
1.36 - * Portions created by the Initial Developer are Copyright (C) 2003
1.37 - * the Initial Developer. All Rights Reserved.
1.38 - *
1.39 - * Contributor(s):
1.40 - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
1.41 - *
1.42 - * Alternatively, the contents of this file may be used under the terms of
1.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
1.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
1.46 - * of those above. If you wish to allow use of your version of this file only
1.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
1.48 - * use your version of this file under the terms of the MPL, indicate your
1.49 - * decision by deleting the provisions above and replace them with the notice
1.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
1.51 - * the provisions above, a recipient may use your version of this file under
1.52 - * the terms of any one of the MPL, the GPL or the LGPL.
1.53 - *
1.54 - *********************************************************************** */
1.55 -/*
1.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
1.57 - * Use is subject to license terms.
1.58 - */
1.59 -
1.60 -#ifndef __ec_h_
1.61 -#define __ec_h_
1.62 -
1.63 -#pragma ident "%Z%%M% %I% %E% SMI"
1.64 -
1.65 -#define EC_DEBUG 0
1.66 -#define EC_POINT_FORM_COMPRESSED_Y0 0x02
1.67 -#define EC_POINT_FORM_COMPRESSED_Y1 0x03
1.68 -#define EC_POINT_FORM_UNCOMPRESSED 0x04
1.69 -#define EC_POINT_FORM_HYBRID_Y0 0x06
1.70 -#define EC_POINT_FORM_HYBRID_Y1 0x07
1.71 -
1.72 -#define ANSI_X962_CURVE_OID_TOTAL_LEN 10
1.73 -#define SECG_CURVE_OID_TOTAL_LEN 7
1.74 -
1.75 -#endif /* __ec_h_ */
2.1 --- a/src/share/native/sun/security/ec/ec2.h Tue Oct 13 15:25:58 2009 -0700
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,146 +0,0 @@
2.4 -/* *********************************************************************
2.5 - *
2.6 - * Sun elects to have this file available under and governed by the
2.7 - * Mozilla Public License Version 1.1 ("MPL") (see
2.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
2.9 - * of doubt and subject to the following, Sun also elects to allow
2.10 - * licensees to use this file under the MPL, the GNU General Public
2.11 - * License version 2 only or the Lesser General Public License version
2.12 - * 2.1 only. Any references to the "GNU General Public License version 2
2.13 - * or later" or "GPL" in the following shall be construed to mean the
2.14 - * GNU General Public License version 2 only. Any references to the "GNU
2.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
2.16 - * following shall be construed to mean the GNU Lesser General Public
2.17 - * License version 2.1 only. However, the following notice accompanied
2.18 - * the original version of this file:
2.19 - *
2.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
2.21 - *
2.22 - * The contents of this file are subject to the Mozilla Public License Version
2.23 - * 1.1 (the "License"); you may not use this file except in compliance with
2.24 - * the License. You may obtain a copy of the License at
2.25 - * http://www.mozilla.org/MPL/
2.26 - *
2.27 - * Software distributed under the License is distributed on an "AS IS" basis,
2.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
2.29 - * for the specific language governing rights and limitations under the
2.30 - * License.
2.31 - *
2.32 - * The Original Code is the elliptic curve math library for binary polynomial field curves.
2.33 - *
2.34 - * The Initial Developer of the Original Code is
2.35 - * Sun Microsystems, Inc.
2.36 - * Portions created by the Initial Developer are Copyright (C) 2003
2.37 - * the Initial Developer. All Rights Reserved.
2.38 - *
2.39 - * Contributor(s):
2.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
2.41 - *
2.42 - * Alternatively, the contents of this file may be used under the terms of
2.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
2.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
2.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
2.46 - * of those above. If you wish to allow use of your version of this file only
2.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
2.48 - * use your version of this file under the terms of the MPL, indicate your
2.49 - * decision by deleting the provisions above and replace them with the notice
2.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
2.51 - * the provisions above, a recipient may use your version of this file under
2.52 - * the terms of any one of the MPL, the GPL or the LGPL.
2.53 - *
2.54 - *********************************************************************** */
2.55 -/*
2.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2.57 - * Use is subject to license terms.
2.58 - */
2.59 -
2.60 -#ifndef _EC2_H
2.61 -#define _EC2_H
2.62 -
2.63 -#pragma ident "%Z%%M% %I% %E% SMI"
2.64 -
2.65 -#include "ecl-priv.h"
2.66 -
2.67 -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
2.68 -mp_err ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py);
2.69 -
2.70 -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
2.71 -mp_err ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py);
2.72 -
2.73 -/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
2.74 - * qy). Uses affine coordinates. */
2.75 -mp_err ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py,
2.76 - const mp_int *qx, const mp_int *qy, mp_int *rx,
2.77 - mp_int *ry, const ECGroup *group);
2.78 -
2.79 -/* Computes R = P - Q. Uses affine coordinates. */
2.80 -mp_err ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py,
2.81 - const mp_int *qx, const mp_int *qy, mp_int *rx,
2.82 - mp_int *ry, const ECGroup *group);
2.83 -
2.84 -/* Computes R = 2P. Uses affine coordinates. */
2.85 -mp_err ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
2.86 - mp_int *ry, const ECGroup *group);
2.87 -
2.88 -/* Validates a point on a GF2m curve. */
2.89 -mp_err ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
2.90 -
2.91 -/* by default, this routine is unused and thus doesn't need to be compiled */
2.92 -#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
2.93 -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
2.94 - * a, b and p are the elliptic curve coefficients and the irreducible that
2.95 - * determines the field GF2m. Uses affine coordinates. */
2.96 -mp_err ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px,
2.97 - const mp_int *py, mp_int *rx, mp_int *ry,
2.98 - const ECGroup *group);
2.99 -#endif
2.100 -
2.101 -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
2.102 - * a, b and p are the elliptic curve coefficients and the irreducible that
2.103 - * determines the field GF2m. Uses Montgomery projective coordinates. */
2.104 -mp_err ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px,
2.105 - const mp_int *py, mp_int *rx, mp_int *ry,
2.106 - const ECGroup *group);
2.107 -
2.108 -#ifdef ECL_ENABLE_GF2M_PROJ
2.109 -/* Converts a point P(px, py) from affine coordinates to projective
2.110 - * coordinates R(rx, ry, rz). */
2.111 -mp_err ec_GF2m_pt_aff2proj(const mp_int *px, const mp_int *py, mp_int *rx,
2.112 - mp_int *ry, mp_int *rz, const ECGroup *group);
2.113 -
2.114 -/* Converts a point P(px, py, pz) from projective coordinates to affine
2.115 - * coordinates R(rx, ry). */
2.116 -mp_err ec_GF2m_pt_proj2aff(const mp_int *px, const mp_int *py,
2.117 - const mp_int *pz, mp_int *rx, mp_int *ry,
2.118 - const ECGroup *group);
2.119 -
2.120 -/* Checks if point P(px, py, pz) is at infinity. Uses projective
2.121 - * coordinates. */
2.122 -mp_err ec_GF2m_pt_is_inf_proj(const mp_int *px, const mp_int *py,
2.123 - const mp_int *pz);
2.124 -
2.125 -/* Sets P(px, py, pz) to be the point at infinity. Uses projective
2.126 - * coordinates. */
2.127 -mp_err ec_GF2m_pt_set_inf_proj(mp_int *px, mp_int *py, mp_int *pz);
2.128 -
2.129 -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
2.130 - * (qx, qy, qz). Uses projective coordinates. */
2.131 -mp_err ec_GF2m_pt_add_proj(const mp_int *px, const mp_int *py,
2.132 - const mp_int *pz, const mp_int *qx,
2.133 - const mp_int *qy, mp_int *rx, mp_int *ry,
2.134 - mp_int *rz, const ECGroup *group);
2.135 -
2.136 -/* Computes R = 2P. Uses projective coordinates. */
2.137 -mp_err ec_GF2m_pt_dbl_proj(const mp_int *px, const mp_int *py,
2.138 - const mp_int *pz, mp_int *rx, mp_int *ry,
2.139 - mp_int *rz, const ECGroup *group);
2.140 -
2.141 -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
2.142 - * a, b and p are the elliptic curve coefficients and the prime that
2.143 - * determines the field GF2m. Uses projective coordinates. */
2.144 -mp_err ec_GF2m_pt_mul_proj(const mp_int *n, const mp_int *px,
2.145 - const mp_int *py, mp_int *rx, mp_int *ry,
2.146 - const ECGroup *group);
2.147 -#endif
2.148 -
2.149 -#endif /* _EC2_H */
3.1 --- a/src/share/native/sun/security/ec/ec2_163.c Tue Oct 13 15:25:58 2009 -0700
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,281 +0,0 @@
3.4 -/* *********************************************************************
3.5 - *
3.6 - * Sun elects to have this file available under and governed by the
3.7 - * Mozilla Public License Version 1.1 ("MPL") (see
3.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
3.9 - * of doubt and subject to the following, Sun also elects to allow
3.10 - * licensees to use this file under the MPL, the GNU General Public
3.11 - * License version 2 only or the Lesser General Public License version
3.12 - * 2.1 only. Any references to the "GNU General Public License version 2
3.13 - * or later" or "GPL" in the following shall be construed to mean the
3.14 - * GNU General Public License version 2 only. Any references to the "GNU
3.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
3.16 - * following shall be construed to mean the GNU Lesser General Public
3.17 - * License version 2.1 only. However, the following notice accompanied
3.18 - * the original version of this file:
3.19 - *
3.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3.21 - *
3.22 - * The contents of this file are subject to the Mozilla Public License Version
3.23 - * 1.1 (the "License"); you may not use this file except in compliance with
3.24 - * the License. You may obtain a copy of the License at
3.25 - * http://www.mozilla.org/MPL/
3.26 - *
3.27 - * Software distributed under the License is distributed on an "AS IS" basis,
3.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
3.29 - * for the specific language governing rights and limitations under the
3.30 - * License.
3.31 - *
3.32 - * The Original Code is the elliptic curve math library for binary polynomial field curves.
3.33 - *
3.34 - * The Initial Developer of the Original Code is
3.35 - * Sun Microsystems, Inc.
3.36 - * Portions created by the Initial Developer are Copyright (C) 2003
3.37 - * the Initial Developer. All Rights Reserved.
3.38 - *
3.39 - * Contributor(s):
3.40 - * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
3.41 - * Stephen Fung <fungstep@hotmail.com>, and
3.42 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
3.43 - *
3.44 - * Alternatively, the contents of this file may be used under the terms of
3.45 - * either the GNU General Public License Version 2 or later (the "GPL"), or
3.46 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
3.47 - * in which case the provisions of the GPL or the LGPL are applicable instead
3.48 - * of those above. If you wish to allow use of your version of this file only
3.49 - * under the terms of either the GPL or the LGPL, and not to allow others to
3.50 - * use your version of this file under the terms of the MPL, indicate your
3.51 - * decision by deleting the provisions above and replace them with the notice
3.52 - * and other provisions required by the GPL or the LGPL. If you do not delete
3.53 - * the provisions above, a recipient may use your version of this file under
3.54 - * the terms of any one of the MPL, the GPL or the LGPL.
3.55 - *
3.56 - *********************************************************************** */
3.57 -/*
3.58 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3.59 - * Use is subject to license terms.
3.60 - */
3.61 -
3.62 -#pragma ident "%Z%%M% %I% %E% SMI"
3.63 -
3.64 -#include "ec2.h"
3.65 -#include "mp_gf2m.h"
3.66 -#include "mp_gf2m-priv.h"
3.67 -#include "mpi.h"
3.68 -#include "mpi-priv.h"
3.69 -#ifndef _KERNEL
3.70 -#include <stdlib.h>
3.71 -#endif
3.72 -
3.73 -/* Fast reduction for polynomials over a 163-bit curve. Assumes reduction
3.74 - * polynomial with terms {163, 7, 6, 3, 0}. */
3.75 -mp_err
3.76 -ec_GF2m_163_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
3.77 -{
3.78 - mp_err res = MP_OKAY;
3.79 - mp_digit *u, z;
3.80 -
3.81 - if (a != r) {
3.82 - MP_CHECKOK(mp_copy(a, r));
3.83 - }
3.84 -#ifdef ECL_SIXTY_FOUR_BIT
3.85 - if (MP_USED(r) < 6) {
3.86 - MP_CHECKOK(s_mp_pad(r, 6));
3.87 - }
3.88 - u = MP_DIGITS(r);
3.89 - MP_USED(r) = 6;
3.90 -
3.91 - /* u[5] only has 6 significant bits */
3.92 - z = u[5];
3.93 - u[2] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
3.94 - z = u[4];
3.95 - u[2] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
3.96 - u[1] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
3.97 - z = u[3];
3.98 - u[1] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
3.99 - u[0] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
3.100 - z = u[2] >> 35; /* z only has 29 significant bits */
3.101 - u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
3.102 - /* clear bits above 163 */
3.103 - u[5] = u[4] = u[3] = 0;
3.104 - u[2] ^= z << 35;
3.105 -#else
3.106 - if (MP_USED(r) < 11) {
3.107 - MP_CHECKOK(s_mp_pad(r, 11));
3.108 - }
3.109 - u = MP_DIGITS(r);
3.110 - MP_USED(r) = 11;
3.111 -
3.112 - /* u[11] only has 6 significant bits */
3.113 - z = u[10];
3.114 - u[5] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
3.115 - u[4] ^= (z << 29);
3.116 - z = u[9];
3.117 - u[5] ^= (z >> 28) ^ (z >> 29);
3.118 - u[4] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
3.119 - u[3] ^= (z << 29);
3.120 - z = u[8];
3.121 - u[4] ^= (z >> 28) ^ (z >> 29);
3.122 - u[3] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
3.123 - u[2] ^= (z << 29);
3.124 - z = u[7];
3.125 - u[3] ^= (z >> 28) ^ (z >> 29);
3.126 - u[2] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
3.127 - u[1] ^= (z << 29);
3.128 - z = u[6];
3.129 - u[2] ^= (z >> 28) ^ (z >> 29);
3.130 - u[1] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
3.131 - u[0] ^= (z << 29);
3.132 - z = u[5] >> 3; /* z only has 29 significant bits */
3.133 - u[1] ^= (z >> 25) ^ (z >> 26);
3.134 - u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
3.135 - /* clear bits above 163 */
3.136 - u[11] = u[10] = u[9] = u[8] = u[7] = u[6] = 0;
3.137 - u[5] ^= z << 3;
3.138 -#endif
3.139 - s_mp_clamp(r);
3.140 -
3.141 - CLEANUP:
3.142 - return res;
3.143 -}
3.144 -
3.145 -/* Fast squaring for polynomials over a 163-bit curve. Assumes reduction
3.146 - * polynomial with terms {163, 7, 6, 3, 0}. */
3.147 -mp_err
3.148 -ec_GF2m_163_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
3.149 -{
3.150 - mp_err res = MP_OKAY;
3.151 - mp_digit *u, *v;
3.152 -
3.153 - v = MP_DIGITS(a);
3.154 -
3.155 -#ifdef ECL_SIXTY_FOUR_BIT
3.156 - if (MP_USED(a) < 3) {
3.157 - return mp_bsqrmod(a, meth->irr_arr, r);
3.158 - }
3.159 - if (MP_USED(r) < 6) {
3.160 - MP_CHECKOK(s_mp_pad(r, 6));
3.161 - }
3.162 - MP_USED(r) = 6;
3.163 -#else
3.164 - if (MP_USED(a) < 6) {
3.165 - return mp_bsqrmod(a, meth->irr_arr, r);
3.166 - }
3.167 - if (MP_USED(r) < 12) {
3.168 - MP_CHECKOK(s_mp_pad(r, 12));
3.169 - }
3.170 - MP_USED(r) = 12;
3.171 -#endif
3.172 - u = MP_DIGITS(r);
3.173 -
3.174 -#ifdef ECL_THIRTY_TWO_BIT
3.175 - u[11] = gf2m_SQR1(v[5]);
3.176 - u[10] = gf2m_SQR0(v[5]);
3.177 - u[9] = gf2m_SQR1(v[4]);
3.178 - u[8] = gf2m_SQR0(v[4]);
3.179 - u[7] = gf2m_SQR1(v[3]);
3.180 - u[6] = gf2m_SQR0(v[3]);
3.181 -#endif
3.182 - u[5] = gf2m_SQR1(v[2]);
3.183 - u[4] = gf2m_SQR0(v[2]);
3.184 - u[3] = gf2m_SQR1(v[1]);
3.185 - u[2] = gf2m_SQR0(v[1]);
3.186 - u[1] = gf2m_SQR1(v[0]);
3.187 - u[0] = gf2m_SQR0(v[0]);
3.188 - return ec_GF2m_163_mod(r, r, meth);
3.189 -
3.190 - CLEANUP:
3.191 - return res;
3.192 -}
3.193 -
3.194 -/* Fast multiplication for polynomials over a 163-bit curve. Assumes
3.195 - * reduction polynomial with terms {163, 7, 6, 3, 0}. */
3.196 -mp_err
3.197 -ec_GF2m_163_mul(const mp_int *a, const mp_int *b, mp_int *r,
3.198 - const GFMethod *meth)
3.199 -{
3.200 - mp_err res = MP_OKAY;
3.201 - mp_digit a2 = 0, a1 = 0, a0, b2 = 0, b1 = 0, b0;
3.202 -
3.203 -#ifdef ECL_THIRTY_TWO_BIT
3.204 - mp_digit a5 = 0, a4 = 0, a3 = 0, b5 = 0, b4 = 0, b3 = 0;
3.205 - mp_digit rm[6];
3.206 -#endif
3.207 -
3.208 - if (a == b) {
3.209 - return ec_GF2m_163_sqr(a, r, meth);
3.210 - } else {
3.211 - switch (MP_USED(a)) {
3.212 -#ifdef ECL_THIRTY_TWO_BIT
3.213 - case 6:
3.214 - a5 = MP_DIGIT(a, 5);
3.215 - case 5:
3.216 - a4 = MP_DIGIT(a, 4);
3.217 - case 4:
3.218 - a3 = MP_DIGIT(a, 3);
3.219 -#endif
3.220 - case 3:
3.221 - a2 = MP_DIGIT(a, 2);
3.222 - case 2:
3.223 - a1 = MP_DIGIT(a, 1);
3.224 - default:
3.225 - a0 = MP_DIGIT(a, 0);
3.226 - }
3.227 - switch (MP_USED(b)) {
3.228 -#ifdef ECL_THIRTY_TWO_BIT
3.229 - case 6:
3.230 - b5 = MP_DIGIT(b, 5);
3.231 - case 5:
3.232 - b4 = MP_DIGIT(b, 4);
3.233 - case 4:
3.234 - b3 = MP_DIGIT(b, 3);
3.235 -#endif
3.236 - case 3:
3.237 - b2 = MP_DIGIT(b, 2);
3.238 - case 2:
3.239 - b1 = MP_DIGIT(b, 1);
3.240 - default:
3.241 - b0 = MP_DIGIT(b, 0);
3.242 - }
3.243 -#ifdef ECL_SIXTY_FOUR_BIT
3.244 - MP_CHECKOK(s_mp_pad(r, 6));
3.245 - s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
3.246 - MP_USED(r) = 6;
3.247 - s_mp_clamp(r);
3.248 -#else
3.249 - MP_CHECKOK(s_mp_pad(r, 12));
3.250 - s_bmul_3x3(MP_DIGITS(r) + 6, a5, a4, a3, b5, b4, b3);
3.251 - s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
3.252 - s_bmul_3x3(rm, a5 ^ a2, a4 ^ a1, a3 ^ a0, b5 ^ b2, b4 ^ b1,
3.253 - b3 ^ b0);
3.254 - rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 11);
3.255 - rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 10);
3.256 - rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 9);
3.257 - rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 8);
3.258 - rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 7);
3.259 - rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 6);
3.260 - MP_DIGIT(r, 8) ^= rm[5];
3.261 - MP_DIGIT(r, 7) ^= rm[4];
3.262 - MP_DIGIT(r, 6) ^= rm[3];
3.263 - MP_DIGIT(r, 5) ^= rm[2];
3.264 - MP_DIGIT(r, 4) ^= rm[1];
3.265 - MP_DIGIT(r, 3) ^= rm[0];
3.266 - MP_USED(r) = 12;
3.267 - s_mp_clamp(r);
3.268 -#endif
3.269 - return ec_GF2m_163_mod(r, r, meth);
3.270 - }
3.271 -
3.272 - CLEANUP:
3.273 - return res;
3.274 -}
3.275 -
3.276 -/* Wire in fast field arithmetic for 163-bit curves. */
3.277 -mp_err
3.278 -ec_group_set_gf2m163(ECGroup *group, ECCurveName name)
3.279 -{
3.280 - group->meth->field_mod = &ec_GF2m_163_mod;
3.281 - group->meth->field_mul = &ec_GF2m_163_mul;
3.282 - group->meth->field_sqr = &ec_GF2m_163_sqr;
3.283 - return MP_OKAY;
3.284 -}
4.1 --- a/src/share/native/sun/security/ec/ec2_193.c Tue Oct 13 15:25:58 2009 -0700
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,298 +0,0 @@
4.4 -/* *********************************************************************
4.5 - *
4.6 - * Sun elects to have this file available under and governed by the
4.7 - * Mozilla Public License Version 1.1 ("MPL") (see
4.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
4.9 - * of doubt and subject to the following, Sun also elects to allow
4.10 - * licensees to use this file under the MPL, the GNU General Public
4.11 - * License version 2 only or the Lesser General Public License version
4.12 - * 2.1 only. Any references to the "GNU General Public License version 2
4.13 - * or later" or "GPL" in the following shall be construed to mean the
4.14 - * GNU General Public License version 2 only. Any references to the "GNU
4.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
4.16 - * following shall be construed to mean the GNU Lesser General Public
4.17 - * License version 2.1 only. However, the following notice accompanied
4.18 - * the original version of this file:
4.19 - *
4.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4.21 - *
4.22 - * The contents of this file are subject to the Mozilla Public License Version
4.23 - * 1.1 (the "License"); you may not use this file except in compliance with
4.24 - * the License. You may obtain a copy of the License at
4.25 - * http://www.mozilla.org/MPL/
4.26 - *
4.27 - * Software distributed under the License is distributed on an "AS IS" basis,
4.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
4.29 - * for the specific language governing rights and limitations under the
4.30 - * License.
4.31 - *
4.32 - * The Original Code is the elliptic curve math library for binary polynomial field curves.
4.33 - *
4.34 - * The Initial Developer of the Original Code is
4.35 - * Sun Microsystems, Inc.
4.36 - * Portions created by the Initial Developer are Copyright (C) 2003
4.37 - * the Initial Developer. All Rights Reserved.
4.38 - *
4.39 - * Contributor(s):
4.40 - * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
4.41 - * Stephen Fung <fungstep@hotmail.com>, and
4.42 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
4.43 - *
4.44 - * Alternatively, the contents of this file may be used under the terms of
4.45 - * either the GNU General Public License Version 2 or later (the "GPL"), or
4.46 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
4.47 - * in which case the provisions of the GPL or the LGPL are applicable instead
4.48 - * of those above. If you wish to allow use of your version of this file only
4.49 - * under the terms of either the GPL or the LGPL, and not to allow others to
4.50 - * use your version of this file under the terms of the MPL, indicate your
4.51 - * decision by deleting the provisions above and replace them with the notice
4.52 - * and other provisions required by the GPL or the LGPL. If you do not delete
4.53 - * the provisions above, a recipient may use your version of this file under
4.54 - * the terms of any one of the MPL, the GPL or the LGPL.
4.55 - *
4.56 - *********************************************************************** */
4.57 -/*
4.58 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
4.59 - * Use is subject to license terms.
4.60 - */
4.61 -
4.62 -#pragma ident "%Z%%M% %I% %E% SMI"
4.63 -
4.64 -#include "ec2.h"
4.65 -#include "mp_gf2m.h"
4.66 -#include "mp_gf2m-priv.h"
4.67 -#include "mpi.h"
4.68 -#include "mpi-priv.h"
4.69 -#ifndef _KERNEL
4.70 -#include <stdlib.h>
4.71 -#endif
4.72 -
4.73 -/* Fast reduction for polynomials over a 193-bit curve. Assumes reduction
4.74 - * polynomial with terms {193, 15, 0}. */
4.75 -mp_err
4.76 -ec_GF2m_193_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
4.77 -{
4.78 - mp_err res = MP_OKAY;
4.79 - mp_digit *u, z;
4.80 -
4.81 - if (a != r) {
4.82 - MP_CHECKOK(mp_copy(a, r));
4.83 - }
4.84 -#ifdef ECL_SIXTY_FOUR_BIT
4.85 - if (MP_USED(r) < 7) {
4.86 - MP_CHECKOK(s_mp_pad(r, 7));
4.87 - }
4.88 - u = MP_DIGITS(r);
4.89 - MP_USED(r) = 7;
4.90 -
4.91 - /* u[6] only has 2 significant bits */
4.92 - z = u[6];
4.93 - u[3] ^= (z << 14) ^ (z >> 1);
4.94 - u[2] ^= (z << 63);
4.95 - z = u[5];
4.96 - u[3] ^= (z >> 50);
4.97 - u[2] ^= (z << 14) ^ (z >> 1);
4.98 - u[1] ^= (z << 63);
4.99 - z = u[4];
4.100 - u[2] ^= (z >> 50);
4.101 - u[1] ^= (z << 14) ^ (z >> 1);
4.102 - u[0] ^= (z << 63);
4.103 - z = u[3] >> 1; /* z only has 63 significant bits */
4.104 - u[1] ^= (z >> 49);
4.105 - u[0] ^= (z << 15) ^ z;
4.106 - /* clear bits above 193 */
4.107 - u[6] = u[5] = u[4] = 0;
4.108 - u[3] ^= z << 1;
4.109 -#else
4.110 - if (MP_USED(r) < 13) {
4.111 - MP_CHECKOK(s_mp_pad(r, 13));
4.112 - }
4.113 - u = MP_DIGITS(r);
4.114 - MP_USED(r) = 13;
4.115 -
4.116 - /* u[12] only has 2 significant bits */
4.117 - z = u[12];
4.118 - u[6] ^= (z << 14) ^ (z >> 1);
4.119 - u[5] ^= (z << 31);
4.120 - z = u[11];
4.121 - u[6] ^= (z >> 18);
4.122 - u[5] ^= (z << 14) ^ (z >> 1);
4.123 - u[4] ^= (z << 31);
4.124 - z = u[10];
4.125 - u[5] ^= (z >> 18);
4.126 - u[4] ^= (z << 14) ^ (z >> 1);
4.127 - u[3] ^= (z << 31);
4.128 - z = u[9];
4.129 - u[4] ^= (z >> 18);
4.130 - u[3] ^= (z << 14) ^ (z >> 1);
4.131 - u[2] ^= (z << 31);
4.132 - z = u[8];
4.133 - u[3] ^= (z >> 18);
4.134 - u[2] ^= (z << 14) ^ (z >> 1);
4.135 - u[1] ^= (z << 31);
4.136 - z = u[7];
4.137 - u[2] ^= (z >> 18);
4.138 - u[1] ^= (z << 14) ^ (z >> 1);
4.139 - u[0] ^= (z << 31);
4.140 - z = u[6] >> 1; /* z only has 31 significant bits */
4.141 - u[1] ^= (z >> 17);
4.142 - u[0] ^= (z << 15) ^ z;
4.143 - /* clear bits above 193 */
4.144 - u[12] = u[11] = u[10] = u[9] = u[8] = u[7] = 0;
4.145 - u[6] ^= z << 1;
4.146 -#endif
4.147 - s_mp_clamp(r);
4.148 -
4.149 - CLEANUP:
4.150 - return res;
4.151 -}
4.152 -
4.153 -/* Fast squaring for polynomials over a 193-bit curve. Assumes reduction
4.154 - * polynomial with terms {193, 15, 0}. */
4.155 -mp_err
4.156 -ec_GF2m_193_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
4.157 -{
4.158 - mp_err res = MP_OKAY;
4.159 - mp_digit *u, *v;
4.160 -
4.161 - v = MP_DIGITS(a);
4.162 -
4.163 -#ifdef ECL_SIXTY_FOUR_BIT
4.164 - if (MP_USED(a) < 4) {
4.165 - return mp_bsqrmod(a, meth->irr_arr, r);
4.166 - }
4.167 - if (MP_USED(r) < 7) {
4.168 - MP_CHECKOK(s_mp_pad(r, 7));
4.169 - }
4.170 - MP_USED(r) = 7;
4.171 -#else
4.172 - if (MP_USED(a) < 7) {
4.173 - return mp_bsqrmod(a, meth->irr_arr, r);
4.174 - }
4.175 - if (MP_USED(r) < 13) {
4.176 - MP_CHECKOK(s_mp_pad(r, 13));
4.177 - }
4.178 - MP_USED(r) = 13;
4.179 -#endif
4.180 - u = MP_DIGITS(r);
4.181 -
4.182 -#ifdef ECL_THIRTY_TWO_BIT
4.183 - u[12] = gf2m_SQR0(v[6]);
4.184 - u[11] = gf2m_SQR1(v[5]);
4.185 - u[10] = gf2m_SQR0(v[5]);
4.186 - u[9] = gf2m_SQR1(v[4]);
4.187 - u[8] = gf2m_SQR0(v[4]);
4.188 - u[7] = gf2m_SQR1(v[3]);
4.189 -#endif
4.190 - u[6] = gf2m_SQR0(v[3]);
4.191 - u[5] = gf2m_SQR1(v[2]);
4.192 - u[4] = gf2m_SQR0(v[2]);
4.193 - u[3] = gf2m_SQR1(v[1]);
4.194 - u[2] = gf2m_SQR0(v[1]);
4.195 - u[1] = gf2m_SQR1(v[0]);
4.196 - u[0] = gf2m_SQR0(v[0]);
4.197 - return ec_GF2m_193_mod(r, r, meth);
4.198 -
4.199 - CLEANUP:
4.200 - return res;
4.201 -}
4.202 -
4.203 -/* Fast multiplication for polynomials over a 193-bit curve. Assumes
4.204 - * reduction polynomial with terms {193, 15, 0}. */
4.205 -mp_err
4.206 -ec_GF2m_193_mul(const mp_int *a, const mp_int *b, mp_int *r,
4.207 - const GFMethod *meth)
4.208 -{
4.209 - mp_err res = MP_OKAY;
4.210 - mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
4.211 -
4.212 -#ifdef ECL_THIRTY_TWO_BIT
4.213 - mp_digit a6 = 0, a5 = 0, a4 = 0, b6 = 0, b5 = 0, b4 = 0;
4.214 - mp_digit rm[8];
4.215 -#endif
4.216 -
4.217 - if (a == b) {
4.218 - return ec_GF2m_193_sqr(a, r, meth);
4.219 - } else {
4.220 - switch (MP_USED(a)) {
4.221 -#ifdef ECL_THIRTY_TWO_BIT
4.222 - case 7:
4.223 - a6 = MP_DIGIT(a, 6);
4.224 - case 6:
4.225 - a5 = MP_DIGIT(a, 5);
4.226 - case 5:
4.227 - a4 = MP_DIGIT(a, 4);
4.228 -#endif
4.229 - case 4:
4.230 - a3 = MP_DIGIT(a, 3);
4.231 - case 3:
4.232 - a2 = MP_DIGIT(a, 2);
4.233 - case 2:
4.234 - a1 = MP_DIGIT(a, 1);
4.235 - default:
4.236 - a0 = MP_DIGIT(a, 0);
4.237 - }
4.238 - switch (MP_USED(b)) {
4.239 -#ifdef ECL_THIRTY_TWO_BIT
4.240 - case 7:
4.241 - b6 = MP_DIGIT(b, 6);
4.242 - case 6:
4.243 - b5 = MP_DIGIT(b, 5);
4.244 - case 5:
4.245 - b4 = MP_DIGIT(b, 4);
4.246 -#endif
4.247 - case 4:
4.248 - b3 = MP_DIGIT(b, 3);
4.249 - case 3:
4.250 - b2 = MP_DIGIT(b, 2);
4.251 - case 2:
4.252 - b1 = MP_DIGIT(b, 1);
4.253 - default:
4.254 - b0 = MP_DIGIT(b, 0);
4.255 - }
4.256 -#ifdef ECL_SIXTY_FOUR_BIT
4.257 - MP_CHECKOK(s_mp_pad(r, 8));
4.258 - s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
4.259 - MP_USED(r) = 8;
4.260 - s_mp_clamp(r);
4.261 -#else
4.262 - MP_CHECKOK(s_mp_pad(r, 14));
4.263 - s_bmul_3x3(MP_DIGITS(r) + 8, a6, a5, a4, b6, b5, b4);
4.264 - s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
4.265 - s_bmul_4x4(rm, a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b3, b6 ^ b2, b5 ^ b1,
4.266 - b4 ^ b0);
4.267 - rm[7] ^= MP_DIGIT(r, 7);
4.268 - rm[6] ^= MP_DIGIT(r, 6);
4.269 - rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
4.270 - rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
4.271 - rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
4.272 - rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
4.273 - rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
4.274 - rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
4.275 - MP_DIGIT(r, 11) ^= rm[7];
4.276 - MP_DIGIT(r, 10) ^= rm[6];
4.277 - MP_DIGIT(r, 9) ^= rm[5];
4.278 - MP_DIGIT(r, 8) ^= rm[4];
4.279 - MP_DIGIT(r, 7) ^= rm[3];
4.280 - MP_DIGIT(r, 6) ^= rm[2];
4.281 - MP_DIGIT(r, 5) ^= rm[1];
4.282 - MP_DIGIT(r, 4) ^= rm[0];
4.283 - MP_USED(r) = 14;
4.284 - s_mp_clamp(r);
4.285 -#endif
4.286 - return ec_GF2m_193_mod(r, r, meth);
4.287 - }
4.288 -
4.289 - CLEANUP:
4.290 - return res;
4.291 -}
4.292 -
4.293 -/* Wire in fast field arithmetic for 193-bit curves. */
4.294 -mp_err
4.295 -ec_group_set_gf2m193(ECGroup *group, ECCurveName name)
4.296 -{
4.297 - group->meth->field_mod = &ec_GF2m_193_mod;
4.298 - group->meth->field_mul = &ec_GF2m_193_mul;
4.299 - group->meth->field_sqr = &ec_GF2m_193_sqr;
4.300 - return MP_OKAY;
4.301 -}
5.1 --- a/src/share/native/sun/security/ec/ec2_233.c Tue Oct 13 15:25:58 2009 -0700
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,321 +0,0 @@
5.4 -/* *********************************************************************
5.5 - *
5.6 - * Sun elects to have this file available under and governed by the
5.7 - * Mozilla Public License Version 1.1 ("MPL") (see
5.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
5.9 - * of doubt and subject to the following, Sun also elects to allow
5.10 - * licensees to use this file under the MPL, the GNU General Public
5.11 - * License version 2 only or the Lesser General Public License version
5.12 - * 2.1 only. Any references to the "GNU General Public License version 2
5.13 - * or later" or "GPL" in the following shall be construed to mean the
5.14 - * GNU General Public License version 2 only. Any references to the "GNU
5.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
5.16 - * following shall be construed to mean the GNU Lesser General Public
5.17 - * License version 2.1 only. However, the following notice accompanied
5.18 - * the original version of this file:
5.19 - *
5.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5.21 - *
5.22 - * The contents of this file are subject to the Mozilla Public License Version
5.23 - * 1.1 (the "License"); you may not use this file except in compliance with
5.24 - * the License. You may obtain a copy of the License at
5.25 - * http://www.mozilla.org/MPL/
5.26 - *
5.27 - * Software distributed under the License is distributed on an "AS IS" basis,
5.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
5.29 - * for the specific language governing rights and limitations under the
5.30 - * License.
5.31 - *
5.32 - * The Original Code is the elliptic curve math library for binary polynomial field curves.
5.33 - *
5.34 - * The Initial Developer of the Original Code is
5.35 - * Sun Microsystems, Inc.
5.36 - * Portions created by the Initial Developer are Copyright (C) 2003
5.37 - * the Initial Developer. All Rights Reserved.
5.38 - *
5.39 - * Contributor(s):
5.40 - * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
5.41 - * Stephen Fung <fungstep@hotmail.com>, and
5.42 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
5.43 - *
5.44 - * Alternatively, the contents of this file may be used under the terms of
5.45 - * either the GNU General Public License Version 2 or later (the "GPL"), or
5.46 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
5.47 - * in which case the provisions of the GPL or the LGPL are applicable instead
5.48 - * of those above. If you wish to allow use of your version of this file only
5.49 - * under the terms of either the GPL or the LGPL, and not to allow others to
5.50 - * use your version of this file under the terms of the MPL, indicate your
5.51 - * decision by deleting the provisions above and replace them with the notice
5.52 - * and other provisions required by the GPL or the LGPL. If you do not delete
5.53 - * the provisions above, a recipient may use your version of this file under
5.54 - * the terms of any one of the MPL, the GPL or the LGPL.
5.55 - *
5.56 - *********************************************************************** */
5.57 -/*
5.58 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
5.59 - * Use is subject to license terms.
5.60 - */
5.61 -
5.62 -#pragma ident "%Z%%M% %I% %E% SMI"
5.63 -
5.64 -#include "ec2.h"
5.65 -#include "mp_gf2m.h"
5.66 -#include "mp_gf2m-priv.h"
5.67 -#include "mpi.h"
5.68 -#include "mpi-priv.h"
5.69 -#ifndef _KERNEL
5.70 -#include <stdlib.h>
5.71 -#endif
5.72 -
5.73 -/* Fast reduction for polynomials over a 233-bit curve. Assumes reduction
5.74 - * polynomial with terms {233, 74, 0}. */
5.75 -mp_err
5.76 -ec_GF2m_233_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
5.77 -{
5.78 - mp_err res = MP_OKAY;
5.79 - mp_digit *u, z;
5.80 -
5.81 - if (a != r) {
5.82 - MP_CHECKOK(mp_copy(a, r));
5.83 - }
5.84 -#ifdef ECL_SIXTY_FOUR_BIT
5.85 - if (MP_USED(r) < 8) {
5.86 - MP_CHECKOK(s_mp_pad(r, 8));
5.87 - }
5.88 - u = MP_DIGITS(r);
5.89 - MP_USED(r) = 8;
5.90 -
5.91 - /* u[7] only has 18 significant bits */
5.92 - z = u[7];
5.93 - u[4] ^= (z << 33) ^ (z >> 41);
5.94 - u[3] ^= (z << 23);
5.95 - z = u[6];
5.96 - u[4] ^= (z >> 31);
5.97 - u[3] ^= (z << 33) ^ (z >> 41);
5.98 - u[2] ^= (z << 23);
5.99 - z = u[5];
5.100 - u[3] ^= (z >> 31);
5.101 - u[2] ^= (z << 33) ^ (z >> 41);
5.102 - u[1] ^= (z << 23);
5.103 - z = u[4];
5.104 - u[2] ^= (z >> 31);
5.105 - u[1] ^= (z << 33) ^ (z >> 41);
5.106 - u[0] ^= (z << 23);
5.107 - z = u[3] >> 41; /* z only has 23 significant bits */
5.108 - u[1] ^= (z << 10);
5.109 - u[0] ^= z;
5.110 - /* clear bits above 233 */
5.111 - u[7] = u[6] = u[5] = u[4] = 0;
5.112 - u[3] ^= z << 41;
5.113 -#else
5.114 - if (MP_USED(r) < 15) {
5.115 - MP_CHECKOK(s_mp_pad(r, 15));
5.116 - }
5.117 - u = MP_DIGITS(r);
5.118 - MP_USED(r) = 15;
5.119 -
5.120 - /* u[14] only has 18 significant bits */
5.121 - z = u[14];
5.122 - u[9] ^= (z << 1);
5.123 - u[7] ^= (z >> 9);
5.124 - u[6] ^= (z << 23);
5.125 - z = u[13];
5.126 - u[9] ^= (z >> 31);
5.127 - u[8] ^= (z << 1);
5.128 - u[6] ^= (z >> 9);
5.129 - u[5] ^= (z << 23);
5.130 - z = u[12];
5.131 - u[8] ^= (z >> 31);
5.132 - u[7] ^= (z << 1);
5.133 - u[5] ^= (z >> 9);
5.134 - u[4] ^= (z << 23);
5.135 - z = u[11];
5.136 - u[7] ^= (z >> 31);
5.137 - u[6] ^= (z << 1);
5.138 - u[4] ^= (z >> 9);
5.139 - u[3] ^= (z << 23);
5.140 - z = u[10];
5.141 - u[6] ^= (z >> 31);
5.142 - u[5] ^= (z << 1);
5.143 - u[3] ^= (z >> 9);
5.144 - u[2] ^= (z << 23);
5.145 - z = u[9];
5.146 - u[5] ^= (z >> 31);
5.147 - u[4] ^= (z << 1);
5.148 - u[2] ^= (z >> 9);
5.149 - u[1] ^= (z << 23);
5.150 - z = u[8];
5.151 - u[4] ^= (z >> 31);
5.152 - u[3] ^= (z << 1);
5.153 - u[1] ^= (z >> 9);
5.154 - u[0] ^= (z << 23);
5.155 - z = u[7] >> 9; /* z only has 23 significant bits */
5.156 - u[3] ^= (z >> 22);
5.157 - u[2] ^= (z << 10);
5.158 - u[0] ^= z;
5.159 - /* clear bits above 233 */
5.160 - u[14] = u[13] = u[12] = u[11] = u[10] = u[9] = u[8] = 0;
5.161 - u[7] ^= z << 9;
5.162 -#endif
5.163 - s_mp_clamp(r);
5.164 -
5.165 - CLEANUP:
5.166 - return res;
5.167 -}
5.168 -
5.169 -/* Fast squaring for polynomials over a 233-bit curve. Assumes reduction
5.170 - * polynomial with terms {233, 74, 0}. */
5.171 -mp_err
5.172 -ec_GF2m_233_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
5.173 -{
5.174 - mp_err res = MP_OKAY;
5.175 - mp_digit *u, *v;
5.176 -
5.177 - v = MP_DIGITS(a);
5.178 -
5.179 -#ifdef ECL_SIXTY_FOUR_BIT
5.180 - if (MP_USED(a) < 4) {
5.181 - return mp_bsqrmod(a, meth->irr_arr, r);
5.182 - }
5.183 - if (MP_USED(r) < 8) {
5.184 - MP_CHECKOK(s_mp_pad(r, 8));
5.185 - }
5.186 - MP_USED(r) = 8;
5.187 -#else
5.188 - if (MP_USED(a) < 8) {
5.189 - return mp_bsqrmod(a, meth->irr_arr, r);
5.190 - }
5.191 - if (MP_USED(r) < 15) {
5.192 - MP_CHECKOK(s_mp_pad(r, 15));
5.193 - }
5.194 - MP_USED(r) = 15;
5.195 -#endif
5.196 - u = MP_DIGITS(r);
5.197 -
5.198 -#ifdef ECL_THIRTY_TWO_BIT
5.199 - u[14] = gf2m_SQR0(v[7]);
5.200 - u[13] = gf2m_SQR1(v[6]);
5.201 - u[12] = gf2m_SQR0(v[6]);
5.202 - u[11] = gf2m_SQR1(v[5]);
5.203 - u[10] = gf2m_SQR0(v[5]);
5.204 - u[9] = gf2m_SQR1(v[4]);
5.205 - u[8] = gf2m_SQR0(v[4]);
5.206 -#endif
5.207 - u[7] = gf2m_SQR1(v[3]);
5.208 - u[6] = gf2m_SQR0(v[3]);
5.209 - u[5] = gf2m_SQR1(v[2]);
5.210 - u[4] = gf2m_SQR0(v[2]);
5.211 - u[3] = gf2m_SQR1(v[1]);
5.212 - u[2] = gf2m_SQR0(v[1]);
5.213 - u[1] = gf2m_SQR1(v[0]);
5.214 - u[0] = gf2m_SQR0(v[0]);
5.215 - return ec_GF2m_233_mod(r, r, meth);
5.216 -
5.217 - CLEANUP:
5.218 - return res;
5.219 -}
5.220 -
5.221 -/* Fast multiplication for polynomials over a 233-bit curve. Assumes
5.222 - * reduction polynomial with terms {233, 74, 0}. */
5.223 -mp_err
5.224 -ec_GF2m_233_mul(const mp_int *a, const mp_int *b, mp_int *r,
5.225 - const GFMethod *meth)
5.226 -{
5.227 - mp_err res = MP_OKAY;
5.228 - mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
5.229 -
5.230 -#ifdef ECL_THIRTY_TWO_BIT
5.231 - mp_digit a7 = 0, a6 = 0, a5 = 0, a4 = 0, b7 = 0, b6 = 0, b5 = 0, b4 =
5.232 - 0;
5.233 - mp_digit rm[8];
5.234 -#endif
5.235 -
5.236 - if (a == b) {
5.237 - return ec_GF2m_233_sqr(a, r, meth);
5.238 - } else {
5.239 - switch (MP_USED(a)) {
5.240 -#ifdef ECL_THIRTY_TWO_BIT
5.241 - case 8:
5.242 - a7 = MP_DIGIT(a, 7);
5.243 - case 7:
5.244 - a6 = MP_DIGIT(a, 6);
5.245 - case 6:
5.246 - a5 = MP_DIGIT(a, 5);
5.247 - case 5:
5.248 - a4 = MP_DIGIT(a, 4);
5.249 -#endif
5.250 - case 4:
5.251 - a3 = MP_DIGIT(a, 3);
5.252 - case 3:
5.253 - a2 = MP_DIGIT(a, 2);
5.254 - case 2:
5.255 - a1 = MP_DIGIT(a, 1);
5.256 - default:
5.257 - a0 = MP_DIGIT(a, 0);
5.258 - }
5.259 - switch (MP_USED(b)) {
5.260 -#ifdef ECL_THIRTY_TWO_BIT
5.261 - case 8:
5.262 - b7 = MP_DIGIT(b, 7);
5.263 - case 7:
5.264 - b6 = MP_DIGIT(b, 6);
5.265 - case 6:
5.266 - b5 = MP_DIGIT(b, 5);
5.267 - case 5:
5.268 - b4 = MP_DIGIT(b, 4);
5.269 -#endif
5.270 - case 4:
5.271 - b3 = MP_DIGIT(b, 3);
5.272 - case 3:
5.273 - b2 = MP_DIGIT(b, 2);
5.274 - case 2:
5.275 - b1 = MP_DIGIT(b, 1);
5.276 - default:
5.277 - b0 = MP_DIGIT(b, 0);
5.278 - }
5.279 -#ifdef ECL_SIXTY_FOUR_BIT
5.280 - MP_CHECKOK(s_mp_pad(r, 8));
5.281 - s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
5.282 - MP_USED(r) = 8;
5.283 - s_mp_clamp(r);
5.284 -#else
5.285 - MP_CHECKOK(s_mp_pad(r, 16));
5.286 - s_bmul_4x4(MP_DIGITS(r) + 8, a7, a6, a5, a4, b7, b6, b5, b4);
5.287 - s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
5.288 - s_bmul_4x4(rm, a7 ^ a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b7 ^ b3,
5.289 - b6 ^ b2, b5 ^ b1, b4 ^ b0);
5.290 - rm[7] ^= MP_DIGIT(r, 7) ^ MP_DIGIT(r, 15);
5.291 - rm[6] ^= MP_DIGIT(r, 6) ^ MP_DIGIT(r, 14);
5.292 - rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
5.293 - rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
5.294 - rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
5.295 - rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
5.296 - rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
5.297 - rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
5.298 - MP_DIGIT(r, 11) ^= rm[7];
5.299 - MP_DIGIT(r, 10) ^= rm[6];
5.300 - MP_DIGIT(r, 9) ^= rm[5];
5.301 - MP_DIGIT(r, 8) ^= rm[4];
5.302 - MP_DIGIT(r, 7) ^= rm[3];
5.303 - MP_DIGIT(r, 6) ^= rm[2];
5.304 - MP_DIGIT(r, 5) ^= rm[1];
5.305 - MP_DIGIT(r, 4) ^= rm[0];
5.306 - MP_USED(r) = 16;
5.307 - s_mp_clamp(r);
5.308 -#endif
5.309 - return ec_GF2m_233_mod(r, r, meth);
5.310 - }
5.311 -
5.312 - CLEANUP:
5.313 - return res;
5.314 -}
5.315 -
5.316 -/* Wire in fast field arithmetic for 233-bit curves. */
5.317 -mp_err
5.318 -ec_group_set_gf2m233(ECGroup *group, ECCurveName name)
5.319 -{
5.320 - group->meth->field_mod = &ec_GF2m_233_mod;
5.321 - group->meth->field_mul = &ec_GF2m_233_mul;
5.322 - group->meth->field_sqr = &ec_GF2m_233_sqr;
5.323 - return MP_OKAY;
5.324 -}
6.1 --- a/src/share/native/sun/security/ec/ec2_aff.c Tue Oct 13 15:25:58 2009 -0700
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,368 +0,0 @@
6.4 -/* *********************************************************************
6.5 - *
6.6 - * Sun elects to have this file available under and governed by the
6.7 - * Mozilla Public License Version 1.1 ("MPL") (see
6.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
6.9 - * of doubt and subject to the following, Sun also elects to allow
6.10 - * licensees to use this file under the MPL, the GNU General Public
6.11 - * License version 2 only or the Lesser General Public License version
6.12 - * 2.1 only. Any references to the "GNU General Public License version 2
6.13 - * or later" or "GPL" in the following shall be construed to mean the
6.14 - * GNU General Public License version 2 only. Any references to the "GNU
6.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
6.16 - * following shall be construed to mean the GNU Lesser General Public
6.17 - * License version 2.1 only. However, the following notice accompanied
6.18 - * the original version of this file:
6.19 - *
6.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6.21 - *
6.22 - * The contents of this file are subject to the Mozilla Public License Version
6.23 - * 1.1 (the "License"); you may not use this file except in compliance with
6.24 - * the License. You may obtain a copy of the License at
6.25 - * http://www.mozilla.org/MPL/
6.26 - *
6.27 - * Software distributed under the License is distributed on an "AS IS" basis,
6.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
6.29 - * for the specific language governing rights and limitations under the
6.30 - * License.
6.31 - *
6.32 - * The Original Code is the elliptic curve math library for binary polynomial field curves.
6.33 - *
6.34 - * The Initial Developer of the Original Code is
6.35 - * Sun Microsystems, Inc.
6.36 - * Portions created by the Initial Developer are Copyright (C) 2003
6.37 - * the Initial Developer. All Rights Reserved.
6.38 - *
6.39 - * Contributor(s):
6.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
6.41 - *
6.42 - * Alternatively, the contents of this file may be used under the terms of
6.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
6.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
6.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
6.46 - * of those above. If you wish to allow use of your version of this file only
6.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
6.48 - * use your version of this file under the terms of the MPL, indicate your
6.49 - * decision by deleting the provisions above and replace them with the notice
6.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
6.51 - * the provisions above, a recipient may use your version of this file under
6.52 - * the terms of any one of the MPL, the GPL or the LGPL.
6.53 - *
6.54 - *********************************************************************** */
6.55 -/*
6.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
6.57 - * Use is subject to license terms.
6.58 - */
6.59 -
6.60 -#pragma ident "%Z%%M% %I% %E% SMI"
6.61 -
6.62 -#include "ec2.h"
6.63 -#include "mplogic.h"
6.64 -#include "mp_gf2m.h"
6.65 -#ifndef _KERNEL
6.66 -#include <stdlib.h>
6.67 -#endif
6.68 -
6.69 -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
6.70 -mp_err
6.71 -ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py)
6.72 -{
6.73 -
6.74 - if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
6.75 - return MP_YES;
6.76 - } else {
6.77 - return MP_NO;
6.78 - }
6.79 -
6.80 -}
6.81 -
6.82 -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
6.83 -mp_err
6.84 -ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py)
6.85 -{
6.86 - mp_zero(px);
6.87 - mp_zero(py);
6.88 - return MP_OKAY;
6.89 -}
6.90 -
6.91 -/* Computes R = P + Q based on IEEE P1363 A.10.2. Elliptic curve points P,
6.92 - * Q, and R can all be identical. Uses affine coordinates. */
6.93 -mp_err
6.94 -ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
6.95 - const mp_int *qy, mp_int *rx, mp_int *ry,
6.96 - const ECGroup *group)
6.97 -{
6.98 - mp_err res = MP_OKAY;
6.99 - mp_int lambda, tempx, tempy;
6.100 -
6.101 - MP_DIGITS(&lambda) = 0;
6.102 - MP_DIGITS(&tempx) = 0;
6.103 - MP_DIGITS(&tempy) = 0;
6.104 - MP_CHECKOK(mp_init(&lambda, FLAG(px)));
6.105 - MP_CHECKOK(mp_init(&tempx, FLAG(px)));
6.106 - MP_CHECKOK(mp_init(&tempy, FLAG(px)));
6.107 - /* if P = inf, then R = Q */
6.108 - if (ec_GF2m_pt_is_inf_aff(px, py) == 0) {
6.109 - MP_CHECKOK(mp_copy(qx, rx));
6.110 - MP_CHECKOK(mp_copy(qy, ry));
6.111 - res = MP_OKAY;
6.112 - goto CLEANUP;
6.113 - }
6.114 - /* if Q = inf, then R = P */
6.115 - if (ec_GF2m_pt_is_inf_aff(qx, qy) == 0) {
6.116 - MP_CHECKOK(mp_copy(px, rx));
6.117 - MP_CHECKOK(mp_copy(py, ry));
6.118 - res = MP_OKAY;
6.119 - goto CLEANUP;
6.120 - }
6.121 - /* if px != qx, then lambda = (py+qy) / (px+qx), tempx = a + lambda^2
6.122 - * + lambda + px + qx */
6.123 - if (mp_cmp(px, qx) != 0) {
6.124 - MP_CHECKOK(group->meth->field_add(py, qy, &tempy, group->meth));
6.125 - MP_CHECKOK(group->meth->field_add(px, qx, &tempx, group->meth));
6.126 - MP_CHECKOK(group->meth->
6.127 - field_div(&tempy, &tempx, &lambda, group->meth));
6.128 - MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
6.129 - MP_CHECKOK(group->meth->
6.130 - field_add(&tempx, &lambda, &tempx, group->meth));
6.131 - MP_CHECKOK(group->meth->
6.132 - field_add(&tempx, &group->curvea, &tempx, group->meth));
6.133 - MP_CHECKOK(group->meth->
6.134 - field_add(&tempx, px, &tempx, group->meth));
6.135 - MP_CHECKOK(group->meth->
6.136 - field_add(&tempx, qx, &tempx, group->meth));
6.137 - } else {
6.138 - /* if py != qy or qx = 0, then R = inf */
6.139 - if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) {
6.140 - mp_zero(rx);
6.141 - mp_zero(ry);
6.142 - res = MP_OKAY;
6.143 - goto CLEANUP;
6.144 - }
6.145 - /* lambda = qx + qy / qx */
6.146 - MP_CHECKOK(group->meth->field_div(qy, qx, &lambda, group->meth));
6.147 - MP_CHECKOK(group->meth->
6.148 - field_add(&lambda, qx, &lambda, group->meth));
6.149 - /* tempx = a + lambda^2 + lambda */
6.150 - MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
6.151 - MP_CHECKOK(group->meth->
6.152 - field_add(&tempx, &lambda, &tempx, group->meth));
6.153 - MP_CHECKOK(group->meth->
6.154 - field_add(&tempx, &group->curvea, &tempx, group->meth));
6.155 - }
6.156 - /* ry = (qx + tempx) * lambda + tempx + qy */
6.157 - MP_CHECKOK(group->meth->field_add(qx, &tempx, &tempy, group->meth));
6.158 - MP_CHECKOK(group->meth->
6.159 - field_mul(&tempy, &lambda, &tempy, group->meth));
6.160 - MP_CHECKOK(group->meth->
6.161 - field_add(&tempy, &tempx, &tempy, group->meth));
6.162 - MP_CHECKOK(group->meth->field_add(&tempy, qy, ry, group->meth));
6.163 - /* rx = tempx */
6.164 - MP_CHECKOK(mp_copy(&tempx, rx));
6.165 -
6.166 - CLEANUP:
6.167 - mp_clear(&lambda);
6.168 - mp_clear(&tempx);
6.169 - mp_clear(&tempy);
6.170 - return res;
6.171 -}
6.172 -
6.173 -/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
6.174 - * identical. Uses affine coordinates. */
6.175 -mp_err
6.176 -ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
6.177 - const mp_int *qy, mp_int *rx, mp_int *ry,
6.178 - const ECGroup *group)
6.179 -{
6.180 - mp_err res = MP_OKAY;
6.181 - mp_int nqy;
6.182 -
6.183 - MP_DIGITS(&nqy) = 0;
6.184 - MP_CHECKOK(mp_init(&nqy, FLAG(px)));
6.185 - /* nqy = qx+qy */
6.186 - MP_CHECKOK(group->meth->field_add(qx, qy, &nqy, group->meth));
6.187 - MP_CHECKOK(group->point_add(px, py, qx, &nqy, rx, ry, group));
6.188 - CLEANUP:
6.189 - mp_clear(&nqy);
6.190 - return res;
6.191 -}
6.192 -
6.193 -/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
6.194 - * affine coordinates. */
6.195 -mp_err
6.196 -ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
6.197 - mp_int *ry, const ECGroup *group)
6.198 -{
6.199 - return group->point_add(px, py, px, py, rx, ry, group);
6.200 -}
6.201 -
6.202 -/* by default, this routine is unused and thus doesn't need to be compiled */
6.203 -#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
6.204 -/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
6.205 - * R can be identical. Uses affine coordinates. */
6.206 -mp_err
6.207 -ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
6.208 - mp_int *rx, mp_int *ry, const ECGroup *group)
6.209 -{
6.210 - mp_err res = MP_OKAY;
6.211 - mp_int k, k3, qx, qy, sx, sy;
6.212 - int b1, b3, i, l;
6.213 -
6.214 - MP_DIGITS(&k) = 0;
6.215 - MP_DIGITS(&k3) = 0;
6.216 - MP_DIGITS(&qx) = 0;
6.217 - MP_DIGITS(&qy) = 0;
6.218 - MP_DIGITS(&sx) = 0;
6.219 - MP_DIGITS(&sy) = 0;
6.220 - MP_CHECKOK(mp_init(&k));
6.221 - MP_CHECKOK(mp_init(&k3));
6.222 - MP_CHECKOK(mp_init(&qx));
6.223 - MP_CHECKOK(mp_init(&qy));
6.224 - MP_CHECKOK(mp_init(&sx));
6.225 - MP_CHECKOK(mp_init(&sy));
6.226 -
6.227 - /* if n = 0 then r = inf */
6.228 - if (mp_cmp_z(n) == 0) {
6.229 - mp_zero(rx);
6.230 - mp_zero(ry);
6.231 - res = MP_OKAY;
6.232 - goto CLEANUP;
6.233 - }
6.234 - /* Q = P, k = n */
6.235 - MP_CHECKOK(mp_copy(px, &qx));
6.236 - MP_CHECKOK(mp_copy(py, &qy));
6.237 - MP_CHECKOK(mp_copy(n, &k));
6.238 - /* if n < 0 then Q = -Q, k = -k */
6.239 - if (mp_cmp_z(n) < 0) {
6.240 - MP_CHECKOK(group->meth->field_add(&qx, &qy, &qy, group->meth));
6.241 - MP_CHECKOK(mp_neg(&k, &k));
6.242 - }
6.243 -#ifdef ECL_DEBUG /* basic double and add method */
6.244 - l = mpl_significant_bits(&k) - 1;
6.245 - MP_CHECKOK(mp_copy(&qx, &sx));
6.246 - MP_CHECKOK(mp_copy(&qy, &sy));
6.247 - for (i = l - 1; i >= 0; i--) {
6.248 - /* S = 2S */
6.249 - MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
6.250 - /* if k_i = 1, then S = S + Q */
6.251 - if (mpl_get_bit(&k, i) != 0) {
6.252 - MP_CHECKOK(group->
6.253 - point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
6.254 - }
6.255 - }
6.256 -#else /* double and add/subtract method from
6.257 - * standard */
6.258 - /* k3 = 3 * k */
6.259 - MP_CHECKOK(mp_set_int(&k3, 3));
6.260 - MP_CHECKOK(mp_mul(&k, &k3, &k3));
6.261 - /* S = Q */
6.262 - MP_CHECKOK(mp_copy(&qx, &sx));
6.263 - MP_CHECKOK(mp_copy(&qy, &sy));
6.264 - /* l = index of high order bit in binary representation of 3*k */
6.265 - l = mpl_significant_bits(&k3) - 1;
6.266 - /* for i = l-1 downto 1 */
6.267 - for (i = l - 1; i >= 1; i--) {
6.268 - /* S = 2S */
6.269 - MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
6.270 - b3 = MP_GET_BIT(&k3, i);
6.271 - b1 = MP_GET_BIT(&k, i);
6.272 - /* if k3_i = 1 and k_i = 0, then S = S + Q */
6.273 - if ((b3 == 1) && (b1 == 0)) {
6.274 - MP_CHECKOK(group->
6.275 - point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
6.276 - /* if k3_i = 0 and k_i = 1, then S = S - Q */
6.277 - } else if ((b3 == 0) && (b1 == 1)) {
6.278 - MP_CHECKOK(group->
6.279 - point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
6.280 - }
6.281 - }
6.282 -#endif
6.283 - /* output S */
6.284 - MP_CHECKOK(mp_copy(&sx, rx));
6.285 - MP_CHECKOK(mp_copy(&sy, ry));
6.286 -
6.287 - CLEANUP:
6.288 - mp_clear(&k);
6.289 - mp_clear(&k3);
6.290 - mp_clear(&qx);
6.291 - mp_clear(&qy);
6.292 - mp_clear(&sx);
6.293 - mp_clear(&sy);
6.294 - return res;
6.295 -}
6.296 -#endif
6.297 -
6.298 -/* Validates a point on a GF2m curve. */
6.299 -mp_err
6.300 -ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
6.301 -{
6.302 - mp_err res = MP_NO;
6.303 - mp_int accl, accr, tmp, pxt, pyt;
6.304 -
6.305 - MP_DIGITS(&accl) = 0;
6.306 - MP_DIGITS(&accr) = 0;
6.307 - MP_DIGITS(&tmp) = 0;
6.308 - MP_DIGITS(&pxt) = 0;
6.309 - MP_DIGITS(&pyt) = 0;
6.310 - MP_CHECKOK(mp_init(&accl, FLAG(px)));
6.311 - MP_CHECKOK(mp_init(&accr, FLAG(px)));
6.312 - MP_CHECKOK(mp_init(&tmp, FLAG(px)));
6.313 - MP_CHECKOK(mp_init(&pxt, FLAG(px)));
6.314 - MP_CHECKOK(mp_init(&pyt, FLAG(px)));
6.315 -
6.316 - /* 1: Verify that publicValue is not the point at infinity */
6.317 - if (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES) {
6.318 - res = MP_NO;
6.319 - goto CLEANUP;
6.320 - }
6.321 - /* 2: Verify that the coordinates of publicValue are elements
6.322 - * of the field.
6.323 - */
6.324 - if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
6.325 - (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
6.326 - res = MP_NO;
6.327 - goto CLEANUP;
6.328 - }
6.329 - /* 3: Verify that publicValue is on the curve. */
6.330 - if (group->meth->field_enc) {
6.331 - group->meth->field_enc(px, &pxt, group->meth);
6.332 - group->meth->field_enc(py, &pyt, group->meth);
6.333 - } else {
6.334 - mp_copy(px, &pxt);
6.335 - mp_copy(py, &pyt);
6.336 - }
6.337 - /* left-hand side: y^2 + x*y */
6.338 - MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
6.339 - MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) );
6.340 - MP_CHECKOK( group->meth->field_add(&accl, &tmp, &accl, group->meth) );
6.341 - /* right-hand side: x^3 + a*x^2 + b */
6.342 - MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
6.343 - MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
6.344 - MP_CHECKOK( group->meth->field_mul(&group->curvea, &tmp, &tmp, group->meth) );
6.345 - MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
6.346 - MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
6.347 - /* check LHS - RHS == 0 */
6.348 - MP_CHECKOK( group->meth->field_add(&accl, &accr, &accr, group->meth) );
6.349 - if (mp_cmp_z(&accr) != 0) {
6.350 - res = MP_NO;
6.351 - goto CLEANUP;
6.352 - }
6.353 - /* 4: Verify that the order of the curve times the publicValue
6.354 - * is the point at infinity.
6.355 - */
6.356 - MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
6.357 - if (ec_GF2m_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
6.358 - res = MP_NO;
6.359 - goto CLEANUP;
6.360 - }
6.361 -
6.362 - res = MP_YES;
6.363 -
6.364 -CLEANUP:
6.365 - mp_clear(&accl);
6.366 - mp_clear(&accr);
6.367 - mp_clear(&tmp);
6.368 - mp_clear(&pxt);
6.369 - mp_clear(&pyt);
6.370 - return res;
6.371 -}
7.1 --- a/src/share/native/sun/security/ec/ec2_mont.c Tue Oct 13 15:25:58 2009 -0700
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,296 +0,0 @@
7.4 -/* *********************************************************************
7.5 - *
7.6 - * Sun elects to have this file available under and governed by the
7.7 - * Mozilla Public License Version 1.1 ("MPL") (see
7.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
7.9 - * of doubt and subject to the following, Sun also elects to allow
7.10 - * licensees to use this file under the MPL, the GNU General Public
7.11 - * License version 2 only or the Lesser General Public License version
7.12 - * 2.1 only. Any references to the "GNU General Public License version 2
7.13 - * or later" or "GPL" in the following shall be construed to mean the
7.14 - * GNU General Public License version 2 only. Any references to the "GNU
7.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
7.16 - * following shall be construed to mean the GNU Lesser General Public
7.17 - * License version 2.1 only. However, the following notice accompanied
7.18 - * the original version of this file:
7.19 - *
7.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7.21 - *
7.22 - * The contents of this file are subject to the Mozilla Public License Version
7.23 - * 1.1 (the "License"); you may not use this file except in compliance with
7.24 - * the License. You may obtain a copy of the License at
7.25 - * http://www.mozilla.org/MPL/
7.26 - *
7.27 - * Software distributed under the License is distributed on an "AS IS" basis,
7.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7.29 - * for the specific language governing rights and limitations under the
7.30 - * License.
7.31 - *
7.32 - * The Original Code is the elliptic curve math library for binary polynomial field curves.
7.33 - *
7.34 - * The Initial Developer of the Original Code is
7.35 - * Sun Microsystems, Inc.
7.36 - * Portions created by the Initial Developer are Copyright (C) 2003
7.37 - * the Initial Developer. All Rights Reserved.
7.38 - *
7.39 - * Contributor(s):
7.40 - * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
7.41 - * Stephen Fung <fungstep@hotmail.com>, and
7.42 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
7.43 - *
7.44 - * Alternatively, the contents of this file may be used under the terms of
7.45 - * either the GNU General Public License Version 2 or later (the "GPL"), or
7.46 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
7.47 - * in which case the provisions of the GPL or the LGPL are applicable instead
7.48 - * of those above. If you wish to allow use of your version of this file only
7.49 - * under the terms of either the GPL or the LGPL, and not to allow others to
7.50 - * use your version of this file under the terms of the MPL, indicate your
7.51 - * decision by deleting the provisions above and replace them with the notice
7.52 - * and other provisions required by the GPL or the LGPL. If you do not delete
7.53 - * the provisions above, a recipient may use your version of this file under
7.54 - * the terms of any one of the MPL, the GPL or the LGPL.
7.55 - *
7.56 - *********************************************************************** */
7.57 -/*
7.58 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
7.59 - * Use is subject to license terms.
7.60 - */
7.61 -
7.62 -#pragma ident "%Z%%M% %I% %E% SMI"
7.63 -
7.64 -#include "ec2.h"
7.65 -#include "mplogic.h"
7.66 -#include "mp_gf2m.h"
7.67 -#ifndef _KERNEL
7.68 -#include <stdlib.h>
7.69 -#endif
7.70 -
7.71 -/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery
7.72 - * projective coordinates. Uses algorithm Mdouble in appendix of Lopez, J.
7.73 - * and Dahab, R. "Fast multiplication on elliptic curves over GF(2^m)
7.74 - * without precomputation". modified to not require precomputation of
7.75 - * c=b^{2^{m-1}}. */
7.76 -static mp_err
7.77 -gf2m_Mdouble(mp_int *x, mp_int *z, const ECGroup *group, int kmflag)
7.78 -{
7.79 - mp_err res = MP_OKAY;
7.80 - mp_int t1;
7.81 -
7.82 - MP_DIGITS(&t1) = 0;
7.83 - MP_CHECKOK(mp_init(&t1, kmflag));
7.84 -
7.85 - MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
7.86 - MP_CHECKOK(group->meth->field_sqr(z, &t1, group->meth));
7.87 - MP_CHECKOK(group->meth->field_mul(x, &t1, z, group->meth));
7.88 - MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
7.89 - MP_CHECKOK(group->meth->field_sqr(&t1, &t1, group->meth));
7.90 - MP_CHECKOK(group->meth->
7.91 - field_mul(&group->curveb, &t1, &t1, group->meth));
7.92 - MP_CHECKOK(group->meth->field_add(x, &t1, x, group->meth));
7.93 -
7.94 - CLEANUP:
7.95 - mp_clear(&t1);
7.96 - return res;
7.97 -}
7.98 -
7.99 -/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in
7.100 - * Montgomery projective coordinates. Uses algorithm Madd in appendix of
7.101 - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
7.102 - * GF(2^m) without precomputation". */
7.103 -static mp_err
7.104 -gf2m_Madd(const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, mp_int *z2,
7.105 - const ECGroup *group, int kmflag)
7.106 -{
7.107 - mp_err res = MP_OKAY;
7.108 - mp_int t1, t2;
7.109 -
7.110 - MP_DIGITS(&t1) = 0;
7.111 - MP_DIGITS(&t2) = 0;
7.112 - MP_CHECKOK(mp_init(&t1, kmflag));
7.113 - MP_CHECKOK(mp_init(&t2, kmflag));
7.114 -
7.115 - MP_CHECKOK(mp_copy(x, &t1));
7.116 - MP_CHECKOK(group->meth->field_mul(x1, z2, x1, group->meth));
7.117 - MP_CHECKOK(group->meth->field_mul(z1, x2, z1, group->meth));
7.118 - MP_CHECKOK(group->meth->field_mul(x1, z1, &t2, group->meth));
7.119 - MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
7.120 - MP_CHECKOK(group->meth->field_sqr(z1, z1, group->meth));
7.121 - MP_CHECKOK(group->meth->field_mul(z1, &t1, x1, group->meth));
7.122 - MP_CHECKOK(group->meth->field_add(x1, &t2, x1, group->meth));
7.123 -
7.124 - CLEANUP:
7.125 - mp_clear(&t1);
7.126 - mp_clear(&t2);
7.127 - return res;
7.128 -}
7.129 -
7.130 -/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
7.131 - * using Montgomery point multiplication algorithm Mxy() in appendix of
7.132 - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
7.133 - * GF(2^m) without precomputation". Returns: 0 on error 1 if return value
7.134 - * should be the point at infinity 2 otherwise */
7.135 -static int
7.136 -gf2m_Mxy(const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
7.137 - mp_int *x2, mp_int *z2, const ECGroup *group)
7.138 -{
7.139 - mp_err res = MP_OKAY;
7.140 - int ret = 0;
7.141 - mp_int t3, t4, t5;
7.142 -
7.143 - MP_DIGITS(&t3) = 0;
7.144 - MP_DIGITS(&t4) = 0;
7.145 - MP_DIGITS(&t5) = 0;
7.146 - MP_CHECKOK(mp_init(&t3, FLAG(x2)));
7.147 - MP_CHECKOK(mp_init(&t4, FLAG(x2)));
7.148 - MP_CHECKOK(mp_init(&t5, FLAG(x2)));
7.149 -
7.150 - if (mp_cmp_z(z1) == 0) {
7.151 - mp_zero(x2);
7.152 - mp_zero(z2);
7.153 - ret = 1;
7.154 - goto CLEANUP;
7.155 - }
7.156 -
7.157 - if (mp_cmp_z(z2) == 0) {
7.158 - MP_CHECKOK(mp_copy(x, x2));
7.159 - MP_CHECKOK(group->meth->field_add(x, y, z2, group->meth));
7.160 - ret = 2;
7.161 - goto CLEANUP;
7.162 - }
7.163 -
7.164 - MP_CHECKOK(mp_set_int(&t5, 1));
7.165 - if (group->meth->field_enc) {
7.166 - MP_CHECKOK(group->meth->field_enc(&t5, &t5, group->meth));
7.167 - }
7.168 -
7.169 - MP_CHECKOK(group->meth->field_mul(z1, z2, &t3, group->meth));
7.170 -
7.171 - MP_CHECKOK(group->meth->field_mul(z1, x, z1, group->meth));
7.172 - MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
7.173 - MP_CHECKOK(group->meth->field_mul(z2, x, z2, group->meth));
7.174 - MP_CHECKOK(group->meth->field_mul(z2, x1, x1, group->meth));
7.175 - MP_CHECKOK(group->meth->field_add(z2, x2, z2, group->meth));
7.176 -
7.177 - MP_CHECKOK(group->meth->field_mul(z2, z1, z2, group->meth));
7.178 - MP_CHECKOK(group->meth->field_sqr(x, &t4, group->meth));
7.179 - MP_CHECKOK(group->meth->field_add(&t4, y, &t4, group->meth));
7.180 - MP_CHECKOK(group->meth->field_mul(&t4, &t3, &t4, group->meth));
7.181 - MP_CHECKOK(group->meth->field_add(&t4, z2, &t4, group->meth));
7.182 -
7.183 - MP_CHECKOK(group->meth->field_mul(&t3, x, &t3, group->meth));
7.184 - MP_CHECKOK(group->meth->field_div(&t5, &t3, &t3, group->meth));
7.185 - MP_CHECKOK(group->meth->field_mul(&t3, &t4, &t4, group->meth));
7.186 - MP_CHECKOK(group->meth->field_mul(x1, &t3, x2, group->meth));
7.187 - MP_CHECKOK(group->meth->field_add(x2, x, z2, group->meth));
7.188 -
7.189 - MP_CHECKOK(group->meth->field_mul(z2, &t4, z2, group->meth));
7.190 - MP_CHECKOK(group->meth->field_add(z2, y, z2, group->meth));
7.191 -
7.192 - ret = 2;
7.193 -
7.194 - CLEANUP:
7.195 - mp_clear(&t3);
7.196 - mp_clear(&t4);
7.197 - mp_clear(&t5);
7.198 - if (res == MP_OKAY) {
7.199 - return ret;
7.200 - } else {
7.201 - return 0;
7.202 - }
7.203 -}
7.204 -
7.205 -/* Computes R = nP based on algorithm 2P of Lopex, J. and Dahab, R. "Fast
7.206 - * multiplication on elliptic curves over GF(2^m) without
7.207 - * precomputation". Elliptic curve points P and R can be identical. Uses
7.208 - * Montgomery projective coordinates. */
7.209 -mp_err
7.210 -ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px, const mp_int *py,
7.211 - mp_int *rx, mp_int *ry, const ECGroup *group)
7.212 -{
7.213 - mp_err res = MP_OKAY;
7.214 - mp_int x1, x2, z1, z2;
7.215 - int i, j;
7.216 - mp_digit top_bit, mask;
7.217 -
7.218 - MP_DIGITS(&x1) = 0;
7.219 - MP_DIGITS(&x2) = 0;
7.220 - MP_DIGITS(&z1) = 0;
7.221 - MP_DIGITS(&z2) = 0;
7.222 - MP_CHECKOK(mp_init(&x1, FLAG(n)));
7.223 - MP_CHECKOK(mp_init(&x2, FLAG(n)));
7.224 - MP_CHECKOK(mp_init(&z1, FLAG(n)));
7.225 - MP_CHECKOK(mp_init(&z2, FLAG(n)));
7.226 -
7.227 - /* if result should be point at infinity */
7.228 - if ((mp_cmp_z(n) == 0) || (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES)) {
7.229 - MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
7.230 - goto CLEANUP;
7.231 - }
7.232 -
7.233 - MP_CHECKOK(mp_copy(px, &x1)); /* x1 = px */
7.234 - MP_CHECKOK(mp_set_int(&z1, 1)); /* z1 = 1 */
7.235 - MP_CHECKOK(group->meth->field_sqr(&x1, &z2, group->meth)); /* z2 =
7.236 - * x1^2 =
7.237 - * px^2 */
7.238 - MP_CHECKOK(group->meth->field_sqr(&z2, &x2, group->meth));
7.239 - MP_CHECKOK(group->meth->field_add(&x2, &group->curveb, &x2, group->meth)); /* x2
7.240 - * =
7.241 - * px^4
7.242 - * +
7.243 - * b
7.244 - */
7.245 -
7.246 - /* find top-most bit and go one past it */
7.247 - i = MP_USED(n) - 1;
7.248 - j = MP_DIGIT_BIT - 1;
7.249 - top_bit = 1;
7.250 - top_bit <<= MP_DIGIT_BIT - 1;
7.251 - mask = top_bit;
7.252 - while (!(MP_DIGITS(n)[i] & mask)) {
7.253 - mask >>= 1;
7.254 - j--;
7.255 - }
7.256 - mask >>= 1;
7.257 - j--;
7.258 -
7.259 - /* if top most bit was at word break, go to next word */
7.260 - if (!mask) {
7.261 - i--;
7.262 - j = MP_DIGIT_BIT - 1;
7.263 - mask = top_bit;
7.264 - }
7.265 -
7.266 - for (; i >= 0; i--) {
7.267 - for (; j >= 0; j--) {
7.268 - if (MP_DIGITS(n)[i] & mask) {
7.269 - MP_CHECKOK(gf2m_Madd(px, &x1, &z1, &x2, &z2, group, FLAG(n)));
7.270 - MP_CHECKOK(gf2m_Mdouble(&x2, &z2, group, FLAG(n)));
7.271 - } else {
7.272 - MP_CHECKOK(gf2m_Madd(px, &x2, &z2, &x1, &z1, group, FLAG(n)));
7.273 - MP_CHECKOK(gf2m_Mdouble(&x1, &z1, group, FLAG(n)));
7.274 - }
7.275 - mask >>= 1;
7.276 - }
7.277 - j = MP_DIGIT_BIT - 1;
7.278 - mask = top_bit;
7.279 - }
7.280 -
7.281 - /* convert out of "projective" coordinates */
7.282 - i = gf2m_Mxy(px, py, &x1, &z1, &x2, &z2, group);
7.283 - if (i == 0) {
7.284 - res = MP_BADARG;
7.285 - goto CLEANUP;
7.286 - } else if (i == 1) {
7.287 - MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
7.288 - } else {
7.289 - MP_CHECKOK(mp_copy(&x2, rx));
7.290 - MP_CHECKOK(mp_copy(&z2, ry));
7.291 - }
7.292 -
7.293 - CLEANUP:
7.294 - mp_clear(&x1);
7.295 - mp_clear(&x2);
7.296 - mp_clear(&z1);
7.297 - mp_clear(&z2);
7.298 - return res;
7.299 -}
8.1 --- a/src/share/native/sun/security/ec/ec_naf.c Tue Oct 13 15:25:58 2009 -0700
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,123 +0,0 @@
8.4 -/* *********************************************************************
8.5 - *
8.6 - * Sun elects to have this file available under and governed by the
8.7 - * Mozilla Public License Version 1.1 ("MPL") (see
8.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
8.9 - * of doubt and subject to the following, Sun also elects to allow
8.10 - * licensees to use this file under the MPL, the GNU General Public
8.11 - * License version 2 only or the Lesser General Public License version
8.12 - * 2.1 only. Any references to the "GNU General Public License version 2
8.13 - * or later" or "GPL" in the following shall be construed to mean the
8.14 - * GNU General Public License version 2 only. Any references to the "GNU
8.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
8.16 - * following shall be construed to mean the GNU Lesser General Public
8.17 - * License version 2.1 only. However, the following notice accompanied
8.18 - * the original version of this file:
8.19 - *
8.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8.21 - *
8.22 - * The contents of this file are subject to the Mozilla Public License Version
8.23 - * 1.1 (the "License"); you may not use this file except in compliance with
8.24 - * the License. You may obtain a copy of the License at
8.25 - * http://www.mozilla.org/MPL/
8.26 - *
8.27 - * Software distributed under the License is distributed on an "AS IS" basis,
8.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8.29 - * for the specific language governing rights and limitations under the
8.30 - * License.
8.31 - *
8.32 - * The Original Code is the elliptic curve math library.
8.33 - *
8.34 - * The Initial Developer of the Original Code is
8.35 - * Sun Microsystems, Inc.
8.36 - * Portions created by the Initial Developer are Copyright (C) 2003
8.37 - * the Initial Developer. All Rights Reserved.
8.38 - *
8.39 - * Contributor(s):
8.40 - * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
8.41 - *
8.42 - * Alternatively, the contents of this file may be used under the terms of
8.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
8.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
8.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
8.46 - * of those above. If you wish to allow use of your version of this file only
8.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
8.48 - * use your version of this file under the terms of the MPL, indicate your
8.49 - * decision by deleting the provisions above and replace them with the notice
8.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
8.51 - * the provisions above, a recipient may use your version of this file under
8.52 - * the terms of any one of the MPL, the GPL or the LGPL.
8.53 - *
8.54 - *********************************************************************** */
8.55 -/*
8.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
8.57 - * Use is subject to license terms.
8.58 - */
8.59 -
8.60 -#pragma ident "%Z%%M% %I% %E% SMI"
8.61 -
8.62 -#include "ecl-priv.h"
8.63 -
8.64 -/* Returns 2^e as an integer. This is meant to be used for small powers of
8.65 - * two. */
8.66 -int
8.67 -ec_twoTo(int e)
8.68 -{
8.69 - int a = 1;
8.70 - int i;
8.71 -
8.72 - for (i = 0; i < e; i++) {
8.73 - a *= 2;
8.74 - }
8.75 - return a;
8.76 -}
8.77 -
8.78 -/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
8.79 - * be an array of signed char's to output to, bitsize should be the number
8.80 - * of bits of out, in is the original scalar, and w is the window size.
8.81 - * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
8.82 - * Menezes, "Software implementation of elliptic curve cryptography over
8.83 - * binary fields", Proc. CHES 2000. */
8.84 -mp_err
8.85 -ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, int w)
8.86 -{
8.87 - mp_int k;
8.88 - mp_err res = MP_OKAY;
8.89 - int i, twowm1, mask;
8.90 -
8.91 - twowm1 = ec_twoTo(w - 1);
8.92 - mask = 2 * twowm1 - 1;
8.93 -
8.94 - MP_DIGITS(&k) = 0;
8.95 - MP_CHECKOK(mp_init_copy(&k, in));
8.96 -
8.97 - i = 0;
8.98 - /* Compute wNAF form */
8.99 - while (mp_cmp_z(&k) > 0) {
8.100 - if (mp_isodd(&k)) {
8.101 - out[i] = MP_DIGIT(&k, 0) & mask;
8.102 - if (out[i] >= twowm1)
8.103 - out[i] -= 2 * twowm1;
8.104 -
8.105 - /* Subtract off out[i]. Note mp_sub_d only works with
8.106 - * unsigned digits */
8.107 - if (out[i] >= 0) {
8.108 - mp_sub_d(&k, out[i], &k);
8.109 - } else {
8.110 - mp_add_d(&k, -(out[i]), &k);
8.111 - }
8.112 - } else {
8.113 - out[i] = 0;
8.114 - }
8.115 - mp_div_2(&k, &k);
8.116 - i++;
8.117 - }
8.118 - /* Zero out the remaining elements of the out array. */
8.119 - for (; i < bitsize + 1; i++) {
8.120 - out[i] = 0;
8.121 - }
8.122 - CLEANUP:
8.123 - mp_clear(&k);
8.124 - return res;
8.125 -
8.126 -}
9.1 --- a/src/share/native/sun/security/ec/ecc_impl.h Tue Oct 13 15:25:58 2009 -0700
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,278 +0,0 @@
9.4 -/* *********************************************************************
9.5 - *
9.6 - * Sun elects to have this file available under and governed by the
9.7 - * Mozilla Public License Version 1.1 ("MPL") (see
9.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
9.9 - * of doubt and subject to the following, Sun also elects to allow
9.10 - * licensees to use this file under the MPL, the GNU General Public
9.11 - * License version 2 only or the Lesser General Public License version
9.12 - * 2.1 only. Any references to the "GNU General Public License version 2
9.13 - * or later" or "GPL" in the following shall be construed to mean the
9.14 - * GNU General Public License version 2 only. Any references to the "GNU
9.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
9.16 - * following shall be construed to mean the GNU Lesser General Public
9.17 - * License version 2.1 only. However, the following notice accompanied
9.18 - * the original version of this file:
9.19 - *
9.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
9.21 - *
9.22 - * The contents of this file are subject to the Mozilla Public License Version
9.23 - * 1.1 (the "License"); you may not use this file except in compliance with
9.24 - * the License. You may obtain a copy of the License at
9.25 - * http://www.mozilla.org/MPL/
9.26 - *
9.27 - * Software distributed under the License is distributed on an "AS IS" basis,
9.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
9.29 - * for the specific language governing rights and limitations under the
9.30 - * License.
9.31 - *
9.32 - * The Original Code is the Netscape security libraries.
9.33 - *
9.34 - * The Initial Developer of the Original Code is
9.35 - * Netscape Communications Corporation.
9.36 - * Portions created by the Initial Developer are Copyright (C) 1994-2000
9.37 - * the Initial Developer. All Rights Reserved.
9.38 - *
9.39 - * Contributor(s):
9.40 - * Dr Vipul Gupta <vipul.gupta@sun.com> and
9.41 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
9.42 - *
9.43 - * Alternatively, the contents of this file may be used under the terms of
9.44 - * either the GNU General Public License Version 2 or later (the "GPL"), or
9.45 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
9.46 - * in which case the provisions of the GPL or the LGPL are applicable instead
9.47 - * of those above. If you wish to allow use of your version of this file only
9.48 - * under the terms of either the GPL or the LGPL, and not to allow others to
9.49 - * use your version of this file under the terms of the MPL, indicate your
9.50 - * decision by deleting the provisions above and replace them with the notice
9.51 - * and other provisions required by the GPL or the LGPL. If you do not delete
9.52 - * the provisions above, a recipient may use your version of this file under
9.53 - * the terms of any one of the MPL, the GPL or the LGPL.
9.54 - *
9.55 - *********************************************************************** */
9.56 -/*
9.57 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
9.58 - * Use is subject to license terms.
9.59 - */
9.60 -
9.61 -#ifndef _ECC_IMPL_H
9.62 -#define _ECC_IMPL_H
9.63 -
9.64 -#pragma ident "%Z%%M% %I% %E% SMI"
9.65 -
9.66 -#ifdef __cplusplus
9.67 -extern "C" {
9.68 -#endif
9.69 -
9.70 -#include <sys/types.h>
9.71 -#include "ecl-exp.h"
9.72 -
9.73 -/*
9.74 - * Multi-platform definitions
9.75 - */
9.76 -#ifdef __linux__
9.77 -#define B_FALSE FALSE
9.78 -#define B_TRUE TRUE
9.79 -typedef unsigned char uint8_t;
9.80 -typedef unsigned long ulong_t;
9.81 -typedef enum { B_FALSE, B_TRUE } boolean_t;
9.82 -#endif /* __linux__ */
9.83 -
9.84 -#ifdef _WIN32
9.85 -typedef unsigned char uint8_t;
9.86 -typedef unsigned long ulong_t;
9.87 -typedef enum boolean { B_FALSE, B_TRUE } boolean_t;
9.88 -#endif /* _WIN32 */
9.89 -
9.90 -#ifndef _KERNEL
9.91 -#include <stdlib.h>
9.92 -#endif /* _KERNEL */
9.93 -
9.94 -#define EC_MAX_DIGEST_LEN 1024 /* max digest that can be signed */
9.95 -#define EC_MAX_POINT_LEN 145 /* max len of DER encoded Q */
9.96 -#define EC_MAX_VALUE_LEN 72 /* max len of ANSI X9.62 private value d */
9.97 -#define EC_MAX_SIG_LEN 144 /* max signature len for supported curves */
9.98 -#define EC_MIN_KEY_LEN 112 /* min key length in bits */
9.99 -#define EC_MAX_KEY_LEN 571 /* max key length in bits */
9.100 -#define EC_MAX_OID_LEN 10 /* max length of OID buffer */
9.101 -
9.102 -/*
9.103 - * Various structures and definitions from NSS are here.
9.104 - */
9.105 -
9.106 -#ifdef _KERNEL
9.107 -#define PORT_ArenaAlloc(a, n, f) kmem_alloc((n), (f))
9.108 -#define PORT_ArenaZAlloc(a, n, f) kmem_zalloc((n), (f))
9.109 -#define PORT_ArenaGrow(a, b, c, d) NULL
9.110 -#define PORT_ZAlloc(n, f) kmem_zalloc((n), (f))
9.111 -#define PORT_Alloc(n, f) kmem_alloc((n), (f))
9.112 -#else
9.113 -#define PORT_ArenaAlloc(a, n, f) malloc((n))
9.114 -#define PORT_ArenaZAlloc(a, n, f) calloc(1, (n))
9.115 -#define PORT_ArenaGrow(a, b, c, d) NULL
9.116 -#define PORT_ZAlloc(n, f) calloc(1, (n))
9.117 -#define PORT_Alloc(n, f) malloc((n))
9.118 -#endif
9.119 -
9.120 -#define PORT_NewArena(b) (char *)12345
9.121 -#define PORT_ArenaMark(a) NULL
9.122 -#define PORT_ArenaUnmark(a, b)
9.123 -#define PORT_ArenaRelease(a, m)
9.124 -#define PORT_FreeArena(a, b)
9.125 -#define PORT_Strlen(s) strlen((s))
9.126 -#define PORT_SetError(e)
9.127 -
9.128 -#define PRBool boolean_t
9.129 -#define PR_TRUE B_TRUE
9.130 -#define PR_FALSE B_FALSE
9.131 -
9.132 -#ifdef _KERNEL
9.133 -#define PORT_Assert ASSERT
9.134 -#define PORT_Memcpy(t, f, l) bcopy((f), (t), (l))
9.135 -#else
9.136 -#define PORT_Assert assert
9.137 -#define PORT_Memcpy(t, f, l) memcpy((t), (f), (l))
9.138 -#endif
9.139 -
9.140 -#define CHECK_OK(func) if (func == NULL) goto cleanup
9.141 -#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
9.142 -
9.143 -typedef enum {
9.144 - siBuffer = 0,
9.145 - siClearDataBuffer = 1,
9.146 - siCipherDataBuffer = 2,
9.147 - siDERCertBuffer = 3,
9.148 - siEncodedCertBuffer = 4,
9.149 - siDERNameBuffer = 5,
9.150 - siEncodedNameBuffer = 6,
9.151 - siAsciiNameString = 7,
9.152 - siAsciiString = 8,
9.153 - siDEROID = 9,
9.154 - siUnsignedInteger = 10,
9.155 - siUTCTime = 11,
9.156 - siGeneralizedTime = 12
9.157 -} SECItemType;
9.158 -
9.159 -typedef struct SECItemStr SECItem;
9.160 -
9.161 -struct SECItemStr {
9.162 - SECItemType type;
9.163 - unsigned char *data;
9.164 - unsigned int len;
9.165 -};
9.166 -
9.167 -typedef SECItem SECKEYECParams;
9.168 -
9.169 -typedef enum { ec_params_explicit,
9.170 - ec_params_named
9.171 -} ECParamsType;
9.172 -
9.173 -typedef enum { ec_field_GFp = 1,
9.174 - ec_field_GF2m
9.175 -} ECFieldType;
9.176 -
9.177 -struct ECFieldIDStr {
9.178 - int size; /* field size in bits */
9.179 - ECFieldType type;
9.180 - union {
9.181 - SECItem prime; /* prime p for (GFp) */
9.182 - SECItem poly; /* irreducible binary polynomial for (GF2m) */
9.183 - } u;
9.184 - int k1; /* first coefficient of pentanomial or
9.185 - * the only coefficient of trinomial
9.186 - */
9.187 - int k2; /* two remaining coefficients of pentanomial */
9.188 - int k3;
9.189 -};
9.190 -typedef struct ECFieldIDStr ECFieldID;
9.191 -
9.192 -struct ECCurveStr {
9.193 - SECItem a; /* contains octet stream encoding of
9.194 - * field element (X9.62 section 4.3.3)
9.195 - */
9.196 - SECItem b;
9.197 - SECItem seed;
9.198 -};
9.199 -typedef struct ECCurveStr ECCurve;
9.200 -
9.201 -typedef void PRArenaPool;
9.202 -
9.203 -struct ECParamsStr {
9.204 - PRArenaPool * arena;
9.205 - ECParamsType type;
9.206 - ECFieldID fieldID;
9.207 - ECCurve curve;
9.208 - SECItem base;
9.209 - SECItem order;
9.210 - int cofactor;
9.211 - SECItem DEREncoding;
9.212 - ECCurveName name;
9.213 - SECItem curveOID;
9.214 -};
9.215 -typedef struct ECParamsStr ECParams;
9.216 -
9.217 -struct ECPublicKeyStr {
9.218 - ECParams ecParams;
9.219 - SECItem publicValue; /* elliptic curve point encoded as
9.220 - * octet stream.
9.221 - */
9.222 -};
9.223 -typedef struct ECPublicKeyStr ECPublicKey;
9.224 -
9.225 -struct ECPrivateKeyStr {
9.226 - ECParams ecParams;
9.227 - SECItem publicValue; /* encoded ec point */
9.228 - SECItem privateValue; /* private big integer */
9.229 - SECItem version; /* As per SEC 1, Appendix C, Section C.4 */
9.230 -};
9.231 -typedef struct ECPrivateKeyStr ECPrivateKey;
9.232 -
9.233 -typedef enum _SECStatus {
9.234 - SECBufferTooSmall = -3,
9.235 - SECWouldBlock = -2,
9.236 - SECFailure = -1,
9.237 - SECSuccess = 0
9.238 -} SECStatus;
9.239 -
9.240 -#ifdef _KERNEL
9.241 -#define RNG_GenerateGlobalRandomBytes(p,l) ecc_knzero_random_generator((p), (l))
9.242 -#else
9.243 -/*
9.244 - This function is no longer required because the random bytes are now
9.245 - supplied by the caller. Force a failure.
9.246 -VR
9.247 -#define RNG_GenerateGlobalRandomBytes(p,l) SECFailure
9.248 -*/
9.249 -#define RNG_GenerateGlobalRandomBytes(p,l) SECSuccess
9.250 -#endif
9.251 -#define CHECK_MPI_OK(func) if (MP_OKAY > (err = func)) goto cleanup
9.252 -#define MP_TO_SEC_ERROR(err)
9.253 -
9.254 -#define SECITEM_TO_MPINT(it, mp) \
9.255 - CHECK_MPI_OK(mp_read_unsigned_octets((mp), (it).data, (it).len))
9.256 -
9.257 -extern int ecc_knzero_random_generator(uint8_t *, size_t);
9.258 -extern ulong_t soft_nzero_random_generator(uint8_t *, ulong_t);
9.259 -
9.260 -extern SECStatus EC_DecodeParams(const SECItem *, ECParams **, int);
9.261 -extern SECItem * SECITEM_AllocItem(PRArenaPool *, SECItem *, unsigned int, int);
9.262 -extern SECStatus SECITEM_CopyItem(PRArenaPool *, SECItem *, const SECItem *,
9.263 - int);
9.264 -extern void SECITEM_FreeItem(SECItem *, boolean_t);
9.265 -extern SECStatus EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey, const unsigned char* random, int randomlen, int);
9.266 -extern SECStatus EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
9.267 - const unsigned char *seed, int seedlen, int kmflag);
9.268 -extern SECStatus ECDSA_SignDigest(ECPrivateKey *, SECItem *, const SECItem *,
9.269 - const unsigned char* randon, int randomlen, int);
9.270 -extern SECStatus ECDSA_SignDigestWithSeed(ECPrivateKey *, SECItem *,
9.271 - const SECItem *, const unsigned char *seed, int seedlen, int kmflag);
9.272 -extern SECStatus ECDSA_VerifyDigest(ECPublicKey *, const SECItem *,
9.273 - const SECItem *, int);
9.274 -extern SECStatus ECDH_Derive(SECItem *, ECParams *, SECItem *, boolean_t,
9.275 - SECItem *, int);
9.276 -
9.277 -#ifdef __cplusplus
9.278 -}
9.279 -#endif
9.280 -
9.281 -#endif /* _ECC_IMPL_H */
10.1 --- a/src/share/native/sun/security/ec/ecdecode.c Tue Oct 13 15:25:58 2009 -0700
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,632 +0,0 @@
10.4 -/* *********************************************************************
10.5 - *
10.6 - * Sun elects to have this file available under and governed by the
10.7 - * Mozilla Public License Version 1.1 ("MPL") (see
10.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
10.9 - * of doubt and subject to the following, Sun also elects to allow
10.10 - * licensees to use this file under the MPL, the GNU General Public
10.11 - * License version 2 only or the Lesser General Public License version
10.12 - * 2.1 only. Any references to the "GNU General Public License version 2
10.13 - * or later" or "GPL" in the following shall be construed to mean the
10.14 - * GNU General Public License version 2 only. Any references to the "GNU
10.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
10.16 - * following shall be construed to mean the GNU Lesser General Public
10.17 - * License version 2.1 only. However, the following notice accompanied
10.18 - * the original version of this file:
10.19 - *
10.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
10.21 - *
10.22 - * The contents of this file are subject to the Mozilla Public License Version
10.23 - * 1.1 (the "License"); you may not use this file except in compliance with
10.24 - * the License. You may obtain a copy of the License at
10.25 - * http://www.mozilla.org/MPL/
10.26 - *
10.27 - * Software distributed under the License is distributed on an "AS IS" basis,
10.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10.29 - * for the specific language governing rights and limitations under the
10.30 - * License.
10.31 - *
10.32 - * The Original Code is the Elliptic Curve Cryptography library.
10.33 - *
10.34 - * The Initial Developer of the Original Code is
10.35 - * Sun Microsystems, Inc.
10.36 - * Portions created by the Initial Developer are Copyright (C) 2003
10.37 - * the Initial Developer. All Rights Reserved.
10.38 - *
10.39 - * Contributor(s):
10.40 - * Dr Vipul Gupta <vipul.gupta@sun.com> and
10.41 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
10.42 - *
10.43 - * Alternatively, the contents of this file may be used under the terms of
10.44 - * either the GNU General Public License Version 2 or later (the "GPL"), or
10.45 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
10.46 - * in which case the provisions of the GPL or the LGPL are applicable instead
10.47 - * of those above. If you wish to allow use of your version of this file only
10.48 - * under the terms of either the GPL or the LGPL, and not to allow others to
10.49 - * use your version of this file under the terms of the MPL, indicate your
10.50 - * decision by deleting the provisions above and replace them with the notice
10.51 - * and other provisions required by the GPL or the LGPL. If you do not delete
10.52 - * the provisions above, a recipient may use your version of this file under
10.53 - * the terms of any one of the MPL, the GPL or the LGPL.
10.54 - *
10.55 - *********************************************************************** */
10.56 -/*
10.57 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
10.58 - * Use is subject to license terms.
10.59 - */
10.60 -
10.61 -#pragma ident "%Z%%M% %I% %E% SMI"
10.62 -
10.63 -#include <sys/types.h>
10.64 -
10.65 -#ifndef _WIN32
10.66 -#ifndef __linux__
10.67 -#include <sys/systm.h>
10.68 -#endif /* __linux__ */
10.69 -#include <sys/param.h>
10.70 -#endif /* _WIN32 */
10.71 -
10.72 -#ifdef _KERNEL
10.73 -#include <sys/kmem.h>
10.74 -#else
10.75 -#include <string.h>
10.76 -#endif
10.77 -#include "ec.h"
10.78 -#include "ecl-curve.h"
10.79 -#include "ecc_impl.h"
10.80 -
10.81 -#define MAX_ECKEY_LEN 72
10.82 -#define SEC_ASN1_OBJECT_ID 0x06
10.83 -
10.84 -/*
10.85 - * Initializes a SECItem from a hexadecimal string
10.86 - *
10.87 - * Warning: This function ignores leading 00's, so any leading 00's
10.88 - * in the hexadecimal string must be optional.
10.89 - */
10.90 -static SECItem *
10.91 -hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str,
10.92 - int kmflag)
10.93 -{
10.94 - int i = 0;
10.95 - int byteval = 0;
10.96 - int tmp = strlen(str);
10.97 -
10.98 - if ((tmp % 2) != 0) return NULL;
10.99 -
10.100 - /* skip leading 00's unless the hex string is "00" */
10.101 - while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
10.102 - str += 2;
10.103 - tmp -= 2;
10.104 - }
10.105 -
10.106 - item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2, kmflag);
10.107 - if (item->data == NULL) return NULL;
10.108 - item->len = tmp/2;
10.109 -
10.110 - while (str[i]) {
10.111 - if ((str[i] >= '0') && (str[i] <= '9'))
10.112 - tmp = str[i] - '0';
10.113 - else if ((str[i] >= 'a') && (str[i] <= 'f'))
10.114 - tmp = str[i] - 'a' + 10;
10.115 - else if ((str[i] >= 'A') && (str[i] <= 'F'))
10.116 - tmp = str[i] - 'A' + 10;
10.117 - else
10.118 - return NULL;
10.119 -
10.120 - byteval = byteval * 16 + tmp;
10.121 - if ((i % 2) != 0) {
10.122 - item->data[i/2] = byteval;
10.123 - byteval = 0;
10.124 - }
10.125 - i++;
10.126 - }
10.127 -
10.128 - return item;
10.129 -}
10.130 -
10.131 -static SECStatus
10.132 -gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params,
10.133 - int kmflag)
10.134 -{
10.135 - SECStatus rv = SECFailure;
10.136 - const ECCurveParams *curveParams;
10.137 - /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
10.138 - char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
10.139 -
10.140 - if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
10.141 - params->name = name;
10.142 - curveParams = ecCurve_map[params->name];
10.143 - CHECK_OK(curveParams);
10.144 - params->fieldID.size = curveParams->size;
10.145 - params->fieldID.type = field_type;
10.146 - if (field_type == ec_field_GFp) {
10.147 - CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.prime,
10.148 - curveParams->irr, kmflag));
10.149 - } else {
10.150 - CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.poly,
10.151 - curveParams->irr, kmflag));
10.152 - }
10.153 - CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.a,
10.154 - curveParams->curvea, kmflag));
10.155 - CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.b,
10.156 - curveParams->curveb, kmflag));
10.157 - genenc[0] = '0';
10.158 - genenc[1] = '4';
10.159 - genenc[2] = '\0';
10.160 - strcat(genenc, curveParams->genx);
10.161 - strcat(genenc, curveParams->geny);
10.162 - CHECK_OK(hexString2SECItem(NULL, ¶ms->base, genenc, kmflag));
10.163 - CHECK_OK(hexString2SECItem(NULL, ¶ms->order,
10.164 - curveParams->order, kmflag));
10.165 - params->cofactor = curveParams->cofactor;
10.166 -
10.167 - rv = SECSuccess;
10.168 -
10.169 -cleanup:
10.170 - return rv;
10.171 -}
10.172 -
10.173 -ECCurveName SECOID_FindOIDTag(const SECItem *);
10.174 -
10.175 -SECStatus
10.176 -EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
10.177 - ECParams *params, int kmflag)
10.178 -{
10.179 - SECStatus rv = SECFailure;
10.180 - ECCurveName tag;
10.181 - SECItem oid = { siBuffer, NULL, 0};
10.182 -
10.183 -#if EC_DEBUG
10.184 - int i;
10.185 -
10.186 - printf("Encoded params in EC_DecodeParams: ");
10.187 - for (i = 0; i < encodedParams->len; i++) {
10.188 - printf("%02x:", encodedParams->data[i]);
10.189 - }
10.190 - printf("\n");
10.191 -#endif
10.192 -
10.193 - if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
10.194 - (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
10.195 - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
10.196 - return SECFailure;
10.197 - };
10.198 -
10.199 - oid.len = encodedParams->len - 2;
10.200 - oid.data = encodedParams->data + 2;
10.201 - if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
10.202 - ((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) {
10.203 - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
10.204 - return SECFailure;
10.205 - }
10.206 -
10.207 - params->arena = arena;
10.208 - params->cofactor = 0;
10.209 - params->type = ec_params_named;
10.210 - params->name = ECCurve_noName;
10.211 -
10.212 - /* For named curves, fill out curveOID */
10.213 - params->curveOID.len = oid.len;
10.214 - params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len,
10.215 - kmflag);
10.216 - if (params->curveOID.data == NULL) goto cleanup;
10.217 - memcpy(params->curveOID.data, oid.data, oid.len);
10.218 -
10.219 -#if EC_DEBUG
10.220 -#ifndef SECOID_FindOIDTagDescription
10.221 - printf("Curve: %s\n", ecCurve_map[tag]->text);
10.222 -#else
10.223 - printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
10.224 -#endif
10.225 -#endif
10.226 -
10.227 - switch (tag) {
10.228 -
10.229 - /* Binary curves */
10.230 -
10.231 - case ECCurve_X9_62_CHAR2_PNB163V1:
10.232 - /* Populate params for c2pnb163v1 */
10.233 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
10.234 - params, kmflag) );
10.235 - break;
10.236 -
10.237 - case ECCurve_X9_62_CHAR2_PNB163V2:
10.238 - /* Populate params for c2pnb163v2 */
10.239 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
10.240 - params, kmflag) );
10.241 - break;
10.242 -
10.243 - case ECCurve_X9_62_CHAR2_PNB163V3:
10.244 - /* Populate params for c2pnb163v3 */
10.245 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
10.246 - params, kmflag) );
10.247 - break;
10.248 -
10.249 - case ECCurve_X9_62_CHAR2_PNB176V1:
10.250 - /* Populate params for c2pnb176v1 */
10.251 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
10.252 - params, kmflag) );
10.253 - break;
10.254 -
10.255 - case ECCurve_X9_62_CHAR2_TNB191V1:
10.256 - /* Populate params for c2tnb191v1 */
10.257 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
10.258 - params, kmflag) );
10.259 - break;
10.260 -
10.261 - case ECCurve_X9_62_CHAR2_TNB191V2:
10.262 - /* Populate params for c2tnb191v2 */
10.263 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
10.264 - params, kmflag) );
10.265 - break;
10.266 -
10.267 - case ECCurve_X9_62_CHAR2_TNB191V3:
10.268 - /* Populate params for c2tnb191v3 */
10.269 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
10.270 - params, kmflag) );
10.271 - break;
10.272 -
10.273 - case ECCurve_X9_62_CHAR2_PNB208W1:
10.274 - /* Populate params for c2pnb208w1 */
10.275 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
10.276 - params, kmflag) );
10.277 - break;
10.278 -
10.279 - case ECCurve_X9_62_CHAR2_TNB239V1:
10.280 - /* Populate params for c2tnb239v1 */
10.281 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
10.282 - params, kmflag) );
10.283 - break;
10.284 -
10.285 - case ECCurve_X9_62_CHAR2_TNB239V2:
10.286 - /* Populate params for c2tnb239v2 */
10.287 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
10.288 - params, kmflag) );
10.289 - break;
10.290 -
10.291 - case ECCurve_X9_62_CHAR2_TNB239V3:
10.292 - /* Populate params for c2tnb239v3 */
10.293 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
10.294 - params, kmflag) );
10.295 - break;
10.296 -
10.297 - case ECCurve_X9_62_CHAR2_PNB272W1:
10.298 - /* Populate params for c2pnb272w1 */
10.299 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
10.300 - params, kmflag) );
10.301 - break;
10.302 -
10.303 - case ECCurve_X9_62_CHAR2_PNB304W1:
10.304 - /* Populate params for c2pnb304w1 */
10.305 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
10.306 - params, kmflag) );
10.307 - break;
10.308 -
10.309 - case ECCurve_X9_62_CHAR2_TNB359V1:
10.310 - /* Populate params for c2tnb359v1 */
10.311 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
10.312 - params, kmflag) );
10.313 - break;
10.314 -
10.315 - case ECCurve_X9_62_CHAR2_PNB368W1:
10.316 - /* Populate params for c2pnb368w1 */
10.317 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
10.318 - params, kmflag) );
10.319 - break;
10.320 -
10.321 - case ECCurve_X9_62_CHAR2_TNB431R1:
10.322 - /* Populate params for c2tnb431r1 */
10.323 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
10.324 - params, kmflag) );
10.325 - break;
10.326 -
10.327 - case ECCurve_SECG_CHAR2_113R1:
10.328 - /* Populate params for sect113r1 */
10.329 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
10.330 - params, kmflag) );
10.331 - break;
10.332 -
10.333 - case ECCurve_SECG_CHAR2_113R2:
10.334 - /* Populate params for sect113r2 */
10.335 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
10.336 - params, kmflag) );
10.337 - break;
10.338 -
10.339 - case ECCurve_SECG_CHAR2_131R1:
10.340 - /* Populate params for sect131r1 */
10.341 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
10.342 - params, kmflag) );
10.343 - break;
10.344 -
10.345 - case ECCurve_SECG_CHAR2_131R2:
10.346 - /* Populate params for sect131r2 */
10.347 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
10.348 - params, kmflag) );
10.349 - break;
10.350 -
10.351 - case ECCurve_SECG_CHAR2_163K1:
10.352 - /* Populate params for sect163k1
10.353 - * (the NIST K-163 curve)
10.354 - */
10.355 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
10.356 - params, kmflag) );
10.357 - break;
10.358 -
10.359 - case ECCurve_SECG_CHAR2_163R1:
10.360 - /* Populate params for sect163r1 */
10.361 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
10.362 - params, kmflag) );
10.363 - break;
10.364 -
10.365 - case ECCurve_SECG_CHAR2_163R2:
10.366 - /* Populate params for sect163r2
10.367 - * (the NIST B-163 curve)
10.368 - */
10.369 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
10.370 - params, kmflag) );
10.371 - break;
10.372 -
10.373 - case ECCurve_SECG_CHAR2_193R1:
10.374 - /* Populate params for sect193r1 */
10.375 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
10.376 - params, kmflag) );
10.377 - break;
10.378 -
10.379 - case ECCurve_SECG_CHAR2_193R2:
10.380 - /* Populate params for sect193r2 */
10.381 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
10.382 - params, kmflag) );
10.383 - break;
10.384 -
10.385 - case ECCurve_SECG_CHAR2_233K1:
10.386 - /* Populate params for sect233k1
10.387 - * (the NIST K-233 curve)
10.388 - */
10.389 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
10.390 - params, kmflag) );
10.391 - break;
10.392 -
10.393 - case ECCurve_SECG_CHAR2_233R1:
10.394 - /* Populate params for sect233r1
10.395 - * (the NIST B-233 curve)
10.396 - */
10.397 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
10.398 - params, kmflag) );
10.399 - break;
10.400 -
10.401 - case ECCurve_SECG_CHAR2_239K1:
10.402 - /* Populate params for sect239k1 */
10.403 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
10.404 - params, kmflag) );
10.405 - break;
10.406 -
10.407 - case ECCurve_SECG_CHAR2_283K1:
10.408 - /* Populate params for sect283k1
10.409 - * (the NIST K-283 curve)
10.410 - */
10.411 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
10.412 - params, kmflag) );
10.413 - break;
10.414 -
10.415 - case ECCurve_SECG_CHAR2_283R1:
10.416 - /* Populate params for sect283r1
10.417 - * (the NIST B-283 curve)
10.418 - */
10.419 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
10.420 - params, kmflag) );
10.421 - break;
10.422 -
10.423 - case ECCurve_SECG_CHAR2_409K1:
10.424 - /* Populate params for sect409k1
10.425 - * (the NIST K-409 curve)
10.426 - */
10.427 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
10.428 - params, kmflag) );
10.429 - break;
10.430 -
10.431 - case ECCurve_SECG_CHAR2_409R1:
10.432 - /* Populate params for sect409r1
10.433 - * (the NIST B-409 curve)
10.434 - */
10.435 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
10.436 - params, kmflag) );
10.437 - break;
10.438 -
10.439 - case ECCurve_SECG_CHAR2_571K1:
10.440 - /* Populate params for sect571k1
10.441 - * (the NIST K-571 curve)
10.442 - */
10.443 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
10.444 - params, kmflag) );
10.445 - break;
10.446 -
10.447 - case ECCurve_SECG_CHAR2_571R1:
10.448 - /* Populate params for sect571r1
10.449 - * (the NIST B-571 curve)
10.450 - */
10.451 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
10.452 - params, kmflag) );
10.453 - break;
10.454 -
10.455 - /* Prime curves */
10.456 -
10.457 - case ECCurve_X9_62_PRIME_192V1:
10.458 - /* Populate params for prime192v1 aka secp192r1
10.459 - * (the NIST P-192 curve)
10.460 - */
10.461 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
10.462 - params, kmflag) );
10.463 - break;
10.464 -
10.465 - case ECCurve_X9_62_PRIME_192V2:
10.466 - /* Populate params for prime192v2 */
10.467 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
10.468 - params, kmflag) );
10.469 - break;
10.470 -
10.471 - case ECCurve_X9_62_PRIME_192V3:
10.472 - /* Populate params for prime192v3 */
10.473 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
10.474 - params, kmflag) );
10.475 - break;
10.476 -
10.477 - case ECCurve_X9_62_PRIME_239V1:
10.478 - /* Populate params for prime239v1 */
10.479 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
10.480 - params, kmflag) );
10.481 - break;
10.482 -
10.483 - case ECCurve_X9_62_PRIME_239V2:
10.484 - /* Populate params for prime239v2 */
10.485 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
10.486 - params, kmflag) );
10.487 - break;
10.488 -
10.489 - case ECCurve_X9_62_PRIME_239V3:
10.490 - /* Populate params for prime239v3 */
10.491 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
10.492 - params, kmflag) );
10.493 - break;
10.494 -
10.495 - case ECCurve_X9_62_PRIME_256V1:
10.496 - /* Populate params for prime256v1 aka secp256r1
10.497 - * (the NIST P-256 curve)
10.498 - */
10.499 - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
10.500 - params, kmflag) );
10.501 - break;
10.502 -
10.503 - case ECCurve_SECG_PRIME_112R1:
10.504 - /* Populate params for secp112r1 */
10.505 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
10.506 - params, kmflag) );
10.507 - break;
10.508 -
10.509 - case ECCurve_SECG_PRIME_112R2:
10.510 - /* Populate params for secp112r2 */
10.511 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
10.512 - params, kmflag) );
10.513 - break;
10.514 -
10.515 - case ECCurve_SECG_PRIME_128R1:
10.516 - /* Populate params for secp128r1 */
10.517 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
10.518 - params, kmflag) );
10.519 - break;
10.520 -
10.521 - case ECCurve_SECG_PRIME_128R2:
10.522 - /* Populate params for secp128r2 */
10.523 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
10.524 - params, kmflag) );
10.525 - break;
10.526 -
10.527 - case ECCurve_SECG_PRIME_160K1:
10.528 - /* Populate params for secp160k1 */
10.529 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
10.530 - params, kmflag) );
10.531 - break;
10.532 -
10.533 - case ECCurve_SECG_PRIME_160R1:
10.534 - /* Populate params for secp160r1 */
10.535 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
10.536 - params, kmflag) );
10.537 - break;
10.538 -
10.539 - case ECCurve_SECG_PRIME_160R2:
10.540 - /* Populate params for secp160r1 */
10.541 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
10.542 - params, kmflag) );
10.543 - break;
10.544 -
10.545 - case ECCurve_SECG_PRIME_192K1:
10.546 - /* Populate params for secp192k1 */
10.547 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
10.548 - params, kmflag) );
10.549 - break;
10.550 -
10.551 - case ECCurve_SECG_PRIME_224K1:
10.552 - /* Populate params for secp224k1 */
10.553 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
10.554 - params, kmflag) );
10.555 - break;
10.556 -
10.557 - case ECCurve_SECG_PRIME_224R1:
10.558 - /* Populate params for secp224r1
10.559 - * (the NIST P-224 curve)
10.560 - */
10.561 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
10.562 - params, kmflag) );
10.563 - break;
10.564 -
10.565 - case ECCurve_SECG_PRIME_256K1:
10.566 - /* Populate params for secp256k1 */
10.567 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
10.568 - params, kmflag) );
10.569 - break;
10.570 -
10.571 - case ECCurve_SECG_PRIME_384R1:
10.572 - /* Populate params for secp384r1
10.573 - * (the NIST P-384 curve)
10.574 - */
10.575 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
10.576 - params, kmflag) );
10.577 - break;
10.578 -
10.579 - case ECCurve_SECG_PRIME_521R1:
10.580 - /* Populate params for secp521r1
10.581 - * (the NIST P-521 curve)
10.582 - */
10.583 - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
10.584 - params, kmflag) );
10.585 - break;
10.586 -
10.587 - default:
10.588 - break;
10.589 - };
10.590 -
10.591 -cleanup:
10.592 - if (!params->cofactor) {
10.593 - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
10.594 -#if EC_DEBUG
10.595 - printf("Unrecognized curve, returning NULL params\n");
10.596 -#endif
10.597 - }
10.598 -
10.599 - return rv;
10.600 -}
10.601 -
10.602 -SECStatus
10.603 -EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams, int kmflag)
10.604 -{
10.605 - PRArenaPool *arena;
10.606 - ECParams *params;
10.607 - SECStatus rv = SECFailure;
10.608 -
10.609 - /* Initialize an arena for the ECParams structure */
10.610 - if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
10.611 - return SECFailure;
10.612 -
10.613 - params = (ECParams *)PORT_ArenaZAlloc(NULL, sizeof(ECParams), kmflag);
10.614 - if (!params) {
10.615 - PORT_FreeArena(NULL, B_TRUE);
10.616 - return SECFailure;
10.617 - }
10.618 -
10.619 - /* Copy the encoded params */
10.620 - SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len,
10.621 - kmflag);
10.622 - memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
10.623 -
10.624 - /* Fill out the rest of the ECParams structure based on
10.625 - * the encoded params
10.626 - */
10.627 - rv = EC_FillParams(NULL, encodedParams, params, kmflag);
10.628 - if (rv == SECFailure) {
10.629 - PORT_FreeArena(NULL, B_TRUE);
10.630 - return SECFailure;
10.631 - } else {
10.632 - *ecparams = params;;
10.633 - return SECSuccess;
10.634 - }
10.635 -}
11.1 --- a/src/share/native/sun/security/ec/ecl-curve.h Tue Oct 13 15:25:58 2009 -0700
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,710 +0,0 @@
11.4 -/* *********************************************************************
11.5 - *
11.6 - * Sun elects to have this file available under and governed by the
11.7 - * Mozilla Public License Version 1.1 ("MPL") (see
11.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
11.9 - * of doubt and subject to the following, Sun also elects to allow
11.10 - * licensees to use this file under the MPL, the GNU General Public
11.11 - * License version 2 only or the Lesser General Public License version
11.12 - * 2.1 only. Any references to the "GNU General Public License version 2
11.13 - * or later" or "GPL" in the following shall be construed to mean the
11.14 - * GNU General Public License version 2 only. Any references to the "GNU
11.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
11.16 - * following shall be construed to mean the GNU Lesser General Public
11.17 - * License version 2.1 only. However, the following notice accompanied
11.18 - * the original version of this file:
11.19 - *
11.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
11.21 - *
11.22 - * The contents of this file are subject to the Mozilla Public License Version
11.23 - * 1.1 (the "License"); you may not use this file except in compliance with
11.24 - * the License. You may obtain a copy of the License at
11.25 - * http://www.mozilla.org/MPL/
11.26 - *
11.27 - * Software distributed under the License is distributed on an "AS IS" basis,
11.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11.29 - * for the specific language governing rights and limitations under the
11.30 - * License.
11.31 - *
11.32 - * The Original Code is the elliptic curve math library.
11.33 - *
11.34 - * The Initial Developer of the Original Code is
11.35 - * Sun Microsystems, Inc.
11.36 - * Portions created by the Initial Developer are Copyright (C) 2003
11.37 - * the Initial Developer. All Rights Reserved.
11.38 - *
11.39 - * Contributor(s):
11.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
11.41 - *
11.42 - * Alternatively, the contents of this file may be used under the terms of
11.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
11.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
11.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
11.46 - * of those above. If you wish to allow use of your version of this file only
11.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
11.48 - * use your version of this file under the terms of the MPL, indicate your
11.49 - * decision by deleting the provisions above and replace them with the notice
11.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
11.51 - * the provisions above, a recipient may use your version of this file under
11.52 - * the terms of any one of the MPL, the GPL or the LGPL.
11.53 - *
11.54 - *********************************************************************** */
11.55 -/*
11.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
11.57 - * Use is subject to license terms.
11.58 - */
11.59 -
11.60 -#ifndef _ECL_CURVE_H
11.61 -#define _ECL_CURVE_H
11.62 -
11.63 -#pragma ident "%Z%%M% %I% %E% SMI"
11.64 -
11.65 -#include "ecl-exp.h"
11.66 -#ifndef _KERNEL
11.67 -#include <stdlib.h>
11.68 -#endif
11.69 -
11.70 -/* NIST prime curves */
11.71 -static const ECCurveParams ecCurve_NIST_P192 = {
11.72 - "NIST-P192", ECField_GFp, 192,
11.73 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
11.74 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
11.75 - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
11.76 - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
11.77 - "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
11.78 - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 1
11.79 -};
11.80 -
11.81 -static const ECCurveParams ecCurve_NIST_P224 = {
11.82 - "NIST-P224", ECField_GFp, 224,
11.83 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
11.84 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
11.85 - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
11.86 - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
11.87 - "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
11.88 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1
11.89 -};
11.90 -
11.91 -static const ECCurveParams ecCurve_NIST_P256 = {
11.92 - "NIST-P256", ECField_GFp, 256,
11.93 - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
11.94 - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
11.95 - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
11.96 - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
11.97 - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
11.98 - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1
11.99 -};
11.100 -
11.101 -static const ECCurveParams ecCurve_NIST_P384 = {
11.102 - "NIST-P384", ECField_GFp, 384,
11.103 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
11.104 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
11.105 - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
11.106 - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
11.107 - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
11.108 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
11.109 - 1
11.110 -};
11.111 -
11.112 -static const ECCurveParams ecCurve_NIST_P521 = {
11.113 - "NIST-P521", ECField_GFp, 521,
11.114 - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
11.115 - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
11.116 - "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
11.117 - "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
11.118 - "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
11.119 - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
11.120 - 1
11.121 -};
11.122 -
11.123 -/* NIST binary curves */
11.124 -static const ECCurveParams ecCurve_NIST_K163 = {
11.125 - "NIST-K163", ECField_GF2m, 163,
11.126 - "0800000000000000000000000000000000000000C9",
11.127 - "000000000000000000000000000000000000000001",
11.128 - "000000000000000000000000000000000000000001",
11.129 - "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
11.130 - "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
11.131 - "04000000000000000000020108A2E0CC0D99F8A5EF", 2
11.132 -};
11.133 -
11.134 -static const ECCurveParams ecCurve_NIST_B163 = {
11.135 - "NIST-B163", ECField_GF2m, 163,
11.136 - "0800000000000000000000000000000000000000C9",
11.137 - "000000000000000000000000000000000000000001",
11.138 - "020A601907B8C953CA1481EB10512F78744A3205FD",
11.139 - "03F0EBA16286A2D57EA0991168D4994637E8343E36",
11.140 - "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
11.141 - "040000000000000000000292FE77E70C12A4234C33", 2
11.142 -};
11.143 -
11.144 -static const ECCurveParams ecCurve_NIST_K233 = {
11.145 - "NIST-K233", ECField_GF2m, 233,
11.146 - "020000000000000000000000000000000000000004000000000000000001",
11.147 - "000000000000000000000000000000000000000000000000000000000000",
11.148 - "000000000000000000000000000000000000000000000000000000000001",
11.149 - "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
11.150 - "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
11.151 - "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4
11.152 -};
11.153 -
11.154 -static const ECCurveParams ecCurve_NIST_B233 = {
11.155 - "NIST-B233", ECField_GF2m, 233,
11.156 - "020000000000000000000000000000000000000004000000000000000001",
11.157 - "000000000000000000000000000000000000000000000000000000000001",
11.158 - "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
11.159 - "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
11.160 - "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
11.161 - "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2
11.162 -};
11.163 -
11.164 -static const ECCurveParams ecCurve_NIST_K283 = {
11.165 - "NIST-K283", ECField_GF2m, 283,
11.166 - "0800000000000000000000000000000000000000000000000000000000000000000010A1",
11.167 - "000000000000000000000000000000000000000000000000000000000000000000000000",
11.168 - "000000000000000000000000000000000000000000000000000000000000000000000001",
11.169 - "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
11.170 - "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
11.171 - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", 4
11.172 -};
11.173 -
11.174 -static const ECCurveParams ecCurve_NIST_B283 = {
11.175 - "NIST-B283", ECField_GF2m, 283,
11.176 - "0800000000000000000000000000000000000000000000000000000000000000000010A1",
11.177 - "000000000000000000000000000000000000000000000000000000000000000000000001",
11.178 - "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
11.179 - "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
11.180 - "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
11.181 - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 2
11.182 -};
11.183 -
11.184 -static const ECCurveParams ecCurve_NIST_K409 = {
11.185 - "NIST-K409", ECField_GF2m, 409,
11.186 - "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
11.187 - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
11.188 - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
11.189 - "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
11.190 - "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
11.191 - "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4
11.192 -};
11.193 -
11.194 -static const ECCurveParams ecCurve_NIST_B409 = {
11.195 - "NIST-B409", ECField_GF2m, 409,
11.196 - "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
11.197 - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
11.198 - "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
11.199 - "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
11.200 - "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
11.201 - "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", 2
11.202 -};
11.203 -
11.204 -static const ECCurveParams ecCurve_NIST_K571 = {
11.205 - "NIST-K571", ECField_GF2m, 571,
11.206 - "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
11.207 - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
11.208 - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
11.209 - "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
11.210 - "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
11.211 - "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", 4
11.212 -};
11.213 -
11.214 -static const ECCurveParams ecCurve_NIST_B571 = {
11.215 - "NIST-B571", ECField_GF2m, 571,
11.216 - "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
11.217 - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
11.218 - "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
11.219 - "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
11.220 - "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
11.221 - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", 2
11.222 -};
11.223 -
11.224 -/* ANSI X9.62 prime curves */
11.225 -static const ECCurveParams ecCurve_X9_62_PRIME_192V2 = {
11.226 - "X9.62 P-192V2", ECField_GFp, 192,
11.227 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
11.228 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
11.229 - "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
11.230 - "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
11.231 - "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
11.232 - "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", 1
11.233 -};
11.234 -
11.235 -static const ECCurveParams ecCurve_X9_62_PRIME_192V3 = {
11.236 - "X9.62 P-192V3", ECField_GFp, 192,
11.237 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
11.238 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
11.239 - "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
11.240 - "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
11.241 - "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
11.242 - "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", 1
11.243 -};
11.244 -
11.245 -static const ECCurveParams ecCurve_X9_62_PRIME_239V1 = {
11.246 - "X9.62 P-239V1", ECField_GFp, 239,
11.247 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
11.248 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
11.249 - "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
11.250 - "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
11.251 - "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
11.252 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", 1
11.253 -};
11.254 -
11.255 -static const ECCurveParams ecCurve_X9_62_PRIME_239V2 = {
11.256 - "X9.62 P-239V2", ECField_GFp, 239,
11.257 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
11.258 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
11.259 - "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
11.260 - "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
11.261 - "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
11.262 - "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", 1
11.263 -};
11.264 -
11.265 -static const ECCurveParams ecCurve_X9_62_PRIME_239V3 = {
11.266 - "X9.62 P-239V3", ECField_GFp, 239,
11.267 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
11.268 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
11.269 - "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
11.270 - "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
11.271 - "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
11.272 - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", 1
11.273 -};
11.274 -
11.275 -/* ANSI X9.62 binary curves */
11.276 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V1 = {
11.277 - "X9.62 C2-PNB163V1", ECField_GF2m, 163,
11.278 - "080000000000000000000000000000000000000107",
11.279 - "072546B5435234A422E0789675F432C89435DE5242",
11.280 - "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
11.281 - "07AF69989546103D79329FCC3D74880F33BBE803CB",
11.282 - "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
11.283 - "0400000000000000000001E60FC8821CC74DAEAFC1", 2
11.284 -};
11.285 -
11.286 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V2 = {
11.287 - "X9.62 C2-PNB163V2", ECField_GF2m, 163,
11.288 - "080000000000000000000000000000000000000107",
11.289 - "0108B39E77C4B108BED981ED0E890E117C511CF072",
11.290 - "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
11.291 - "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
11.292 - "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
11.293 - "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2
11.294 -};
11.295 -
11.296 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V3 = {
11.297 - "X9.62 C2-PNB163V3", ECField_GF2m, 163,
11.298 - "080000000000000000000000000000000000000107",
11.299 - "07A526C63D3E25A256A007699F5447E32AE456B50E",
11.300 - "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
11.301 - "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
11.302 - "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
11.303 - "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2
11.304 -};
11.305 -
11.306 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB176V1 = {
11.307 - "X9.62 C2-PNB176V1", ECField_GF2m, 176,
11.308 - "0100000000000000000000000000000000080000000007",
11.309 - "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
11.310 - "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
11.311 - "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
11.312 - "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
11.313 - "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E
11.314 -};
11.315 -
11.316 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V1 = {
11.317 - "X9.62 C2-TNB191V1", ECField_GF2m, 191,
11.318 - "800000000000000000000000000000000000000000000201",
11.319 - "2866537B676752636A68F56554E12640276B649EF7526267",
11.320 - "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
11.321 - "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
11.322 - "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
11.323 - "40000000000000000000000004A20E90C39067C893BBB9A5", 2
11.324 -};
11.325 -
11.326 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V2 = {
11.327 - "X9.62 C2-TNB191V2", ECField_GF2m, 191,
11.328 - "800000000000000000000000000000000000000000000201",
11.329 - "401028774D7777C7B7666D1366EA432071274F89FF01E718",
11.330 - "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
11.331 - "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
11.332 - "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
11.333 - "20000000000000000000000050508CB89F652824E06B8173", 4
11.334 -};
11.335 -
11.336 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V3 = {
11.337 - "X9.62 C2-TNB191V3", ECField_GF2m, 191,
11.338 - "800000000000000000000000000000000000000000000201",
11.339 - "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
11.340 - "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
11.341 - "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
11.342 - "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
11.343 - "155555555555555555555555610C0B196812BFB6288A3EA3", 6
11.344 -};
11.345 -
11.346 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB208W1 = {
11.347 - "X9.62 C2-PNB208W1", ECField_GF2m, 208,
11.348 - "010000000000000000000000000000000800000000000000000007",
11.349 - "0000000000000000000000000000000000000000000000000000",
11.350 - "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
11.351 - "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
11.352 - "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
11.353 - "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48
11.354 -};
11.355 -
11.356 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V1 = {
11.357 - "X9.62 C2-TNB239V1", ECField_GF2m, 239,
11.358 - "800000000000000000000000000000000000000000000000001000000001",
11.359 - "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
11.360 - "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
11.361 - "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
11.362 - "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
11.363 - "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4
11.364 -};
11.365 -
11.366 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V2 = {
11.367 - "X9.62 C2-TNB239V2", ECField_GF2m, 239,
11.368 - "800000000000000000000000000000000000000000000000001000000001",
11.369 - "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
11.370 - "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
11.371 - "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
11.372 - "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
11.373 - "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6
11.374 -};
11.375 -
11.376 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V3 = {
11.377 - "X9.62 C2-TNB239V3", ECField_GF2m, 239,
11.378 - "800000000000000000000000000000000000000000000000001000000001",
11.379 - "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
11.380 - "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
11.381 - "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
11.382 - "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
11.383 - "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA
11.384 -};
11.385 -
11.386 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB272W1 = {
11.387 - "X9.62 C2-PNB272W1", ECField_GF2m, 272,
11.388 - "010000000000000000000000000000000000000000000000000000010000000000000B",
11.389 - "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
11.390 - "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
11.391 - "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
11.392 - "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
11.393 - "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
11.394 - 0xFF06
11.395 -};
11.396 -
11.397 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB304W1 = {
11.398 - "X9.62 C2-PNB304W1", ECField_GF2m, 304,
11.399 - "010000000000000000000000000000000000000000000000000000000000000000000000000807",
11.400 - "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
11.401 - "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
11.402 - "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
11.403 - "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
11.404 - "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 0xFE2E
11.405 -};
11.406 -
11.407 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB359V1 = {
11.408 - "X9.62 C2-TNB359V1", ECField_GF2m, 359,
11.409 - "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
11.410 - "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
11.411 - "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
11.412 - "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
11.413 - "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
11.414 - "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 0x4C
11.415 -};
11.416 -
11.417 -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB368W1 = {
11.418 - "X9.62 C2-PNB368W1", ECField_GF2m, 368,
11.419 - "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
11.420 - "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
11.421 - "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
11.422 - "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
11.423 - "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
11.424 - "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 0xFF70
11.425 -};
11.426 -
11.427 -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB431R1 = {
11.428 - "X9.62 C2-TNB431R1", ECField_GF2m, 431,
11.429 - "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
11.430 - "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
11.431 - "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
11.432 - "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
11.433 - "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
11.434 - "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760
11.435 -};
11.436 -
11.437 -/* SEC2 prime curves */
11.438 -static const ECCurveParams ecCurve_SECG_PRIME_112R1 = {
11.439 - "SECP-112R1", ECField_GFp, 112,
11.440 - "DB7C2ABF62E35E668076BEAD208B",
11.441 - "DB7C2ABF62E35E668076BEAD2088",
11.442 - "659EF8BA043916EEDE8911702B22",
11.443 - "09487239995A5EE76B55F9C2F098",
11.444 - "A89CE5AF8724C0A23E0E0FF77500",
11.445 - "DB7C2ABF62E35E7628DFAC6561C5", 1
11.446 -};
11.447 -
11.448 -static const ECCurveParams ecCurve_SECG_PRIME_112R2 = {
11.449 - "SECP-112R2", ECField_GFp, 112,
11.450 - "DB7C2ABF62E35E668076BEAD208B",
11.451 - "6127C24C05F38A0AAAF65C0EF02C",
11.452 - "51DEF1815DB5ED74FCC34C85D709",
11.453 - "4BA30AB5E892B4E1649DD0928643",
11.454 - "adcd46f5882e3747def36e956e97",
11.455 - "36DF0AAFD8B8D7597CA10520D04B", 4
11.456 -};
11.457 -
11.458 -static const ECCurveParams ecCurve_SECG_PRIME_128R1 = {
11.459 - "SECP-128R1", ECField_GFp, 128,
11.460 - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
11.461 - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
11.462 - "E87579C11079F43DD824993C2CEE5ED3",
11.463 - "161FF7528B899B2D0C28607CA52C5B86",
11.464 - "CF5AC8395BAFEB13C02DA292DDED7A83",
11.465 - "FFFFFFFE0000000075A30D1B9038A115", 1
11.466 -};
11.467 -
11.468 -static const ECCurveParams ecCurve_SECG_PRIME_128R2 = {
11.469 - "SECP-128R2", ECField_GFp, 128,
11.470 - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
11.471 - "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
11.472 - "5EEEFCA380D02919DC2C6558BB6D8A5D",
11.473 - "7B6AA5D85E572983E6FB32A7CDEBC140",
11.474 - "27B6916A894D3AEE7106FE805FC34B44",
11.475 - "3FFFFFFF7FFFFFFFBE0024720613B5A3", 4
11.476 -};
11.477 -
11.478 -static const ECCurveParams ecCurve_SECG_PRIME_160K1 = {
11.479 - "SECP-160K1", ECField_GFp, 160,
11.480 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
11.481 - "0000000000000000000000000000000000000000",
11.482 - "0000000000000000000000000000000000000007",
11.483 - "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
11.484 - "938CF935318FDCED6BC28286531733C3F03C4FEE",
11.485 - "0100000000000000000001B8FA16DFAB9ACA16B6B3", 1
11.486 -};
11.487 -
11.488 -static const ECCurveParams ecCurve_SECG_PRIME_160R1 = {
11.489 - "SECP-160R1", ECField_GFp, 160,
11.490 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
11.491 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
11.492 - "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
11.493 - "4A96B5688EF573284664698968C38BB913CBFC82",
11.494 - "23A628553168947D59DCC912042351377AC5FB32",
11.495 - "0100000000000000000001F4C8F927AED3CA752257", 1
11.496 -};
11.497 -
11.498 -static const ECCurveParams ecCurve_SECG_PRIME_160R2 = {
11.499 - "SECP-160R2", ECField_GFp, 160,
11.500 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
11.501 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
11.502 - "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
11.503 - "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
11.504 - "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
11.505 - "0100000000000000000000351EE786A818F3A1A16B", 1
11.506 -};
11.507 -
11.508 -static const ECCurveParams ecCurve_SECG_PRIME_192K1 = {
11.509 - "SECP-192K1", ECField_GFp, 192,
11.510 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
11.511 - "000000000000000000000000000000000000000000000000",
11.512 - "000000000000000000000000000000000000000000000003",
11.513 - "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
11.514 - "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
11.515 - "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 1
11.516 -};
11.517 -
11.518 -static const ECCurveParams ecCurve_SECG_PRIME_224K1 = {
11.519 - "SECP-224K1", ECField_GFp, 224,
11.520 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
11.521 - "00000000000000000000000000000000000000000000000000000000",
11.522 - "00000000000000000000000000000000000000000000000000000005",
11.523 - "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
11.524 - "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
11.525 - "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 1
11.526 -};
11.527 -
11.528 -static const ECCurveParams ecCurve_SECG_PRIME_256K1 = {
11.529 - "SECP-256K1", ECField_GFp, 256,
11.530 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
11.531 - "0000000000000000000000000000000000000000000000000000000000000000",
11.532 - "0000000000000000000000000000000000000000000000000000000000000007",
11.533 - "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
11.534 - "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
11.535 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 1
11.536 -};
11.537 -
11.538 -/* SEC2 binary curves */
11.539 -static const ECCurveParams ecCurve_SECG_CHAR2_113R1 = {
11.540 - "SECT-113R1", ECField_GF2m, 113,
11.541 - "020000000000000000000000000201",
11.542 - "003088250CA6E7C7FE649CE85820F7",
11.543 - "00E8BEE4D3E2260744188BE0E9C723",
11.544 - "009D73616F35F4AB1407D73562C10F",
11.545 - "00A52830277958EE84D1315ED31886",
11.546 - "0100000000000000D9CCEC8A39E56F", 2
11.547 -};
11.548 -
11.549 -static const ECCurveParams ecCurve_SECG_CHAR2_113R2 = {
11.550 - "SECT-113R2", ECField_GF2m, 113,
11.551 - "020000000000000000000000000201",
11.552 - "00689918DBEC7E5A0DD6DFC0AA55C7",
11.553 - "0095E9A9EC9B297BD4BF36E059184F",
11.554 - "01A57A6A7B26CA5EF52FCDB8164797",
11.555 - "00B3ADC94ED1FE674C06E695BABA1D",
11.556 - "010000000000000108789B2496AF93", 2
11.557 -};
11.558 -
11.559 -static const ECCurveParams ecCurve_SECG_CHAR2_131R1 = {
11.560 - "SECT-131R1", ECField_GF2m, 131,
11.561 - "080000000000000000000000000000010D",
11.562 - "07A11B09A76B562144418FF3FF8C2570B8",
11.563 - "0217C05610884B63B9C6C7291678F9D341",
11.564 - "0081BAF91FDF9833C40F9C181343638399",
11.565 - "078C6E7EA38C001F73C8134B1B4EF9E150",
11.566 - "0400000000000000023123953A9464B54D", 2
11.567 -};
11.568 -
11.569 -static const ECCurveParams ecCurve_SECG_CHAR2_131R2 = {
11.570 - "SECT-131R2", ECField_GF2m, 131,
11.571 - "080000000000000000000000000000010D",
11.572 - "03E5A88919D7CAFCBF415F07C2176573B2",
11.573 - "04B8266A46C55657AC734CE38F018F2192",
11.574 - "0356DCD8F2F95031AD652D23951BB366A8",
11.575 - "0648F06D867940A5366D9E265DE9EB240F",
11.576 - "0400000000000000016954A233049BA98F", 2
11.577 -};
11.578 -
11.579 -static const ECCurveParams ecCurve_SECG_CHAR2_163R1 = {
11.580 - "SECT-163R1", ECField_GF2m, 163,
11.581 - "0800000000000000000000000000000000000000C9",
11.582 - "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
11.583 - "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
11.584 - "0369979697AB43897789566789567F787A7876A654",
11.585 - "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
11.586 - "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2
11.587 -};
11.588 -
11.589 -static const ECCurveParams ecCurve_SECG_CHAR2_193R1 = {
11.590 - "SECT-193R1", ECField_GF2m, 193,
11.591 - "02000000000000000000000000000000000000000000008001",
11.592 - "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
11.593 - "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
11.594 - "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
11.595 - "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
11.596 - "01000000000000000000000000C7F34A778F443ACC920EBA49", 2
11.597 -};
11.598 -
11.599 -static const ECCurveParams ecCurve_SECG_CHAR2_193R2 = {
11.600 - "SECT-193R2", ECField_GF2m, 193,
11.601 - "02000000000000000000000000000000000000000000008001",
11.602 - "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
11.603 - "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
11.604 - "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
11.605 - "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
11.606 - "010000000000000000000000015AAB561B005413CCD4EE99D5", 2
11.607 -};
11.608 -
11.609 -static const ECCurveParams ecCurve_SECG_CHAR2_239K1 = {
11.610 - "SECT-239K1", ECField_GF2m, 239,
11.611 - "800000000000000000004000000000000000000000000000000000000001",
11.612 - "000000000000000000000000000000000000000000000000000000000000",
11.613 - "000000000000000000000000000000000000000000000000000000000001",
11.614 - "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
11.615 - "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
11.616 - "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4
11.617 -};
11.618 -
11.619 -/* WTLS curves */
11.620 -static const ECCurveParams ecCurve_WTLS_1 = {
11.621 - "WTLS-1", ECField_GF2m, 113,
11.622 - "020000000000000000000000000201",
11.623 - "000000000000000000000000000001",
11.624 - "000000000000000000000000000001",
11.625 - "01667979A40BA497E5D5C270780617",
11.626 - "00F44B4AF1ECC2630E08785CEBCC15",
11.627 - "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2
11.628 -};
11.629 -
11.630 -static const ECCurveParams ecCurve_WTLS_8 = {
11.631 - "WTLS-8", ECField_GFp, 112,
11.632 - "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
11.633 - "0000000000000000000000000000",
11.634 - "0000000000000000000000000003",
11.635 - "0000000000000000000000000001",
11.636 - "0000000000000000000000000002",
11.637 - "0100000000000001ECEA551AD837E9", 1
11.638 -};
11.639 -
11.640 -static const ECCurveParams ecCurve_WTLS_9 = {
11.641 - "WTLS-9", ECField_GFp, 160,
11.642 - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
11.643 - "0000000000000000000000000000000000000000",
11.644 - "0000000000000000000000000000000000000003",
11.645 - "0000000000000000000000000000000000000001",
11.646 - "0000000000000000000000000000000000000002",
11.647 - "0100000000000000000001CDC98AE0E2DE574ABF33", 1
11.648 -};
11.649 -
11.650 -/* mapping between ECCurveName enum and pointers to ECCurveParams */
11.651 -static const ECCurveParams *ecCurve_map[] = {
11.652 - NULL, /* ECCurve_noName */
11.653 - &ecCurve_NIST_P192, /* ECCurve_NIST_P192 */
11.654 - &ecCurve_NIST_P224, /* ECCurve_NIST_P224 */
11.655 - &ecCurve_NIST_P256, /* ECCurve_NIST_P256 */
11.656 - &ecCurve_NIST_P384, /* ECCurve_NIST_P384 */
11.657 - &ecCurve_NIST_P521, /* ECCurve_NIST_P521 */
11.658 - &ecCurve_NIST_K163, /* ECCurve_NIST_K163 */
11.659 - &ecCurve_NIST_B163, /* ECCurve_NIST_B163 */
11.660 - &ecCurve_NIST_K233, /* ECCurve_NIST_K233 */
11.661 - &ecCurve_NIST_B233, /* ECCurve_NIST_B233 */
11.662 - &ecCurve_NIST_K283, /* ECCurve_NIST_K283 */
11.663 - &ecCurve_NIST_B283, /* ECCurve_NIST_B283 */
11.664 - &ecCurve_NIST_K409, /* ECCurve_NIST_K409 */
11.665 - &ecCurve_NIST_B409, /* ECCurve_NIST_B409 */
11.666 - &ecCurve_NIST_K571, /* ECCurve_NIST_K571 */
11.667 - &ecCurve_NIST_B571, /* ECCurve_NIST_B571 */
11.668 - &ecCurve_X9_62_PRIME_192V2, /* ECCurve_X9_62_PRIME_192V2 */
11.669 - &ecCurve_X9_62_PRIME_192V3, /* ECCurve_X9_62_PRIME_192V3 */
11.670 - &ecCurve_X9_62_PRIME_239V1, /* ECCurve_X9_62_PRIME_239V1 */
11.671 - &ecCurve_X9_62_PRIME_239V2, /* ECCurve_X9_62_PRIME_239V2 */
11.672 - &ecCurve_X9_62_PRIME_239V3, /* ECCurve_X9_62_PRIME_239V3 */
11.673 - &ecCurve_X9_62_CHAR2_PNB163V1, /* ECCurve_X9_62_CHAR2_PNB163V1 */
11.674 - &ecCurve_X9_62_CHAR2_PNB163V2, /* ECCurve_X9_62_CHAR2_PNB163V2 */
11.675 - &ecCurve_X9_62_CHAR2_PNB163V3, /* ECCurve_X9_62_CHAR2_PNB163V3 */
11.676 - &ecCurve_X9_62_CHAR2_PNB176V1, /* ECCurve_X9_62_CHAR2_PNB176V1 */
11.677 - &ecCurve_X9_62_CHAR2_TNB191V1, /* ECCurve_X9_62_CHAR2_TNB191V1 */
11.678 - &ecCurve_X9_62_CHAR2_TNB191V2, /* ECCurve_X9_62_CHAR2_TNB191V2 */
11.679 - &ecCurve_X9_62_CHAR2_TNB191V3, /* ECCurve_X9_62_CHAR2_TNB191V3 */
11.680 - &ecCurve_X9_62_CHAR2_PNB208W1, /* ECCurve_X9_62_CHAR2_PNB208W1 */
11.681 - &ecCurve_X9_62_CHAR2_TNB239V1, /* ECCurve_X9_62_CHAR2_TNB239V1 */
11.682 - &ecCurve_X9_62_CHAR2_TNB239V2, /* ECCurve_X9_62_CHAR2_TNB239V2 */
11.683 - &ecCurve_X9_62_CHAR2_TNB239V3, /* ECCurve_X9_62_CHAR2_TNB239V3 */
11.684 - &ecCurve_X9_62_CHAR2_PNB272W1, /* ECCurve_X9_62_CHAR2_PNB272W1 */
11.685 - &ecCurve_X9_62_CHAR2_PNB304W1, /* ECCurve_X9_62_CHAR2_PNB304W1 */
11.686 - &ecCurve_X9_62_CHAR2_TNB359V1, /* ECCurve_X9_62_CHAR2_TNB359V1 */
11.687 - &ecCurve_X9_62_CHAR2_PNB368W1, /* ECCurve_X9_62_CHAR2_PNB368W1 */
11.688 - &ecCurve_X9_62_CHAR2_TNB431R1, /* ECCurve_X9_62_CHAR2_TNB431R1 */
11.689 - &ecCurve_SECG_PRIME_112R1, /* ECCurve_SECG_PRIME_112R1 */
11.690 - &ecCurve_SECG_PRIME_112R2, /* ECCurve_SECG_PRIME_112R2 */
11.691 - &ecCurve_SECG_PRIME_128R1, /* ECCurve_SECG_PRIME_128R1 */
11.692 - &ecCurve_SECG_PRIME_128R2, /* ECCurve_SECG_PRIME_128R2 */
11.693 - &ecCurve_SECG_PRIME_160K1, /* ECCurve_SECG_PRIME_160K1 */
11.694 - &ecCurve_SECG_PRIME_160R1, /* ECCurve_SECG_PRIME_160R1 */
11.695 - &ecCurve_SECG_PRIME_160R2, /* ECCurve_SECG_PRIME_160R2 */
11.696 - &ecCurve_SECG_PRIME_192K1, /* ECCurve_SECG_PRIME_192K1 */
11.697 - &ecCurve_SECG_PRIME_224K1, /* ECCurve_SECG_PRIME_224K1 */
11.698 - &ecCurve_SECG_PRIME_256K1, /* ECCurve_SECG_PRIME_256K1 */
11.699 - &ecCurve_SECG_CHAR2_113R1, /* ECCurve_SECG_CHAR2_113R1 */
11.700 - &ecCurve_SECG_CHAR2_113R2, /* ECCurve_SECG_CHAR2_113R2 */
11.701 - &ecCurve_SECG_CHAR2_131R1, /* ECCurve_SECG_CHAR2_131R1 */
11.702 - &ecCurve_SECG_CHAR2_131R2, /* ECCurve_SECG_CHAR2_131R2 */
11.703 - &ecCurve_SECG_CHAR2_163R1, /* ECCurve_SECG_CHAR2_163R1 */
11.704 - &ecCurve_SECG_CHAR2_193R1, /* ECCurve_SECG_CHAR2_193R1 */
11.705 - &ecCurve_SECG_CHAR2_193R2, /* ECCurve_SECG_CHAR2_193R2 */
11.706 - &ecCurve_SECG_CHAR2_239K1, /* ECCurve_SECG_CHAR2_239K1 */
11.707 - &ecCurve_WTLS_1, /* ECCurve_WTLS_1 */
11.708 - &ecCurve_WTLS_8, /* ECCurve_WTLS_8 */
11.709 - &ecCurve_WTLS_9, /* ECCurve_WTLS_9 */
11.710 - NULL /* ECCurve_pastLastCurve */
11.711 -};
11.712 -
11.713 -#endif /* _ECL_CURVE_H */
12.1 --- a/src/share/native/sun/security/ec/ecl-exp.h Tue Oct 13 15:25:58 2009 -0700
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,216 +0,0 @@
12.4 -/* *********************************************************************
12.5 - *
12.6 - * Sun elects to have this file available under and governed by the
12.7 - * Mozilla Public License Version 1.1 ("MPL") (see
12.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
12.9 - * of doubt and subject to the following, Sun also elects to allow
12.10 - * licensees to use this file under the MPL, the GNU General Public
12.11 - * License version 2 only or the Lesser General Public License version
12.12 - * 2.1 only. Any references to the "GNU General Public License version 2
12.13 - * or later" or "GPL" in the following shall be construed to mean the
12.14 - * GNU General Public License version 2 only. Any references to the "GNU
12.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
12.16 - * following shall be construed to mean the GNU Lesser General Public
12.17 - * License version 2.1 only. However, the following notice accompanied
12.18 - * the original version of this file:
12.19 - *
12.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
12.21 - *
12.22 - * The contents of this file are subject to the Mozilla Public License Version
12.23 - * 1.1 (the "License"); you may not use this file except in compliance with
12.24 - * the License. You may obtain a copy of the License at
12.25 - * http://www.mozilla.org/MPL/
12.26 - *
12.27 - * Software distributed under the License is distributed on an "AS IS" basis,
12.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12.29 - * for the specific language governing rights and limitations under the
12.30 - * License.
12.31 - *
12.32 - * The Original Code is the elliptic curve math library.
12.33 - *
12.34 - * The Initial Developer of the Original Code is
12.35 - * Sun Microsystems, Inc.
12.36 - * Portions created by the Initial Developer are Copyright (C) 2003
12.37 - * the Initial Developer. All Rights Reserved.
12.38 - *
12.39 - * Contributor(s):
12.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
12.41 - *
12.42 - * Alternatively, the contents of this file may be used under the terms of
12.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
12.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
12.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
12.46 - * of those above. If you wish to allow use of your version of this file only
12.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
12.48 - * use your version of this file under the terms of the MPL, indicate your
12.49 - * decision by deleting the provisions above and replace them with the notice
12.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
12.51 - * the provisions above, a recipient may use your version of this file under
12.52 - * the terms of any one of the MPL, the GPL or the LGPL.
12.53 - *
12.54 - *********************************************************************** */
12.55 -/*
12.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
12.57 - * Use is subject to license terms.
12.58 - */
12.59 -
12.60 -#ifndef _ECL_EXP_H
12.61 -#define _ECL_EXP_H
12.62 -
12.63 -#pragma ident "%Z%%M% %I% %E% SMI"
12.64 -
12.65 -/* Curve field type */
12.66 -typedef enum {
12.67 - ECField_GFp,
12.68 - ECField_GF2m
12.69 -} ECField;
12.70 -
12.71 -/* Hexadecimal encoding of curve parameters */
12.72 -struct ECCurveParamsStr {
12.73 - char *text;
12.74 - ECField field;
12.75 - unsigned int size;
12.76 - char *irr;
12.77 - char *curvea;
12.78 - char *curveb;
12.79 - char *genx;
12.80 - char *geny;
12.81 - char *order;
12.82 - int cofactor;
12.83 -};
12.84 -typedef struct ECCurveParamsStr ECCurveParams;
12.85 -
12.86 -/* Named curve parameters */
12.87 -typedef enum {
12.88 -
12.89 - ECCurve_noName = 0,
12.90 -
12.91 - /* NIST prime curves */
12.92 - ECCurve_NIST_P192,
12.93 - ECCurve_NIST_P224,
12.94 - ECCurve_NIST_P256,
12.95 - ECCurve_NIST_P384,
12.96 - ECCurve_NIST_P521,
12.97 -
12.98 - /* NIST binary curves */
12.99 - ECCurve_NIST_K163,
12.100 - ECCurve_NIST_B163,
12.101 - ECCurve_NIST_K233,
12.102 - ECCurve_NIST_B233,
12.103 - ECCurve_NIST_K283,
12.104 - ECCurve_NIST_B283,
12.105 - ECCurve_NIST_K409,
12.106 - ECCurve_NIST_B409,
12.107 - ECCurve_NIST_K571,
12.108 - ECCurve_NIST_B571,
12.109 -
12.110 - /* ANSI X9.62 prime curves */
12.111 - /* ECCurve_X9_62_PRIME_192V1 == ECCurve_NIST_P192 */
12.112 - ECCurve_X9_62_PRIME_192V2,
12.113 - ECCurve_X9_62_PRIME_192V3,
12.114 - ECCurve_X9_62_PRIME_239V1,
12.115 - ECCurve_X9_62_PRIME_239V2,
12.116 - ECCurve_X9_62_PRIME_239V3,
12.117 - /* ECCurve_X9_62_PRIME_256V1 == ECCurve_NIST_P256 */
12.118 -
12.119 - /* ANSI X9.62 binary curves */
12.120 - ECCurve_X9_62_CHAR2_PNB163V1,
12.121 - ECCurve_X9_62_CHAR2_PNB163V2,
12.122 - ECCurve_X9_62_CHAR2_PNB163V3,
12.123 - ECCurve_X9_62_CHAR2_PNB176V1,
12.124 - ECCurve_X9_62_CHAR2_TNB191V1,
12.125 - ECCurve_X9_62_CHAR2_TNB191V2,
12.126 - ECCurve_X9_62_CHAR2_TNB191V3,
12.127 - ECCurve_X9_62_CHAR2_PNB208W1,
12.128 - ECCurve_X9_62_CHAR2_TNB239V1,
12.129 - ECCurve_X9_62_CHAR2_TNB239V2,
12.130 - ECCurve_X9_62_CHAR2_TNB239V3,
12.131 - ECCurve_X9_62_CHAR2_PNB272W1,
12.132 - ECCurve_X9_62_CHAR2_PNB304W1,
12.133 - ECCurve_X9_62_CHAR2_TNB359V1,
12.134 - ECCurve_X9_62_CHAR2_PNB368W1,
12.135 - ECCurve_X9_62_CHAR2_TNB431R1,
12.136 -
12.137 - /* SEC2 prime curves */
12.138 - ECCurve_SECG_PRIME_112R1,
12.139 - ECCurve_SECG_PRIME_112R2,
12.140 - ECCurve_SECG_PRIME_128R1,
12.141 - ECCurve_SECG_PRIME_128R2,
12.142 - ECCurve_SECG_PRIME_160K1,
12.143 - ECCurve_SECG_PRIME_160R1,
12.144 - ECCurve_SECG_PRIME_160R2,
12.145 - ECCurve_SECG_PRIME_192K1,
12.146 - /* ECCurve_SECG_PRIME_192R1 == ECCurve_NIST_P192 */
12.147 - ECCurve_SECG_PRIME_224K1,
12.148 - /* ECCurve_SECG_PRIME_224R1 == ECCurve_NIST_P224 */
12.149 - ECCurve_SECG_PRIME_256K1,
12.150 - /* ECCurve_SECG_PRIME_256R1 == ECCurve_NIST_P256 */
12.151 - /* ECCurve_SECG_PRIME_384R1 == ECCurve_NIST_P384 */
12.152 - /* ECCurve_SECG_PRIME_521R1 == ECCurve_NIST_P521 */
12.153 -
12.154 - /* SEC2 binary curves */
12.155 - ECCurve_SECG_CHAR2_113R1,
12.156 - ECCurve_SECG_CHAR2_113R2,
12.157 - ECCurve_SECG_CHAR2_131R1,
12.158 - ECCurve_SECG_CHAR2_131R2,
12.159 - /* ECCurve_SECG_CHAR2_163K1 == ECCurve_NIST_K163 */
12.160 - ECCurve_SECG_CHAR2_163R1,
12.161 - /* ECCurve_SECG_CHAR2_163R2 == ECCurve_NIST_B163 */
12.162 - ECCurve_SECG_CHAR2_193R1,
12.163 - ECCurve_SECG_CHAR2_193R2,
12.164 - /* ECCurve_SECG_CHAR2_233K1 == ECCurve_NIST_K233 */
12.165 - /* ECCurve_SECG_CHAR2_233R1 == ECCurve_NIST_B233 */
12.166 - ECCurve_SECG_CHAR2_239K1,
12.167 - /* ECCurve_SECG_CHAR2_283K1 == ECCurve_NIST_K283 */
12.168 - /* ECCurve_SECG_CHAR2_283R1 == ECCurve_NIST_B283 */
12.169 - /* ECCurve_SECG_CHAR2_409K1 == ECCurve_NIST_K409 */
12.170 - /* ECCurve_SECG_CHAR2_409R1 == ECCurve_NIST_B409 */
12.171 - /* ECCurve_SECG_CHAR2_571K1 == ECCurve_NIST_K571 */
12.172 - /* ECCurve_SECG_CHAR2_571R1 == ECCurve_NIST_B571 */
12.173 -
12.174 - /* WTLS curves */
12.175 - ECCurve_WTLS_1,
12.176 - /* there is no WTLS 2 curve */
12.177 - /* ECCurve_WTLS_3 == ECCurve_NIST_K163 */
12.178 - /* ECCurve_WTLS_4 == ECCurve_SECG_CHAR2_113R1 */
12.179 - /* ECCurve_WTLS_5 == ECCurve_X9_62_CHAR2_PNB163V1 */
12.180 - /* ECCurve_WTLS_6 == ECCurve_SECG_PRIME_112R1 */
12.181 - /* ECCurve_WTLS_7 == ECCurve_SECG_PRIME_160R1 */
12.182 - ECCurve_WTLS_8,
12.183 - ECCurve_WTLS_9,
12.184 - /* ECCurve_WTLS_10 == ECCurve_NIST_K233 */
12.185 - /* ECCurve_WTLS_11 == ECCurve_NIST_B233 */
12.186 - /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */
12.187 -
12.188 - ECCurve_pastLastCurve
12.189 -} ECCurveName;
12.190 -
12.191 -/* Aliased named curves */
12.192 -
12.193 -#define ECCurve_X9_62_PRIME_192V1 ECCurve_NIST_P192
12.194 -#define ECCurve_X9_62_PRIME_256V1 ECCurve_NIST_P256
12.195 -#define ECCurve_SECG_PRIME_192R1 ECCurve_NIST_P192
12.196 -#define ECCurve_SECG_PRIME_224R1 ECCurve_NIST_P224
12.197 -#define ECCurve_SECG_PRIME_256R1 ECCurve_NIST_P256
12.198 -#define ECCurve_SECG_PRIME_384R1 ECCurve_NIST_P384
12.199 -#define ECCurve_SECG_PRIME_521R1 ECCurve_NIST_P521
12.200 -#define ECCurve_SECG_CHAR2_163K1 ECCurve_NIST_K163
12.201 -#define ECCurve_SECG_CHAR2_163R2 ECCurve_NIST_B163
12.202 -#define ECCurve_SECG_CHAR2_233K1 ECCurve_NIST_K233
12.203 -#define ECCurve_SECG_CHAR2_233R1 ECCurve_NIST_B233
12.204 -#define ECCurve_SECG_CHAR2_283K1 ECCurve_NIST_K283
12.205 -#define ECCurve_SECG_CHAR2_283R1 ECCurve_NIST_B283
12.206 -#define ECCurve_SECG_CHAR2_409K1 ECCurve_NIST_K409
12.207 -#define ECCurve_SECG_CHAR2_409R1 ECCurve_NIST_B409
12.208 -#define ECCurve_SECG_CHAR2_571K1 ECCurve_NIST_K571
12.209 -#define ECCurve_SECG_CHAR2_571R1 ECCurve_NIST_B571
12.210 -#define ECCurve_WTLS_3 ECCurve_NIST_K163
12.211 -#define ECCurve_WTLS_4 ECCurve_SECG_CHAR2_113R1
12.212 -#define ECCurve_WTLS_5 ECCurve_X9_62_CHAR2_PNB163V1
12.213 -#define ECCurve_WTLS_6 ECCurve_SECG_PRIME_112R1
12.214 -#define ECCurve_WTLS_7 ECCurve_SECG_PRIME_160R1
12.215 -#define ECCurve_WTLS_10 ECCurve_NIST_K233
12.216 -#define ECCurve_WTLS_11 ECCurve_NIST_B233
12.217 -#define ECCurve_WTLS_12 ECCurve_NIST_P224
12.218 -
12.219 -#endif /* _ECL_EXP_H */
13.1 --- a/src/share/native/sun/security/ec/ecl-priv.h Tue Oct 13 15:25:58 2009 -0700
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,304 +0,0 @@
13.4 -/* *********************************************************************
13.5 - *
13.6 - * Sun elects to have this file available under and governed by the
13.7 - * Mozilla Public License Version 1.1 ("MPL") (see
13.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
13.9 - * of doubt and subject to the following, Sun also elects to allow
13.10 - * licensees to use this file under the MPL, the GNU General Public
13.11 - * License version 2 only or the Lesser General Public License version
13.12 - * 2.1 only. Any references to the "GNU General Public License version 2
13.13 - * or later" or "GPL" in the following shall be construed to mean the
13.14 - * GNU General Public License version 2 only. Any references to the "GNU
13.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
13.16 - * following shall be construed to mean the GNU Lesser General Public
13.17 - * License version 2.1 only. However, the following notice accompanied
13.18 - * the original version of this file:
13.19 - *
13.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
13.21 - *
13.22 - * The contents of this file are subject to the Mozilla Public License Version
13.23 - * 1.1 (the "License"); you may not use this file except in compliance with
13.24 - * the License. You may obtain a copy of the License at
13.25 - * http://www.mozilla.org/MPL/
13.26 - *
13.27 - * Software distributed under the License is distributed on an "AS IS" basis,
13.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13.29 - * for the specific language governing rights and limitations under the
13.30 - * License.
13.31 - *
13.32 - * The Original Code is the elliptic curve math library.
13.33 - *
13.34 - * The Initial Developer of the Original Code is
13.35 - * Sun Microsystems, Inc.
13.36 - * Portions created by the Initial Developer are Copyright (C) 2003
13.37 - * the Initial Developer. All Rights Reserved.
13.38 - *
13.39 - * Contributor(s):
13.40 - * Stephen Fung <fungstep@hotmail.com> and
13.41 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
13.42 - *
13.43 - * Alternatively, the contents of this file may be used under the terms of
13.44 - * either the GNU General Public License Version 2 or later (the "GPL"), or
13.45 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
13.46 - * in which case the provisions of the GPL or the LGPL are applicable instead
13.47 - * of those above. If you wish to allow use of your version of this file only
13.48 - * under the terms of either the GPL or the LGPL, and not to allow others to
13.49 - * use your version of this file under the terms of the MPL, indicate your
13.50 - * decision by deleting the provisions above and replace them with the notice
13.51 - * and other provisions required by the GPL or the LGPL. If you do not delete
13.52 - * the provisions above, a recipient may use your version of this file under
13.53 - * the terms of any one of the MPL, the GPL or the LGPL.
13.54 - *
13.55 - *********************************************************************** */
13.56 -/*
13.57 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
13.58 - * Use is subject to license terms.
13.59 - */
13.60 -
13.61 -#ifndef _ECL_PRIV_H
13.62 -#define _ECL_PRIV_H
13.63 -
13.64 -#pragma ident "%Z%%M% %I% %E% SMI"
13.65 -
13.66 -#include "ecl.h"
13.67 -#include "mpi.h"
13.68 -#include "mplogic.h"
13.69 -
13.70 -/* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
13.71 -/* the following needs to go away... */
13.72 -#if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT)
13.73 -#define ECL_SIXTY_FOUR_BIT
13.74 -#else
13.75 -#define ECL_THIRTY_TWO_BIT
13.76 -#endif
13.77 -
13.78 -#define ECL_CURVE_DIGITS(curve_size_in_bits) \
13.79 - (((curve_size_in_bits)+(sizeof(mp_digit)*8-1))/(sizeof(mp_digit)*8))
13.80 -#define ECL_BITS (sizeof(mp_digit)*8)
13.81 -#define ECL_MAX_FIELD_SIZE_DIGITS (80/sizeof(mp_digit))
13.82 -
13.83 -/* Gets the i'th bit in the binary representation of a. If i >= length(a),
13.84 - * then return 0. (The above behaviour differs from mpl_get_bit, which
13.85 - * causes an error if i >= length(a).) */
13.86 -#define MP_GET_BIT(a, i) \
13.87 - ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
13.88 -
13.89 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
13.90 -#define MP_ADD_CARRY(a1, a2, s, cin, cout) \
13.91 - { mp_word w; \
13.92 - w = ((mp_word)(cin)) + (a1) + (a2); \
13.93 - s = ACCUM(w); \
13.94 - cout = CARRYOUT(w); }
13.95 -
13.96 -#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
13.97 - { mp_word w; \
13.98 - w = ((mp_word)(a1)) - (a2) - (bin); \
13.99 - s = ACCUM(w); \
13.100 - bout = (w >> MP_DIGIT_BIT) & 1; }
13.101 -
13.102 -#else
13.103 -/* NOTE,
13.104 - * cin and cout could be the same variable.
13.105 - * bin and bout could be the same variable.
13.106 - * a1 or a2 and s could be the same variable.
13.107 - * don't trash those outputs until their respective inputs have
13.108 - * been read. */
13.109 -#define MP_ADD_CARRY(a1, a2, s, cin, cout) \
13.110 - { mp_digit tmp,sum; \
13.111 - tmp = (a1); \
13.112 - sum = tmp + (a2); \
13.113 - tmp = (sum < tmp); /* detect overflow */ \
13.114 - s = sum += (cin); \
13.115 - cout = tmp + (sum < (cin)); }
13.116 -
13.117 -#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
13.118 - { mp_digit tmp; \
13.119 - tmp = (a1); \
13.120 - s = tmp - (a2); \
13.121 - tmp = (s > tmp); /* detect borrow */ \
13.122 - if ((bin) && !s--) tmp++; \
13.123 - bout = tmp; }
13.124 -#endif
13.125 -
13.126 -
13.127 -struct GFMethodStr;
13.128 -typedef struct GFMethodStr GFMethod;
13.129 -struct GFMethodStr {
13.130 - /* Indicates whether the structure was constructed from dynamic memory
13.131 - * or statically created. */
13.132 - int constructed;
13.133 - /* Irreducible that defines the field. For prime fields, this is the
13.134 - * prime p. For binary polynomial fields, this is the bitstring
13.135 - * representation of the irreducible polynomial. */
13.136 - mp_int irr;
13.137 - /* For prime fields, the value irr_arr[0] is the number of bits in the
13.138 - * field. For binary polynomial fields, the irreducible polynomial
13.139 - * f(t) is represented as an array of unsigned int[], where f(t) is
13.140 - * of the form: f(t) = t^p[0] + t^p[1] + ... + t^p[4] where m = p[0]
13.141 - * > p[1] > ... > p[4] = 0. */
13.142 - unsigned int irr_arr[5];
13.143 - /* Field arithmetic methods. All methods (except field_enc and
13.144 - * field_dec) are assumed to take field-encoded parameters and return
13.145 - * field-encoded values. All methods (except field_enc and field_dec)
13.146 - * are required to be implemented. */
13.147 - mp_err (*field_add) (const mp_int *a, const mp_int *b, mp_int *r,
13.148 - const GFMethod *meth);
13.149 - mp_err (*field_neg) (const mp_int *a, mp_int *r, const GFMethod *meth);
13.150 - mp_err (*field_sub) (const mp_int *a, const mp_int *b, mp_int *r,
13.151 - const GFMethod *meth);
13.152 - mp_err (*field_mod) (const mp_int *a, mp_int *r, const GFMethod *meth);
13.153 - mp_err (*field_mul) (const mp_int *a, const mp_int *b, mp_int *r,
13.154 - const GFMethod *meth);
13.155 - mp_err (*field_sqr) (const mp_int *a, mp_int *r, const GFMethod *meth);
13.156 - mp_err (*field_div) (const mp_int *a, const mp_int *b, mp_int *r,
13.157 - const GFMethod *meth);
13.158 - mp_err (*field_enc) (const mp_int *a, mp_int *r, const GFMethod *meth);
13.159 - mp_err (*field_dec) (const mp_int *a, mp_int *r, const GFMethod *meth);
13.160 - /* Extra storage for implementation-specific data. Any memory
13.161 - * allocated to these extra fields will be cleared by extra_free. */
13.162 - void *extra1;
13.163 - void *extra2;
13.164 - void (*extra_free) (GFMethod *meth);
13.165 -};
13.166 -
13.167 -/* Construct generic GFMethods. */
13.168 -GFMethod *GFMethod_consGFp(const mp_int *irr);
13.169 -GFMethod *GFMethod_consGFp_mont(const mp_int *irr);
13.170 -GFMethod *GFMethod_consGF2m(const mp_int *irr,
13.171 - const unsigned int irr_arr[5]);
13.172 -/* Free the memory allocated (if any) to a GFMethod object. */
13.173 -void GFMethod_free(GFMethod *meth);
13.174 -
13.175 -struct ECGroupStr {
13.176 - /* Indicates whether the structure was constructed from dynamic memory
13.177 - * or statically created. */
13.178 - int constructed;
13.179 - /* Field definition and arithmetic. */
13.180 - GFMethod *meth;
13.181 - /* Textual representation of curve name, if any. */
13.182 - char *text;
13.183 -#ifdef _KERNEL
13.184 - int text_len;
13.185 -#endif
13.186 - /* Curve parameters, field-encoded. */
13.187 - mp_int curvea, curveb;
13.188 - /* x and y coordinates of the base point, field-encoded. */
13.189 - mp_int genx, geny;
13.190 - /* Order and cofactor of the base point. */
13.191 - mp_int order;
13.192 - int cofactor;
13.193 - /* Point arithmetic methods. All methods are assumed to take
13.194 - * field-encoded parameters and return field-encoded values. All
13.195 - * methods (except base_point_mul and points_mul) are required to be
13.196 - * implemented. */
13.197 - mp_err (*point_add) (const mp_int *px, const mp_int *py,
13.198 - const mp_int *qx, const mp_int *qy, mp_int *rx,
13.199 - mp_int *ry, const ECGroup *group);
13.200 - mp_err (*point_sub) (const mp_int *px, const mp_int *py,
13.201 - const mp_int *qx, const mp_int *qy, mp_int *rx,
13.202 - mp_int *ry, const ECGroup *group);
13.203 - mp_err (*point_dbl) (const mp_int *px, const mp_int *py, mp_int *rx,
13.204 - mp_int *ry, const ECGroup *group);
13.205 - mp_err (*point_mul) (const mp_int *n, const mp_int *px,
13.206 - const mp_int *py, mp_int *rx, mp_int *ry,
13.207 - const ECGroup *group);
13.208 - mp_err (*base_point_mul) (const mp_int *n, mp_int *rx, mp_int *ry,
13.209 - const ECGroup *group);
13.210 - mp_err (*points_mul) (const mp_int *k1, const mp_int *k2,
13.211 - const mp_int *px, const mp_int *py, mp_int *rx,
13.212 - mp_int *ry, const ECGroup *group);
13.213 - mp_err (*validate_point) (const mp_int *px, const mp_int *py, const ECGroup *group);
13.214 - /* Extra storage for implementation-specific data. Any memory
13.215 - * allocated to these extra fields will be cleared by extra_free. */
13.216 - void *extra1;
13.217 - void *extra2;
13.218 - void (*extra_free) (ECGroup *group);
13.219 -};
13.220 -
13.221 -/* Wrapper functions for generic prime field arithmetic. */
13.222 -mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
13.223 - const GFMethod *meth);
13.224 -mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
13.225 -mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
13.226 - const GFMethod *meth);
13.227 -
13.228 -/* fixed length in-line adds. Count is in words */
13.229 -mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
13.230 - const GFMethod *meth);
13.231 -mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
13.232 - const GFMethod *meth);
13.233 -mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
13.234 - const GFMethod *meth);
13.235 -mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
13.236 - const GFMethod *meth);
13.237 -mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
13.238 - const GFMethod *meth);
13.239 -mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
13.240 - const GFMethod *meth);
13.241 -mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
13.242 - const GFMethod *meth);
13.243 -mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
13.244 - const GFMethod *meth);
13.245 -
13.246 -mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
13.247 -mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
13.248 - const GFMethod *meth);
13.249 -mp_err ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
13.250 -mp_err ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
13.251 - const GFMethod *meth);
13.252 -/* Wrapper functions for generic binary polynomial field arithmetic. */
13.253 -mp_err ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
13.254 - const GFMethod *meth);
13.255 -mp_err ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
13.256 -mp_err ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
13.257 -mp_err ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
13.258 - const GFMethod *meth);
13.259 -mp_err ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
13.260 -mp_err ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
13.261 - const GFMethod *meth);
13.262 -
13.263 -/* Montgomery prime field arithmetic. */
13.264 -mp_err ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
13.265 - const GFMethod *meth);
13.266 -mp_err ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
13.267 -mp_err ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
13.268 - const GFMethod *meth);
13.269 -mp_err ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
13.270 -mp_err ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
13.271 -void ec_GFp_extra_free_mont(GFMethod *meth);
13.272 -
13.273 -/* point multiplication */
13.274 -mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
13.275 - const mp_int *px, const mp_int *py, mp_int *rx,
13.276 - mp_int *ry, const ECGroup *group);
13.277 -mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
13.278 - const mp_int *px, const mp_int *py, mp_int *rx,
13.279 - mp_int *ry, const ECGroup *group);
13.280 -
13.281 -/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
13.282 - * be an array of signed char's to output to, bitsize should be the number
13.283 - * of bits of out, in is the original scalar, and w is the window size.
13.284 - * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
13.285 - * Menezes, "Software implementation of elliptic curve cryptography over
13.286 - * binary fields", Proc. CHES 2000. */
13.287 -mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in,
13.288 - int w);
13.289 -
13.290 -/* Optimized field arithmetic */
13.291 -mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
13.292 -mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName);
13.293 -mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName);
13.294 -mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName);
13.295 -mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName);
13.296 -mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name);
13.297 -mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name);
13.298 -mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
13.299 -
13.300 -/* Optimized floating-point arithmetic */
13.301 -#ifdef ECL_USE_FP
13.302 -mp_err ec_group_set_secp160r1_fp(ECGroup *group);
13.303 -mp_err ec_group_set_nistp192_fp(ECGroup *group);
13.304 -mp_err ec_group_set_nistp224_fp(ECGroup *group);
13.305 -#endif
13.306 -
13.307 -#endif /* _ECL_PRIV_H */
14.1 --- a/src/share/native/sun/security/ec/ecl.c Tue Oct 13 15:25:58 2009 -0700
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,475 +0,0 @@
14.4 -/* *********************************************************************
14.5 - *
14.6 - * Sun elects to have this file available under and governed by the
14.7 - * Mozilla Public License Version 1.1 ("MPL") (see
14.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
14.9 - * of doubt and subject to the following, Sun also elects to allow
14.10 - * licensees to use this file under the MPL, the GNU General Public
14.11 - * License version 2 only or the Lesser General Public License version
14.12 - * 2.1 only. Any references to the "GNU General Public License version 2
14.13 - * or later" or "GPL" in the following shall be construed to mean the
14.14 - * GNU General Public License version 2 only. Any references to the "GNU
14.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
14.16 - * following shall be construed to mean the GNU Lesser General Public
14.17 - * License version 2.1 only. However, the following notice accompanied
14.18 - * the original version of this file:
14.19 - *
14.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
14.21 - *
14.22 - * The contents of this file are subject to the Mozilla Public License Version
14.23 - * 1.1 (the "License"); you may not use this file except in compliance with
14.24 - * the License. You may obtain a copy of the License at
14.25 - * http://www.mozilla.org/MPL/
14.26 - *
14.27 - * Software distributed under the License is distributed on an "AS IS" basis,
14.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14.29 - * for the specific language governing rights and limitations under the
14.30 - * License.
14.31 - *
14.32 - * The Original Code is the elliptic curve math library.
14.33 - *
14.34 - * The Initial Developer of the Original Code is
14.35 - * Sun Microsystems, Inc.
14.36 - * Portions created by the Initial Developer are Copyright (C) 2003
14.37 - * the Initial Developer. All Rights Reserved.
14.38 - *
14.39 - * Contributor(s):
14.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
14.41 - *
14.42 - * Alternatively, the contents of this file may be used under the terms of
14.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
14.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
14.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
14.46 - * of those above. If you wish to allow use of your version of this file only
14.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
14.48 - * use your version of this file under the terms of the MPL, indicate your
14.49 - * decision by deleting the provisions above and replace them with the notice
14.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
14.51 - * the provisions above, a recipient may use your version of this file under
14.52 - * the terms of any one of the MPL, the GPL or the LGPL.
14.53 - *
14.54 - *********************************************************************** */
14.55 -/*
14.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
14.57 - * Use is subject to license terms.
14.58 - */
14.59 -
14.60 -#pragma ident "%Z%%M% %I% %E% SMI"
14.61 -
14.62 -#include "mpi.h"
14.63 -#include "mplogic.h"
14.64 -#include "ecl.h"
14.65 -#include "ecl-priv.h"
14.66 -#include "ec2.h"
14.67 -#include "ecp.h"
14.68 -#ifndef _KERNEL
14.69 -#include <stdlib.h>
14.70 -#include <string.h>
14.71 -#endif
14.72 -
14.73 -/* Allocate memory for a new ECGroup object. */
14.74 -ECGroup *
14.75 -ECGroup_new(int kmflag)
14.76 -{
14.77 - mp_err res = MP_OKAY;
14.78 - ECGroup *group;
14.79 -#ifdef _KERNEL
14.80 - group = (ECGroup *) kmem_alloc(sizeof(ECGroup), kmflag);
14.81 -#else
14.82 - group = (ECGroup *) malloc(sizeof(ECGroup));
14.83 -#endif
14.84 - if (group == NULL)
14.85 - return NULL;
14.86 - group->constructed = MP_YES;
14.87 - group->meth = NULL;
14.88 - group->text = NULL;
14.89 - MP_DIGITS(&group->curvea) = 0;
14.90 - MP_DIGITS(&group->curveb) = 0;
14.91 - MP_DIGITS(&group->genx) = 0;
14.92 - MP_DIGITS(&group->geny) = 0;
14.93 - MP_DIGITS(&group->order) = 0;
14.94 - group->base_point_mul = NULL;
14.95 - group->points_mul = NULL;
14.96 - group->validate_point = NULL;
14.97 - group->extra1 = NULL;
14.98 - group->extra2 = NULL;
14.99 - group->extra_free = NULL;
14.100 - MP_CHECKOK(mp_init(&group->curvea, kmflag));
14.101 - MP_CHECKOK(mp_init(&group->curveb, kmflag));
14.102 - MP_CHECKOK(mp_init(&group->genx, kmflag));
14.103 - MP_CHECKOK(mp_init(&group->geny, kmflag));
14.104 - MP_CHECKOK(mp_init(&group->order, kmflag));
14.105 -
14.106 - CLEANUP:
14.107 - if (res != MP_OKAY) {
14.108 - ECGroup_free(group);
14.109 - return NULL;
14.110 - }
14.111 - return group;
14.112 -}
14.113 -
14.114 -/* Construct a generic ECGroup for elliptic curves over prime fields. */
14.115 -ECGroup *
14.116 -ECGroup_consGFp(const mp_int *irr, const mp_int *curvea,
14.117 - const mp_int *curveb, const mp_int *genx,
14.118 - const mp_int *geny, const mp_int *order, int cofactor)
14.119 -{
14.120 - mp_err res = MP_OKAY;
14.121 - ECGroup *group = NULL;
14.122 -
14.123 - group = ECGroup_new(FLAG(irr));
14.124 - if (group == NULL)
14.125 - return NULL;
14.126 -
14.127 - group->meth = GFMethod_consGFp(irr);
14.128 - if (group->meth == NULL) {
14.129 - res = MP_MEM;
14.130 - goto CLEANUP;
14.131 - }
14.132 - MP_CHECKOK(mp_copy(curvea, &group->curvea));
14.133 - MP_CHECKOK(mp_copy(curveb, &group->curveb));
14.134 - MP_CHECKOK(mp_copy(genx, &group->genx));
14.135 - MP_CHECKOK(mp_copy(geny, &group->geny));
14.136 - MP_CHECKOK(mp_copy(order, &group->order));
14.137 - group->cofactor = cofactor;
14.138 - group->point_add = &ec_GFp_pt_add_aff;
14.139 - group->point_sub = &ec_GFp_pt_sub_aff;
14.140 - group->point_dbl = &ec_GFp_pt_dbl_aff;
14.141 - group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
14.142 - group->base_point_mul = NULL;
14.143 - group->points_mul = &ec_GFp_pts_mul_jac;
14.144 - group->validate_point = &ec_GFp_validate_point;
14.145 -
14.146 - CLEANUP:
14.147 - if (res != MP_OKAY) {
14.148 - ECGroup_free(group);
14.149 - return NULL;
14.150 - }
14.151 - return group;
14.152 -}
14.153 -
14.154 -/* Construct a generic ECGroup for elliptic curves over prime fields with
14.155 - * field arithmetic implemented in Montgomery coordinates. */
14.156 -ECGroup *
14.157 -ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
14.158 - const mp_int *curveb, const mp_int *genx,
14.159 - const mp_int *geny, const mp_int *order, int cofactor)
14.160 -{
14.161 - mp_err res = MP_OKAY;
14.162 - ECGroup *group = NULL;
14.163 -
14.164 - group = ECGroup_new(FLAG(irr));
14.165 - if (group == NULL)
14.166 - return NULL;
14.167 -
14.168 - group->meth = GFMethod_consGFp_mont(irr);
14.169 - if (group->meth == NULL) {
14.170 - res = MP_MEM;
14.171 - goto CLEANUP;
14.172 - }
14.173 - MP_CHECKOK(group->meth->
14.174 - field_enc(curvea, &group->curvea, group->meth));
14.175 - MP_CHECKOK(group->meth->
14.176 - field_enc(curveb, &group->curveb, group->meth));
14.177 - MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth));
14.178 - MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth));
14.179 - MP_CHECKOK(mp_copy(order, &group->order));
14.180 - group->cofactor = cofactor;
14.181 - group->point_add = &ec_GFp_pt_add_aff;
14.182 - group->point_sub = &ec_GFp_pt_sub_aff;
14.183 - group->point_dbl = &ec_GFp_pt_dbl_aff;
14.184 - group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
14.185 - group->base_point_mul = NULL;
14.186 - group->points_mul = &ec_GFp_pts_mul_jac;
14.187 - group->validate_point = &ec_GFp_validate_point;
14.188 -
14.189 - CLEANUP:
14.190 - if (res != MP_OKAY) {
14.191 - ECGroup_free(group);
14.192 - return NULL;
14.193 - }
14.194 - return group;
14.195 -}
14.196 -
14.197 -#ifdef NSS_ECC_MORE_THAN_SUITE_B
14.198 -/* Construct a generic ECGroup for elliptic curves over binary polynomial
14.199 - * fields. */
14.200 -ECGroup *
14.201 -ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
14.202 - const mp_int *curvea, const mp_int *curveb,
14.203 - const mp_int *genx, const mp_int *geny,
14.204 - const mp_int *order, int cofactor)
14.205 -{
14.206 - mp_err res = MP_OKAY;
14.207 - ECGroup *group = NULL;
14.208 -
14.209 - group = ECGroup_new(FLAG(irr));
14.210 - if (group == NULL)
14.211 - return NULL;
14.212 -
14.213 - group->meth = GFMethod_consGF2m(irr, irr_arr);
14.214 - if (group->meth == NULL) {
14.215 - res = MP_MEM;
14.216 - goto CLEANUP;
14.217 - }
14.218 - MP_CHECKOK(mp_copy(curvea, &group->curvea));
14.219 - MP_CHECKOK(mp_copy(curveb, &group->curveb));
14.220 - MP_CHECKOK(mp_copy(genx, &group->genx));
14.221 - MP_CHECKOK(mp_copy(geny, &group->geny));
14.222 - MP_CHECKOK(mp_copy(order, &group->order));
14.223 - group->cofactor = cofactor;
14.224 - group->point_add = &ec_GF2m_pt_add_aff;
14.225 - group->point_sub = &ec_GF2m_pt_sub_aff;
14.226 - group->point_dbl = &ec_GF2m_pt_dbl_aff;
14.227 - group->point_mul = &ec_GF2m_pt_mul_mont;
14.228 - group->base_point_mul = NULL;
14.229 - group->points_mul = &ec_pts_mul_basic;
14.230 - group->validate_point = &ec_GF2m_validate_point;
14.231 -
14.232 - CLEANUP:
14.233 - if (res != MP_OKAY) {
14.234 - ECGroup_free(group);
14.235 - return NULL;
14.236 - }
14.237 - return group;
14.238 -}
14.239 -#endif
14.240 -
14.241 -/* Construct ECGroup from hex parameters and name, if any. Called by
14.242 - * ECGroup_fromHex and ECGroup_fromName. */
14.243 -ECGroup *
14.244 -ecgroup_fromNameAndHex(const ECCurveName name,
14.245 - const ECCurveParams * params, int kmflag)
14.246 -{
14.247 - mp_int irr, curvea, curveb, genx, geny, order;
14.248 - int bits;
14.249 - ECGroup *group = NULL;
14.250 - mp_err res = MP_OKAY;
14.251 -
14.252 - /* initialize values */
14.253 - MP_DIGITS(&irr) = 0;
14.254 - MP_DIGITS(&curvea) = 0;
14.255 - MP_DIGITS(&curveb) = 0;
14.256 - MP_DIGITS(&genx) = 0;
14.257 - MP_DIGITS(&geny) = 0;
14.258 - MP_DIGITS(&order) = 0;
14.259 - MP_CHECKOK(mp_init(&irr, kmflag));
14.260 - MP_CHECKOK(mp_init(&curvea, kmflag));
14.261 - MP_CHECKOK(mp_init(&curveb, kmflag));
14.262 - MP_CHECKOK(mp_init(&genx, kmflag));
14.263 - MP_CHECKOK(mp_init(&geny, kmflag));
14.264 - MP_CHECKOK(mp_init(&order, kmflag));
14.265 - MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
14.266 - MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
14.267 - MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
14.268 - MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
14.269 - MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
14.270 - MP_CHECKOK(mp_read_radix(&order, params->order, 16));
14.271 -
14.272 - /* determine number of bits */
14.273 - bits = mpl_significant_bits(&irr) - 1;
14.274 - if (bits < MP_OKAY) {
14.275 - res = bits;
14.276 - goto CLEANUP;
14.277 - }
14.278 -
14.279 - /* determine which optimizations (if any) to use */
14.280 - if (params->field == ECField_GFp) {
14.281 -#ifdef NSS_ECC_MORE_THAN_SUITE_B
14.282 - switch (name) {
14.283 -#ifdef ECL_USE_FP
14.284 - case ECCurve_SECG_PRIME_160R1:
14.285 - group =
14.286 - ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
14.287 - &order, params->cofactor);
14.288 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.289 - MP_CHECKOK(ec_group_set_secp160r1_fp(group));
14.290 - break;
14.291 -#endif
14.292 - case ECCurve_SECG_PRIME_192R1:
14.293 -#ifdef ECL_USE_FP
14.294 - group =
14.295 - ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
14.296 - &order, params->cofactor);
14.297 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.298 - MP_CHECKOK(ec_group_set_nistp192_fp(group));
14.299 -#else
14.300 - group =
14.301 - ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
14.302 - &order, params->cofactor);
14.303 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.304 - MP_CHECKOK(ec_group_set_gfp192(group, name));
14.305 -#endif
14.306 - break;
14.307 - case ECCurve_SECG_PRIME_224R1:
14.308 -#ifdef ECL_USE_FP
14.309 - group =
14.310 - ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
14.311 - &order, params->cofactor);
14.312 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.313 - MP_CHECKOK(ec_group_set_nistp224_fp(group));
14.314 -#else
14.315 - group =
14.316 - ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
14.317 - &order, params->cofactor);
14.318 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.319 - MP_CHECKOK(ec_group_set_gfp224(group, name));
14.320 -#endif
14.321 - break;
14.322 - case ECCurve_SECG_PRIME_256R1:
14.323 - group =
14.324 - ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
14.325 - &order, params->cofactor);
14.326 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.327 - MP_CHECKOK(ec_group_set_gfp256(group, name));
14.328 - break;
14.329 - case ECCurve_SECG_PRIME_521R1:
14.330 - group =
14.331 - ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
14.332 - &order, params->cofactor);
14.333 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.334 - MP_CHECKOK(ec_group_set_gfp521(group, name));
14.335 - break;
14.336 - default:
14.337 - /* use generic arithmetic */
14.338 -#endif
14.339 - group =
14.340 - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
14.341 - &order, params->cofactor);
14.342 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.343 -#ifdef NSS_ECC_MORE_THAN_SUITE_B
14.344 - }
14.345 - } else if (params->field == ECField_GF2m) {
14.346 - group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor);
14.347 - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
14.348 - if ((name == ECCurve_NIST_K163) ||
14.349 - (name == ECCurve_NIST_B163) ||
14.350 - (name == ECCurve_SECG_CHAR2_163R1)) {
14.351 - MP_CHECKOK(ec_group_set_gf2m163(group, name));
14.352 - } else if ((name == ECCurve_SECG_CHAR2_193R1) ||
14.353 - (name == ECCurve_SECG_CHAR2_193R2)) {
14.354 - MP_CHECKOK(ec_group_set_gf2m193(group, name));
14.355 - } else if ((name == ECCurve_NIST_K233) ||
14.356 - (name == ECCurve_NIST_B233)) {
14.357 - MP_CHECKOK(ec_group_set_gf2m233(group, name));
14.358 - }
14.359 -#endif
14.360 - } else {
14.361 - res = MP_UNDEF;
14.362 - goto CLEANUP;
14.363 - }
14.364 -
14.365 - /* set name, if any */
14.366 - if ((group != NULL) && (params->text != NULL)) {
14.367 -#ifdef _KERNEL
14.368 - int n = strlen(params->text) + 1;
14.369 -
14.370 - group->text = kmem_alloc(n, kmflag);
14.371 - if (group->text == NULL) {
14.372 - res = MP_MEM;
14.373 - goto CLEANUP;
14.374 - }
14.375 - bcopy(params->text, group->text, n);
14.376 - group->text_len = n;
14.377 -#else
14.378 - group->text = strdup(params->text);
14.379 - if (group->text == NULL) {
14.380 - res = MP_MEM;
14.381 - }
14.382 -#endif
14.383 - }
14.384 -
14.385 - CLEANUP:
14.386 - mp_clear(&irr);
14.387 - mp_clear(&curvea);
14.388 - mp_clear(&curveb);
14.389 - mp_clear(&genx);
14.390 - mp_clear(&geny);
14.391 - mp_clear(&order);
14.392 - if (res != MP_OKAY) {
14.393 - ECGroup_free(group);
14.394 - return NULL;
14.395 - }
14.396 - return group;
14.397 -}
14.398 -
14.399 -/* Construct ECGroup from hexadecimal representations of parameters. */
14.400 -ECGroup *
14.401 -ECGroup_fromHex(const ECCurveParams * params, int kmflag)
14.402 -{
14.403 - return ecgroup_fromNameAndHex(ECCurve_noName, params, kmflag);
14.404 -}
14.405 -
14.406 -/* Construct ECGroup from named parameters. */
14.407 -ECGroup *
14.408 -ECGroup_fromName(const ECCurveName name, int kmflag)
14.409 -{
14.410 - ECGroup *group = NULL;
14.411 - ECCurveParams *params = NULL;
14.412 - mp_err res = MP_OKAY;
14.413 -
14.414 - params = EC_GetNamedCurveParams(name, kmflag);
14.415 - if (params == NULL) {
14.416 - res = MP_UNDEF;
14.417 - goto CLEANUP;
14.418 - }
14.419 -
14.420 - /* construct actual group */
14.421 - group = ecgroup_fromNameAndHex(name, params, kmflag);
14.422 - if (group == NULL) {
14.423 - res = MP_UNDEF;
14.424 - goto CLEANUP;
14.425 - }
14.426 -
14.427 - CLEANUP:
14.428 - EC_FreeCurveParams(params);
14.429 - if (res != MP_OKAY) {
14.430 - ECGroup_free(group);
14.431 - return NULL;
14.432 - }
14.433 - return group;
14.434 -}
14.435 -
14.436 -/* Validates an EC public key as described in Section 5.2.2 of X9.62. */
14.437 -mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
14.438 - mp_int *py)
14.439 -{
14.440 - /* 1: Verify that publicValue is not the point at infinity */
14.441 - /* 2: Verify that the coordinates of publicValue are elements
14.442 - * of the field.
14.443 - */
14.444 - /* 3: Verify that publicValue is on the curve. */
14.445 - /* 4: Verify that the order of the curve times the publicValue
14.446 - * is the point at infinity.
14.447 - */
14.448 - return group->validate_point(px, py, group);
14.449 -}
14.450 -
14.451 -/* Free the memory allocated (if any) to an ECGroup object. */
14.452 -void
14.453 -ECGroup_free(ECGroup *group)
14.454 -{
14.455 - if (group == NULL)
14.456 - return;
14.457 - GFMethod_free(group->meth);
14.458 - if (group->constructed == MP_NO)
14.459 - return;
14.460 - mp_clear(&group->curvea);
14.461 - mp_clear(&group->curveb);
14.462 - mp_clear(&group->genx);
14.463 - mp_clear(&group->geny);
14.464 - mp_clear(&group->order);
14.465 - if (group->text != NULL)
14.466 -#ifdef _KERNEL
14.467 - kmem_free(group->text, group->text_len);
14.468 -#else
14.469 - free(group->text);
14.470 -#endif
14.471 - if (group->extra_free != NULL)
14.472 - group->extra_free(group);
14.473 -#ifdef _KERNEL
14.474 - kmem_free(group, sizeof (ECGroup));
14.475 -#else
14.476 - free(group);
14.477 -#endif
14.478 -}
15.1 --- a/src/share/native/sun/security/ec/ecl.h Tue Oct 13 15:25:58 2009 -0700
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,111 +0,0 @@
15.4 -/* *********************************************************************
15.5 - *
15.6 - * Sun elects to have this file available under and governed by the
15.7 - * Mozilla Public License Version 1.1 ("MPL") (see
15.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
15.9 - * of doubt and subject to the following, Sun also elects to allow
15.10 - * licensees to use this file under the MPL, the GNU General Public
15.11 - * License version 2 only or the Lesser General Public License version
15.12 - * 2.1 only. Any references to the "GNU General Public License version 2
15.13 - * or later" or "GPL" in the following shall be construed to mean the
15.14 - * GNU General Public License version 2 only. Any references to the "GNU
15.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
15.16 - * following shall be construed to mean the GNU Lesser General Public
15.17 - * License version 2.1 only. However, the following notice accompanied
15.18 - * the original version of this file:
15.19 - *
15.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
15.21 - *
15.22 - * The contents of this file are subject to the Mozilla Public License Version
15.23 - * 1.1 (the "License"); you may not use this file except in compliance with
15.24 - * the License. You may obtain a copy of the License at
15.25 - * http://www.mozilla.org/MPL/
15.26 - *
15.27 - * Software distributed under the License is distributed on an "AS IS" basis,
15.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15.29 - * for the specific language governing rights and limitations under the
15.30 - * License.
15.31 - *
15.32 - * The Original Code is the elliptic curve math library.
15.33 - *
15.34 - * The Initial Developer of the Original Code is
15.35 - * Sun Microsystems, Inc.
15.36 - * Portions created by the Initial Developer are Copyright (C) 2003
15.37 - * the Initial Developer. All Rights Reserved.
15.38 - *
15.39 - * Contributor(s):
15.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
15.41 - *
15.42 - * Alternatively, the contents of this file may be used under the terms of
15.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
15.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
15.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
15.46 - * of those above. If you wish to allow use of your version of this file only
15.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
15.48 - * use your version of this file under the terms of the MPL, indicate your
15.49 - * decision by deleting the provisions above and replace them with the notice
15.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
15.51 - * the provisions above, a recipient may use your version of this file under
15.52 - * the terms of any one of the MPL, the GPL or the LGPL.
15.53 - *
15.54 - *********************************************************************** */
15.55 -/*
15.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
15.57 - * Use is subject to license terms.
15.58 - */
15.59 -
15.60 -#ifndef _ECL_H
15.61 -#define _ECL_H
15.62 -
15.63 -#pragma ident "%Z%%M% %I% %E% SMI"
15.64 -
15.65 -/* Although this is not an exported header file, code which uses elliptic
15.66 - * curve point operations will need to include it. */
15.67 -
15.68 -#include "ecl-exp.h"
15.69 -#include "mpi.h"
15.70 -
15.71 -struct ECGroupStr;
15.72 -typedef struct ECGroupStr ECGroup;
15.73 -
15.74 -/* Construct ECGroup from hexadecimal representations of parameters. */
15.75 -ECGroup *ECGroup_fromHex(const ECCurveParams * params, int kmflag);
15.76 -
15.77 -/* Construct ECGroup from named parameters. */
15.78 -ECGroup *ECGroup_fromName(const ECCurveName name, int kmflag);
15.79 -
15.80 -/* Free an allocated ECGroup. */
15.81 -void ECGroup_free(ECGroup *group);
15.82 -
15.83 -/* Construct ECCurveParams from an ECCurveName */
15.84 -ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name, int kmflag);
15.85 -
15.86 -/* Duplicates an ECCurveParams */
15.87 -ECCurveParams *ECCurveParams_dup(const ECCurveParams * params, int kmflag);
15.88 -
15.89 -/* Free an allocated ECCurveParams */
15.90 -void EC_FreeCurveParams(ECCurveParams * params);
15.91 -
15.92 -/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x,
15.93 - * y). If x, y = NULL, then P is assumed to be the generator (base point)
15.94 - * of the group of points on the elliptic curve. Input and output values
15.95 - * are assumed to be NOT field-encoded. */
15.96 -mp_err ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
15.97 - const mp_int *py, mp_int *qx, mp_int *qy);
15.98 -
15.99 -/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k1 * G +
15.100 - * k2 * P(x, y), where G is the generator (base point) of the group of
15.101 - * points on the elliptic curve. Input and output values are assumed to
15.102 - * be NOT field-encoded. */
15.103 -mp_err ECPoints_mul(const ECGroup *group, const mp_int *k1,
15.104 - const mp_int *k2, const mp_int *px, const mp_int *py,
15.105 - mp_int *qx, mp_int *qy);
15.106 -
15.107 -/* Validates an EC public key as described in Section 5.2.2 of X9.62.
15.108 - * Returns MP_YES if the public key is valid, MP_NO if the public key
15.109 - * is invalid, or an error code if the validation could not be
15.110 - * performed. */
15.111 -mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
15.112 - mp_int *py);
15.113 -
15.114 -#endif /* _ECL_H */
16.1 --- a/src/share/native/sun/security/ec/ecl_curve.c Tue Oct 13 15:25:58 2009 -0700
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,216 +0,0 @@
16.4 -/* *********************************************************************
16.5 - *
16.6 - * Sun elects to have this file available under and governed by the
16.7 - * Mozilla Public License Version 1.1 ("MPL") (see
16.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
16.9 - * of doubt and subject to the following, Sun also elects to allow
16.10 - * licensees to use this file under the MPL, the GNU General Public
16.11 - * License version 2 only or the Lesser General Public License version
16.12 - * 2.1 only. Any references to the "GNU General Public License version 2
16.13 - * or later" or "GPL" in the following shall be construed to mean the
16.14 - * GNU General Public License version 2 only. Any references to the "GNU
16.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
16.16 - * following shall be construed to mean the GNU Lesser General Public
16.17 - * License version 2.1 only. However, the following notice accompanied
16.18 - * the original version of this file:
16.19 - *
16.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
16.21 - *
16.22 - * The contents of this file are subject to the Mozilla Public License Version
16.23 - * 1.1 (the "License"); you may not use this file except in compliance with
16.24 - * the License. You may obtain a copy of the License at
16.25 - * http://www.mozilla.org/MPL/
16.26 - *
16.27 - * Software distributed under the License is distributed on an "AS IS" basis,
16.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16.29 - * for the specific language governing rights and limitations under the
16.30 - * License.
16.31 - *
16.32 - * The Original Code is the elliptic curve math library.
16.33 - *
16.34 - * The Initial Developer of the Original Code is
16.35 - * Sun Microsystems, Inc.
16.36 - * Portions created by the Initial Developer are Copyright (C) 2003
16.37 - * the Initial Developer. All Rights Reserved.
16.38 - *
16.39 - * Contributor(s):
16.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
16.41 - *
16.42 - * Alternatively, the contents of this file may be used under the terms of
16.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
16.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
16.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
16.46 - * of those above. If you wish to allow use of your version of this file only
16.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
16.48 - * use your version of this file under the terms of the MPL, indicate your
16.49 - * decision by deleting the provisions above and replace them with the notice
16.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
16.51 - * the provisions above, a recipient may use your version of this file under
16.52 - * the terms of any one of the MPL, the GPL or the LGPL.
16.53 - *
16.54 - *********************************************************************** */
16.55 -/*
16.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
16.57 - * Use is subject to license terms.
16.58 - */
16.59 -
16.60 -#pragma ident "%Z%%M% %I% %E% SMI"
16.61 -
16.62 -#include "ecl.h"
16.63 -#include "ecl-curve.h"
16.64 -#include "ecl-priv.h"
16.65 -#ifndef _KERNEL
16.66 -#include <stdlib.h>
16.67 -#include <string.h>
16.68 -#endif
16.69 -
16.70 -#define CHECK(func) if ((func) == NULL) { res = 0; goto CLEANUP; }
16.71 -
16.72 -/* Duplicates an ECCurveParams */
16.73 -ECCurveParams *
16.74 -ECCurveParams_dup(const ECCurveParams * params, int kmflag)
16.75 -{
16.76 - int res = 1;
16.77 - ECCurveParams *ret = NULL;
16.78 -
16.79 -#ifdef _KERNEL
16.80 - ret = (ECCurveParams *) kmem_zalloc(sizeof(ECCurveParams), kmflag);
16.81 -#else
16.82 - CHECK(ret = (ECCurveParams *) calloc(1, sizeof(ECCurveParams)));
16.83 -#endif
16.84 - if (params->text != NULL) {
16.85 -#ifdef _KERNEL
16.86 - ret->text = kmem_alloc(strlen(params->text) + 1, kmflag);
16.87 - bcopy(params->text, ret->text, strlen(params->text) + 1);
16.88 -#else
16.89 - CHECK(ret->text = strdup(params->text));
16.90 -#endif
16.91 - }
16.92 - ret->field = params->field;
16.93 - ret->size = params->size;
16.94 - if (params->irr != NULL) {
16.95 -#ifdef _KERNEL
16.96 - ret->irr = kmem_alloc(strlen(params->irr) + 1, kmflag);
16.97 - bcopy(params->irr, ret->irr, strlen(params->irr) + 1);
16.98 -#else
16.99 - CHECK(ret->irr = strdup(params->irr));
16.100 -#endif
16.101 - }
16.102 - if (params->curvea != NULL) {
16.103 -#ifdef _KERNEL
16.104 - ret->curvea = kmem_alloc(strlen(params->curvea) + 1, kmflag);
16.105 - bcopy(params->curvea, ret->curvea, strlen(params->curvea) + 1);
16.106 -#else
16.107 - CHECK(ret->curvea = strdup(params->curvea));
16.108 -#endif
16.109 - }
16.110 - if (params->curveb != NULL) {
16.111 -#ifdef _KERNEL
16.112 - ret->curveb = kmem_alloc(strlen(params->curveb) + 1, kmflag);
16.113 - bcopy(params->curveb, ret->curveb, strlen(params->curveb) + 1);
16.114 -#else
16.115 - CHECK(ret->curveb = strdup(params->curveb));
16.116 -#endif
16.117 - }
16.118 - if (params->genx != NULL) {
16.119 -#ifdef _KERNEL
16.120 - ret->genx = kmem_alloc(strlen(params->genx) + 1, kmflag);
16.121 - bcopy(params->genx, ret->genx, strlen(params->genx) + 1);
16.122 -#else
16.123 - CHECK(ret->genx = strdup(params->genx));
16.124 -#endif
16.125 - }
16.126 - if (params->geny != NULL) {
16.127 -#ifdef _KERNEL
16.128 - ret->geny = kmem_alloc(strlen(params->geny) + 1, kmflag);
16.129 - bcopy(params->geny, ret->geny, strlen(params->geny) + 1);
16.130 -#else
16.131 - CHECK(ret->geny = strdup(params->geny));
16.132 -#endif
16.133 - }
16.134 - if (params->order != NULL) {
16.135 -#ifdef _KERNEL
16.136 - ret->order = kmem_alloc(strlen(params->order) + 1, kmflag);
16.137 - bcopy(params->order, ret->order, strlen(params->order) + 1);
16.138 -#else
16.139 - CHECK(ret->order = strdup(params->order));
16.140 -#endif
16.141 - }
16.142 - ret->cofactor = params->cofactor;
16.143 -
16.144 - CLEANUP:
16.145 - if (res != 1) {
16.146 - EC_FreeCurveParams(ret);
16.147 - return NULL;
16.148 - }
16.149 - return ret;
16.150 -}
16.151 -
16.152 -#undef CHECK
16.153 -
16.154 -/* Construct ECCurveParams from an ECCurveName */
16.155 -ECCurveParams *
16.156 -EC_GetNamedCurveParams(const ECCurveName name, int kmflag)
16.157 -{
16.158 - if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) ||
16.159 - (ecCurve_map[name] == NULL)) {
16.160 - return NULL;
16.161 - } else {
16.162 - return ECCurveParams_dup(ecCurve_map[name], kmflag);
16.163 - }
16.164 -}
16.165 -
16.166 -/* Free the memory allocated (if any) to an ECCurveParams object. */
16.167 -void
16.168 -EC_FreeCurveParams(ECCurveParams * params)
16.169 -{
16.170 - if (params == NULL)
16.171 - return;
16.172 - if (params->text != NULL)
16.173 -#ifdef _KERNEL
16.174 - kmem_free(params->text, strlen(params->text) + 1);
16.175 -#else
16.176 - free(params->text);
16.177 -#endif
16.178 - if (params->irr != NULL)
16.179 -#ifdef _KERNEL
16.180 - kmem_free(params->irr, strlen(params->irr) + 1);
16.181 -#else
16.182 - free(params->irr);
16.183 -#endif
16.184 - if (params->curvea != NULL)
16.185 -#ifdef _KERNEL
16.186 - kmem_free(params->curvea, strlen(params->curvea) + 1);
16.187 -#else
16.188 - free(params->curvea);
16.189 -#endif
16.190 - if (params->curveb != NULL)
16.191 -#ifdef _KERNEL
16.192 - kmem_free(params->curveb, strlen(params->curveb) + 1);
16.193 -#else
16.194 - free(params->curveb);
16.195 -#endif
16.196 - if (params->genx != NULL)
16.197 -#ifdef _KERNEL
16.198 - kmem_free(params->genx, strlen(params->genx) + 1);
16.199 -#else
16.200 - free(params->genx);
16.201 -#endif
16.202 - if (params->geny != NULL)
16.203 -#ifdef _KERNEL
16.204 - kmem_free(params->geny, strlen(params->geny) + 1);
16.205 -#else
16.206 - free(params->geny);
16.207 -#endif
16.208 - if (params->order != NULL)
16.209 -#ifdef _KERNEL
16.210 - kmem_free(params->order, strlen(params->order) + 1);
16.211 -#else
16.212 - free(params->order);
16.213 -#endif
16.214 -#ifdef _KERNEL
16.215 - kmem_free(params, sizeof(ECCurveParams));
16.216 -#else
16.217 - free(params);
16.218 -#endif
16.219 -}
17.1 --- a/src/share/native/sun/security/ec/ecl_gf.c Tue Oct 13 15:25:58 2009 -0700
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,1062 +0,0 @@
17.4 -/* *********************************************************************
17.5 - *
17.6 - * Sun elects to have this file available under and governed by the
17.7 - * Mozilla Public License Version 1.1 ("MPL") (see
17.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
17.9 - * of doubt and subject to the following, Sun also elects to allow
17.10 - * licensees to use this file under the MPL, the GNU General Public
17.11 - * License version 2 only or the Lesser General Public License version
17.12 - * 2.1 only. Any references to the "GNU General Public License version 2
17.13 - * or later" or "GPL" in the following shall be construed to mean the
17.14 - * GNU General Public License version 2 only. Any references to the "GNU
17.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
17.16 - * following shall be construed to mean the GNU Lesser General Public
17.17 - * License version 2.1 only. However, the following notice accompanied
17.18 - * the original version of this file:
17.19 - *
17.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
17.21 - *
17.22 - * The contents of this file are subject to the Mozilla Public License Version
17.23 - * 1.1 (the "License"); you may not use this file except in compliance with
17.24 - * the License. You may obtain a copy of the License at
17.25 - * http://www.mozilla.org/MPL/
17.26 - *
17.27 - * Software distributed under the License is distributed on an "AS IS" basis,
17.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17.29 - * for the specific language governing rights and limitations under the
17.30 - * License.
17.31 - *
17.32 - * The Original Code is the elliptic curve math library.
17.33 - *
17.34 - * The Initial Developer of the Original Code is
17.35 - * Sun Microsystems, Inc.
17.36 - * Portions created by the Initial Developer are Copyright (C) 2003
17.37 - * the Initial Developer. All Rights Reserved.
17.38 - *
17.39 - * Contributor(s):
17.40 - * Stephen Fung <fungstep@hotmail.com> and
17.41 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
17.42 - *
17.43 - * Alternatively, the contents of this file may be used under the terms of
17.44 - * either the GNU General Public License Version 2 or later (the "GPL"), or
17.45 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
17.46 - * in which case the provisions of the GPL or the LGPL are applicable instead
17.47 - * of those above. If you wish to allow use of your version of this file only
17.48 - * under the terms of either the GPL or the LGPL, and not to allow others to
17.49 - * use your version of this file under the terms of the MPL, indicate your
17.50 - * decision by deleting the provisions above and replace them with the notice
17.51 - * and other provisions required by the GPL or the LGPL. If you do not delete
17.52 - * the provisions above, a recipient may use your version of this file under
17.53 - * the terms of any one of the MPL, the GPL or the LGPL.
17.54 - *
17.55 - *********************************************************************** */
17.56 -/*
17.57 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
17.58 - * Use is subject to license terms.
17.59 - */
17.60 -
17.61 -#pragma ident "%Z%%M% %I% %E% SMI"
17.62 -
17.63 -#include "mpi.h"
17.64 -#include "mp_gf2m.h"
17.65 -#include "ecl-priv.h"
17.66 -#include "mpi-priv.h"
17.67 -#ifndef _KERNEL
17.68 -#include <stdlib.h>
17.69 -#endif
17.70 -
17.71 -/* Allocate memory for a new GFMethod object. */
17.72 -GFMethod *
17.73 -GFMethod_new(int kmflag)
17.74 -{
17.75 - mp_err res = MP_OKAY;
17.76 - GFMethod *meth;
17.77 -#ifdef _KERNEL
17.78 - meth = (GFMethod *) kmem_alloc(sizeof(GFMethod), kmflag);
17.79 -#else
17.80 - meth = (GFMethod *) malloc(sizeof(GFMethod));
17.81 - if (meth == NULL)
17.82 - return NULL;
17.83 -#endif
17.84 - meth->constructed = MP_YES;
17.85 - MP_DIGITS(&meth->irr) = 0;
17.86 - meth->extra_free = NULL;
17.87 - MP_CHECKOK(mp_init(&meth->irr, kmflag));
17.88 -
17.89 - CLEANUP:
17.90 - if (res != MP_OKAY) {
17.91 - GFMethod_free(meth);
17.92 - return NULL;
17.93 - }
17.94 - return meth;
17.95 -}
17.96 -
17.97 -/* Construct a generic GFMethod for arithmetic over prime fields with
17.98 - * irreducible irr. */
17.99 -GFMethod *
17.100 -GFMethod_consGFp(const mp_int *irr)
17.101 -{
17.102 - mp_err res = MP_OKAY;
17.103 - GFMethod *meth = NULL;
17.104 -
17.105 - meth = GFMethod_new(FLAG(irr));
17.106 - if (meth == NULL)
17.107 - return NULL;
17.108 -
17.109 - MP_CHECKOK(mp_copy(irr, &meth->irr));
17.110 - meth->irr_arr[0] = mpl_significant_bits(irr);
17.111 - meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] =
17.112 - meth->irr_arr[4] = 0;
17.113 - switch(MP_USED(&meth->irr)) {
17.114 - /* maybe we need 1 and 2 words here as well?*/
17.115 - case 3:
17.116 - meth->field_add = &ec_GFp_add_3;
17.117 - meth->field_sub = &ec_GFp_sub_3;
17.118 - break;
17.119 - case 4:
17.120 - meth->field_add = &ec_GFp_add_4;
17.121 - meth->field_sub = &ec_GFp_sub_4;
17.122 - break;
17.123 - case 5:
17.124 - meth->field_add = &ec_GFp_add_5;
17.125 - meth->field_sub = &ec_GFp_sub_5;
17.126 - break;
17.127 - case 6:
17.128 - meth->field_add = &ec_GFp_add_6;
17.129 - meth->field_sub = &ec_GFp_sub_6;
17.130 - break;
17.131 - default:
17.132 - meth->field_add = &ec_GFp_add;
17.133 - meth->field_sub = &ec_GFp_sub;
17.134 - }
17.135 - meth->field_neg = &ec_GFp_neg;
17.136 - meth->field_mod = &ec_GFp_mod;
17.137 - meth->field_mul = &ec_GFp_mul;
17.138 - meth->field_sqr = &ec_GFp_sqr;
17.139 - meth->field_div = &ec_GFp_div;
17.140 - meth->field_enc = NULL;
17.141 - meth->field_dec = NULL;
17.142 - meth->extra1 = NULL;
17.143 - meth->extra2 = NULL;
17.144 - meth->extra_free = NULL;
17.145 -
17.146 - CLEANUP:
17.147 - if (res != MP_OKAY) {
17.148 - GFMethod_free(meth);
17.149 - return NULL;
17.150 - }
17.151 - return meth;
17.152 -}
17.153 -
17.154 -/* Construct a generic GFMethod for arithmetic over binary polynomial
17.155 - * fields with irreducible irr that has array representation irr_arr (see
17.156 - * ecl-priv.h for description of the representation). If irr_arr is NULL,
17.157 - * then it is constructed from the bitstring representation. */
17.158 -GFMethod *
17.159 -GFMethod_consGF2m(const mp_int *irr, const unsigned int irr_arr[5])
17.160 -{
17.161 - mp_err res = MP_OKAY;
17.162 - int ret;
17.163 - GFMethod *meth = NULL;
17.164 -
17.165 - meth = GFMethod_new(FLAG(irr));
17.166 - if (meth == NULL)
17.167 - return NULL;
17.168 -
17.169 - MP_CHECKOK(mp_copy(irr, &meth->irr));
17.170 - if (irr_arr != NULL) {
17.171 - /* Irreducible polynomials are either trinomials or pentanomials. */
17.172 - meth->irr_arr[0] = irr_arr[0];
17.173 - meth->irr_arr[1] = irr_arr[1];
17.174 - meth->irr_arr[2] = irr_arr[2];
17.175 - if (irr_arr[2] > 0) {
17.176 - meth->irr_arr[3] = irr_arr[3];
17.177 - meth->irr_arr[4] = irr_arr[4];
17.178 - } else {
17.179 - meth->irr_arr[3] = meth->irr_arr[4] = 0;
17.180 - }
17.181 - } else {
17.182 - ret = mp_bpoly2arr(irr, meth->irr_arr, 5);
17.183 - /* Irreducible polynomials are either trinomials or pentanomials. */
17.184 - if ((ret != 5) && (ret != 3)) {
17.185 - res = MP_UNDEF;
17.186 - goto CLEANUP;
17.187 - }
17.188 - }
17.189 - meth->field_add = &ec_GF2m_add;
17.190 - meth->field_neg = &ec_GF2m_neg;
17.191 - meth->field_sub = &ec_GF2m_add;
17.192 - meth->field_mod = &ec_GF2m_mod;
17.193 - meth->field_mul = &ec_GF2m_mul;
17.194 - meth->field_sqr = &ec_GF2m_sqr;
17.195 - meth->field_div = &ec_GF2m_div;
17.196 - meth->field_enc = NULL;
17.197 - meth->field_dec = NULL;
17.198 - meth->extra1 = NULL;
17.199 - meth->extra2 = NULL;
17.200 - meth->extra_free = NULL;
17.201 -
17.202 - CLEANUP:
17.203 - if (res != MP_OKAY) {
17.204 - GFMethod_free(meth);
17.205 - return NULL;
17.206 - }
17.207 - return meth;
17.208 -}
17.209 -
17.210 -/* Free the memory allocated (if any) to a GFMethod object. */
17.211 -void
17.212 -GFMethod_free(GFMethod *meth)
17.213 -{
17.214 - if (meth == NULL)
17.215 - return;
17.216 - if (meth->constructed == MP_NO)
17.217 - return;
17.218 - mp_clear(&meth->irr);
17.219 - if (meth->extra_free != NULL)
17.220 - meth->extra_free(meth);
17.221 -#ifdef _KERNEL
17.222 - kmem_free(meth, sizeof(GFMethod));
17.223 -#else
17.224 - free(meth);
17.225 -#endif
17.226 -}
17.227 -
17.228 -/* Wrapper functions for generic prime field arithmetic. */
17.229 -
17.230 -/* Add two field elements. Assumes that 0 <= a, b < meth->irr */
17.231 -mp_err
17.232 -ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
17.233 - const GFMethod *meth)
17.234 -{
17.235 - /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a + b (mod p) */
17.236 - mp_err res;
17.237 -
17.238 - if ((res = mp_add(a, b, r)) != MP_OKAY) {
17.239 - return res;
17.240 - }
17.241 - if (mp_cmp(r, &meth->irr) >= 0) {
17.242 - return mp_sub(r, &meth->irr, r);
17.243 - }
17.244 - return res;
17.245 -}
17.246 -
17.247 -/* Negates a field element. Assumes that 0 <= a < meth->irr */
17.248 -mp_err
17.249 -ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
17.250 -{
17.251 - /* PRE: 0 <= a < p = meth->irr POST: 0 <= r < p, r = -a (mod p) */
17.252 -
17.253 - if (mp_cmp_z(a) == 0) {
17.254 - mp_zero(r);
17.255 - return MP_OKAY;
17.256 - }
17.257 - return mp_sub(&meth->irr, a, r);
17.258 -}
17.259 -
17.260 -/* Subtracts two field elements. Assumes that 0 <= a, b < meth->irr */
17.261 -mp_err
17.262 -ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
17.263 - const GFMethod *meth)
17.264 -{
17.265 - mp_err res = MP_OKAY;
17.266 -
17.267 - /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a - b (mod p) */
17.268 - res = mp_sub(a, b, r);
17.269 - if (res == MP_RANGE) {
17.270 - MP_CHECKOK(mp_sub(b, a, r));
17.271 - if (mp_cmp_z(r) < 0) {
17.272 - MP_CHECKOK(mp_add(r, &meth->irr, r));
17.273 - }
17.274 - MP_CHECKOK(ec_GFp_neg(r, r, meth));
17.275 - }
17.276 - if (mp_cmp_z(r) < 0) {
17.277 - MP_CHECKOK(mp_add(r, &meth->irr, r));
17.278 - }
17.279 - CLEANUP:
17.280 - return res;
17.281 -}
17.282 -/*
17.283 - * Inline adds for small curve lengths.
17.284 - */
17.285 -/* 3 words */
17.286 -mp_err
17.287 -ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
17.288 - const GFMethod *meth)
17.289 -{
17.290 - mp_err res = MP_OKAY;
17.291 - mp_digit a0 = 0, a1 = 0, a2 = 0;
17.292 - mp_digit r0 = 0, r1 = 0, r2 = 0;
17.293 - mp_digit carry;
17.294 -
17.295 - switch(MP_USED(a)) {
17.296 - case 3:
17.297 - a2 = MP_DIGIT(a,2);
17.298 - case 2:
17.299 - a1 = MP_DIGIT(a,1);
17.300 - case 1:
17.301 - a0 = MP_DIGIT(a,0);
17.302 - }
17.303 - switch(MP_USED(b)) {
17.304 - case 3:
17.305 - r2 = MP_DIGIT(b,2);
17.306 - case 2:
17.307 - r1 = MP_DIGIT(b,1);
17.308 - case 1:
17.309 - r0 = MP_DIGIT(b,0);
17.310 - }
17.311 -
17.312 -#ifndef MPI_AMD64_ADD
17.313 - MP_ADD_CARRY(a0, r0, r0, 0, carry);
17.314 - MP_ADD_CARRY(a1, r1, r1, carry, carry);
17.315 - MP_ADD_CARRY(a2, r2, r2, carry, carry);
17.316 -#else
17.317 - __asm__ (
17.318 - "xorq %3,%3 \n\t"
17.319 - "addq %4,%0 \n\t"
17.320 - "adcq %5,%1 \n\t"
17.321 - "adcq %6,%2 \n\t"
17.322 - "adcq $0,%3 \n\t"
17.323 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
17.324 - : "r" (a0), "r" (a1), "r" (a2),
17.325 - "0" (r0), "1" (r1), "2" (r2)
17.326 - : "%cc" );
17.327 -#endif
17.328 -
17.329 - MP_CHECKOK(s_mp_pad(r, 3));
17.330 - MP_DIGIT(r, 2) = r2;
17.331 - MP_DIGIT(r, 1) = r1;
17.332 - MP_DIGIT(r, 0) = r0;
17.333 - MP_SIGN(r) = MP_ZPOS;
17.334 - MP_USED(r) = 3;
17.335 -
17.336 - /* Do quick 'subract' if we've gone over
17.337 - * (add the 2's complement of the curve field) */
17.338 - a2 = MP_DIGIT(&meth->irr,2);
17.339 - if (carry || r2 > a2 ||
17.340 - ((r2 == a2) && mp_cmp(r,&meth->irr) != MP_LT)) {
17.341 - a1 = MP_DIGIT(&meth->irr,1);
17.342 - a0 = MP_DIGIT(&meth->irr,0);
17.343 -#ifndef MPI_AMD64_ADD
17.344 - MP_SUB_BORROW(r0, a0, r0, 0, carry);
17.345 - MP_SUB_BORROW(r1, a1, r1, carry, carry);
17.346 - MP_SUB_BORROW(r2, a2, r2, carry, carry);
17.347 -#else
17.348 - __asm__ (
17.349 - "subq %3,%0 \n\t"
17.350 - "sbbq %4,%1 \n\t"
17.351 - "sbbq %5,%2 \n\t"
17.352 - : "=r"(r0), "=r"(r1), "=r"(r2)
17.353 - : "r" (a0), "r" (a1), "r" (a2),
17.354 - "0" (r0), "1" (r1), "2" (r2)
17.355 - : "%cc" );
17.356 -#endif
17.357 - MP_DIGIT(r, 2) = r2;
17.358 - MP_DIGIT(r, 1) = r1;
17.359 - MP_DIGIT(r, 0) = r0;
17.360 - }
17.361 -
17.362 - s_mp_clamp(r);
17.363 -
17.364 - CLEANUP:
17.365 - return res;
17.366 -}
17.367 -
17.368 -/* 4 words */
17.369 -mp_err
17.370 -ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
17.371 - const GFMethod *meth)
17.372 -{
17.373 - mp_err res = MP_OKAY;
17.374 - mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0;
17.375 - mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
17.376 - mp_digit carry;
17.377 -
17.378 - switch(MP_USED(a)) {
17.379 - case 4:
17.380 - a3 = MP_DIGIT(a,3);
17.381 - case 3:
17.382 - a2 = MP_DIGIT(a,2);
17.383 - case 2:
17.384 - a1 = MP_DIGIT(a,1);
17.385 - case 1:
17.386 - a0 = MP_DIGIT(a,0);
17.387 - }
17.388 - switch(MP_USED(b)) {
17.389 - case 4:
17.390 - r3 = MP_DIGIT(b,3);
17.391 - case 3:
17.392 - r2 = MP_DIGIT(b,2);
17.393 - case 2:
17.394 - r1 = MP_DIGIT(b,1);
17.395 - case 1:
17.396 - r0 = MP_DIGIT(b,0);
17.397 - }
17.398 -
17.399 -#ifndef MPI_AMD64_ADD
17.400 - MP_ADD_CARRY(a0, r0, r0, 0, carry);
17.401 - MP_ADD_CARRY(a1, r1, r1, carry, carry);
17.402 - MP_ADD_CARRY(a2, r2, r2, carry, carry);
17.403 - MP_ADD_CARRY(a3, r3, r3, carry, carry);
17.404 -#else
17.405 - __asm__ (
17.406 - "xorq %4,%4 \n\t"
17.407 - "addq %5,%0 \n\t"
17.408 - "adcq %6,%1 \n\t"
17.409 - "adcq %7,%2 \n\t"
17.410 - "adcq %8,%3 \n\t"
17.411 - "adcq $0,%4 \n\t"
17.412 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(carry)
17.413 - : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
17.414 - "0" (r0), "1" (r1), "2" (r2), "3" (r3)
17.415 - : "%cc" );
17.416 -#endif
17.417 -
17.418 - MP_CHECKOK(s_mp_pad(r, 4));
17.419 - MP_DIGIT(r, 3) = r3;
17.420 - MP_DIGIT(r, 2) = r2;
17.421 - MP_DIGIT(r, 1) = r1;
17.422 - MP_DIGIT(r, 0) = r0;
17.423 - MP_SIGN(r) = MP_ZPOS;
17.424 - MP_USED(r) = 4;
17.425 -
17.426 - /* Do quick 'subract' if we've gone over
17.427 - * (add the 2's complement of the curve field) */
17.428 - a3 = MP_DIGIT(&meth->irr,3);
17.429 - if (carry || r3 > a3 ||
17.430 - ((r3 == a3) && mp_cmp(r,&meth->irr) != MP_LT)) {
17.431 - a2 = MP_DIGIT(&meth->irr,2);
17.432 - a1 = MP_DIGIT(&meth->irr,1);
17.433 - a0 = MP_DIGIT(&meth->irr,0);
17.434 -#ifndef MPI_AMD64_ADD
17.435 - MP_SUB_BORROW(r0, a0, r0, 0, carry);
17.436 - MP_SUB_BORROW(r1, a1, r1, carry, carry);
17.437 - MP_SUB_BORROW(r2, a2, r2, carry, carry);
17.438 - MP_SUB_BORROW(r3, a3, r3, carry, carry);
17.439 -#else
17.440 - __asm__ (
17.441 - "subq %4,%0 \n\t"
17.442 - "sbbq %5,%1 \n\t"
17.443 - "sbbq %6,%2 \n\t"
17.444 - "sbbq %7,%3 \n\t"
17.445 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
17.446 - : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
17.447 - "0" (r0), "1" (r1), "2" (r2), "3" (r3)
17.448 - : "%cc" );
17.449 -#endif
17.450 - MP_DIGIT(r, 3) = r3;
17.451 - MP_DIGIT(r, 2) = r2;
17.452 - MP_DIGIT(r, 1) = r1;
17.453 - MP_DIGIT(r, 0) = r0;
17.454 - }
17.455 -
17.456 - s_mp_clamp(r);
17.457 -
17.458 - CLEANUP:
17.459 - return res;
17.460 -}
17.461 -
17.462 -/* 5 words */
17.463 -mp_err
17.464 -ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
17.465 - const GFMethod *meth)
17.466 -{
17.467 - mp_err res = MP_OKAY;
17.468 - mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0;
17.469 - mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
17.470 - mp_digit carry;
17.471 -
17.472 - switch(MP_USED(a)) {
17.473 - case 5:
17.474 - a4 = MP_DIGIT(a,4);
17.475 - case 4:
17.476 - a3 = MP_DIGIT(a,3);
17.477 - case 3:
17.478 - a2 = MP_DIGIT(a,2);
17.479 - case 2:
17.480 - a1 = MP_DIGIT(a,1);
17.481 - case 1:
17.482 - a0 = MP_DIGIT(a,0);
17.483 - }
17.484 - switch(MP_USED(b)) {
17.485 - case 5:
17.486 - r4 = MP_DIGIT(b,4);
17.487 - case 4:
17.488 - r3 = MP_DIGIT(b,3);
17.489 - case 3:
17.490 - r2 = MP_DIGIT(b,2);
17.491 - case 2:
17.492 - r1 = MP_DIGIT(b,1);
17.493 - case 1:
17.494 - r0 = MP_DIGIT(b,0);
17.495 - }
17.496 -
17.497 - MP_ADD_CARRY(a0, r0, r0, 0, carry);
17.498 - MP_ADD_CARRY(a1, r1, r1, carry, carry);
17.499 - MP_ADD_CARRY(a2, r2, r2, carry, carry);
17.500 - MP_ADD_CARRY(a3, r3, r3, carry, carry);
17.501 - MP_ADD_CARRY(a4, r4, r4, carry, carry);
17.502 -
17.503 - MP_CHECKOK(s_mp_pad(r, 5));
17.504 - MP_DIGIT(r, 4) = r4;
17.505 - MP_DIGIT(r, 3) = r3;
17.506 - MP_DIGIT(r, 2) = r2;
17.507 - MP_DIGIT(r, 1) = r1;
17.508 - MP_DIGIT(r, 0) = r0;
17.509 - MP_SIGN(r) = MP_ZPOS;
17.510 - MP_USED(r) = 5;
17.511 -
17.512 - /* Do quick 'subract' if we've gone over
17.513 - * (add the 2's complement of the curve field) */
17.514 - a4 = MP_DIGIT(&meth->irr,4);
17.515 - if (carry || r4 > a4 ||
17.516 - ((r4 == a4) && mp_cmp(r,&meth->irr) != MP_LT)) {
17.517 - a3 = MP_DIGIT(&meth->irr,3);
17.518 - a2 = MP_DIGIT(&meth->irr,2);
17.519 - a1 = MP_DIGIT(&meth->irr,1);
17.520 - a0 = MP_DIGIT(&meth->irr,0);
17.521 - MP_SUB_BORROW(r0, a0, r0, 0, carry);
17.522 - MP_SUB_BORROW(r1, a1, r1, carry, carry);
17.523 - MP_SUB_BORROW(r2, a2, r2, carry, carry);
17.524 - MP_SUB_BORROW(r3, a3, r3, carry, carry);
17.525 - MP_SUB_BORROW(r4, a4, r4, carry, carry);
17.526 - MP_DIGIT(r, 4) = r4;
17.527 - MP_DIGIT(r, 3) = r3;
17.528 - MP_DIGIT(r, 2) = r2;
17.529 - MP_DIGIT(r, 1) = r1;
17.530 - MP_DIGIT(r, 0) = r0;
17.531 - }
17.532 -
17.533 - s_mp_clamp(r);
17.534 -
17.535 - CLEANUP:
17.536 - return res;
17.537 -}
17.538 -
17.539 -/* 6 words */
17.540 -mp_err
17.541 -ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
17.542 - const GFMethod *meth)
17.543 -{
17.544 - mp_err res = MP_OKAY;
17.545 - mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0;
17.546 - mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
17.547 - mp_digit carry;
17.548 -
17.549 - switch(MP_USED(a)) {
17.550 - case 6:
17.551 - a5 = MP_DIGIT(a,5);
17.552 - case 5:
17.553 - a4 = MP_DIGIT(a,4);
17.554 - case 4:
17.555 - a3 = MP_DIGIT(a,3);
17.556 - case 3:
17.557 - a2 = MP_DIGIT(a,2);
17.558 - case 2:
17.559 - a1 = MP_DIGIT(a,1);
17.560 - case 1:
17.561 - a0 = MP_DIGIT(a,0);
17.562 - }
17.563 - switch(MP_USED(b)) {
17.564 - case 6:
17.565 - r5 = MP_DIGIT(b,5);
17.566 - case 5:
17.567 - r4 = MP_DIGIT(b,4);
17.568 - case 4:
17.569 - r3 = MP_DIGIT(b,3);
17.570 - case 3:
17.571 - r2 = MP_DIGIT(b,2);
17.572 - case 2:
17.573 - r1 = MP_DIGIT(b,1);
17.574 - case 1:
17.575 - r0 = MP_DIGIT(b,0);
17.576 - }
17.577 -
17.578 - MP_ADD_CARRY(a0, r0, r0, 0, carry);
17.579 - MP_ADD_CARRY(a1, r1, r1, carry, carry);
17.580 - MP_ADD_CARRY(a2, r2, r2, carry, carry);
17.581 - MP_ADD_CARRY(a3, r3, r3, carry, carry);
17.582 - MP_ADD_CARRY(a4, r4, r4, carry, carry);
17.583 - MP_ADD_CARRY(a5, r5, r5, carry, carry);
17.584 -
17.585 - MP_CHECKOK(s_mp_pad(r, 6));
17.586 - MP_DIGIT(r, 5) = r5;
17.587 - MP_DIGIT(r, 4) = r4;
17.588 - MP_DIGIT(r, 3) = r3;
17.589 - MP_DIGIT(r, 2) = r2;
17.590 - MP_DIGIT(r, 1) = r1;
17.591 - MP_DIGIT(r, 0) = r0;
17.592 - MP_SIGN(r) = MP_ZPOS;
17.593 - MP_USED(r) = 6;
17.594 -
17.595 - /* Do quick 'subract' if we've gone over
17.596 - * (add the 2's complement of the curve field) */
17.597 - a5 = MP_DIGIT(&meth->irr,5);
17.598 - if (carry || r5 > a5 ||
17.599 - ((r5 == a5) && mp_cmp(r,&meth->irr) != MP_LT)) {
17.600 - a4 = MP_DIGIT(&meth->irr,4);
17.601 - a3 = MP_DIGIT(&meth->irr,3);
17.602 - a2 = MP_DIGIT(&meth->irr,2);
17.603 - a1 = MP_DIGIT(&meth->irr,1);
17.604 - a0 = MP_DIGIT(&meth->irr,0);
17.605 - MP_SUB_BORROW(r0, a0, r0, 0, carry);
17.606 - MP_SUB_BORROW(r1, a1, r1, carry, carry);
17.607 - MP_SUB_BORROW(r2, a2, r2, carry, carry);
17.608 - MP_SUB_BORROW(r3, a3, r3, carry, carry);
17.609 - MP_SUB_BORROW(r4, a4, r4, carry, carry);
17.610 - MP_SUB_BORROW(r5, a5, r5, carry, carry);
17.611 - MP_DIGIT(r, 5) = r5;
17.612 - MP_DIGIT(r, 4) = r4;
17.613 - MP_DIGIT(r, 3) = r3;
17.614 - MP_DIGIT(r, 2) = r2;
17.615 - MP_DIGIT(r, 1) = r1;
17.616 - MP_DIGIT(r, 0) = r0;
17.617 - }
17.618 -
17.619 - s_mp_clamp(r);
17.620 -
17.621 - CLEANUP:
17.622 - return res;
17.623 -}
17.624 -
17.625 -/*
17.626 - * The following subraction functions do in-line subractions based
17.627 - * on our curve size.
17.628 - *
17.629 - * ... 3 words
17.630 - */
17.631 -mp_err
17.632 -ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
17.633 - const GFMethod *meth)
17.634 -{
17.635 - mp_err res = MP_OKAY;
17.636 - mp_digit b0 = 0, b1 = 0, b2 = 0;
17.637 - mp_digit r0 = 0, r1 = 0, r2 = 0;
17.638 - mp_digit borrow;
17.639 -
17.640 - switch(MP_USED(a)) {
17.641 - case 3:
17.642 - r2 = MP_DIGIT(a,2);
17.643 - case 2:
17.644 - r1 = MP_DIGIT(a,1);
17.645 - case 1:
17.646 - r0 = MP_DIGIT(a,0);
17.647 - }
17.648 - switch(MP_USED(b)) {
17.649 - case 3:
17.650 - b2 = MP_DIGIT(b,2);
17.651 - case 2:
17.652 - b1 = MP_DIGIT(b,1);
17.653 - case 1:
17.654 - b0 = MP_DIGIT(b,0);
17.655 - }
17.656 -
17.657 -#ifndef MPI_AMD64_ADD
17.658 - MP_SUB_BORROW(r0, b0, r0, 0, borrow);
17.659 - MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
17.660 - MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
17.661 -#else
17.662 - __asm__ (
17.663 - "xorq %3,%3 \n\t"
17.664 - "subq %4,%0 \n\t"
17.665 - "sbbq %5,%1 \n\t"
17.666 - "sbbq %6,%2 \n\t"
17.667 - "adcq $0,%3 \n\t"
17.668 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r" (borrow)
17.669 - : "r" (b0), "r" (b1), "r" (b2),
17.670 - "0" (r0), "1" (r1), "2" (r2)
17.671 - : "%cc" );
17.672 -#endif
17.673 -
17.674 - /* Do quick 'add' if we've gone under 0
17.675 - * (subtract the 2's complement of the curve field) */
17.676 - if (borrow) {
17.677 - b2 = MP_DIGIT(&meth->irr,2);
17.678 - b1 = MP_DIGIT(&meth->irr,1);
17.679 - b0 = MP_DIGIT(&meth->irr,0);
17.680 -#ifndef MPI_AMD64_ADD
17.681 - MP_ADD_CARRY(b0, r0, r0, 0, borrow);
17.682 - MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
17.683 - MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
17.684 -#else
17.685 - __asm__ (
17.686 - "addq %3,%0 \n\t"
17.687 - "adcq %4,%1 \n\t"
17.688 - "adcq %5,%2 \n\t"
17.689 - : "=r"(r0), "=r"(r1), "=r"(r2)
17.690 - : "r" (b0), "r" (b1), "r" (b2),
17.691 - "0" (r0), "1" (r1), "2" (r2)
17.692 - : "%cc" );
17.693 -#endif
17.694 - }
17.695 -
17.696 -#ifdef MPI_AMD64_ADD
17.697 - /* compiler fakeout? */
17.698 - if ((r2 == b0) && (r1 == b0) && (r0 == b0)) {
17.699 - MP_CHECKOK(s_mp_pad(r, 4));
17.700 - }
17.701 -#endif
17.702 - MP_CHECKOK(s_mp_pad(r, 3));
17.703 - MP_DIGIT(r, 2) = r2;
17.704 - MP_DIGIT(r, 1) = r1;
17.705 - MP_DIGIT(r, 0) = r0;
17.706 - MP_SIGN(r) = MP_ZPOS;
17.707 - MP_USED(r) = 3;
17.708 - s_mp_clamp(r);
17.709 -
17.710 - CLEANUP:
17.711 - return res;
17.712 -}
17.713 -
17.714 -/* 4 words */
17.715 -mp_err
17.716 -ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
17.717 - const GFMethod *meth)
17.718 -{
17.719 - mp_err res = MP_OKAY;
17.720 - mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0;
17.721 - mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
17.722 - mp_digit borrow;
17.723 -
17.724 - switch(MP_USED(a)) {
17.725 - case 4:
17.726 - r3 = MP_DIGIT(a,3);
17.727 - case 3:
17.728 - r2 = MP_DIGIT(a,2);
17.729 - case 2:
17.730 - r1 = MP_DIGIT(a,1);
17.731 - case 1:
17.732 - r0 = MP_DIGIT(a,0);
17.733 - }
17.734 - switch(MP_USED(b)) {
17.735 - case 4:
17.736 - b3 = MP_DIGIT(b,3);
17.737 - case 3:
17.738 - b2 = MP_DIGIT(b,2);
17.739 - case 2:
17.740 - b1 = MP_DIGIT(b,1);
17.741 - case 1:
17.742 - b0 = MP_DIGIT(b,0);
17.743 - }
17.744 -
17.745 -#ifndef MPI_AMD64_ADD
17.746 - MP_SUB_BORROW(r0, b0, r0, 0, borrow);
17.747 - MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
17.748 - MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
17.749 - MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
17.750 -#else
17.751 - __asm__ (
17.752 - "xorq %4,%4 \n\t"
17.753 - "subq %5,%0 \n\t"
17.754 - "sbbq %6,%1 \n\t"
17.755 - "sbbq %7,%2 \n\t"
17.756 - "sbbq %8,%3 \n\t"
17.757 - "adcq $0,%4 \n\t"
17.758 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r" (borrow)
17.759 - : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
17.760 - "0" (r0), "1" (r1), "2" (r2), "3" (r3)
17.761 - : "%cc" );
17.762 -#endif
17.763 -
17.764 - /* Do quick 'add' if we've gone under 0
17.765 - * (subtract the 2's complement of the curve field) */
17.766 - if (borrow) {
17.767 - b3 = MP_DIGIT(&meth->irr,3);
17.768 - b2 = MP_DIGIT(&meth->irr,2);
17.769 - b1 = MP_DIGIT(&meth->irr,1);
17.770 - b0 = MP_DIGIT(&meth->irr,0);
17.771 -#ifndef MPI_AMD64_ADD
17.772 - MP_ADD_CARRY(b0, r0, r0, 0, borrow);
17.773 - MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
17.774 - MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
17.775 - MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
17.776 -#else
17.777 - __asm__ (
17.778 - "addq %4,%0 \n\t"
17.779 - "adcq %5,%1 \n\t"
17.780 - "adcq %6,%2 \n\t"
17.781 - "adcq %7,%3 \n\t"
17.782 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
17.783 - : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
17.784 - "0" (r0), "1" (r1), "2" (r2), "3" (r3)
17.785 - : "%cc" );
17.786 -#endif
17.787 - }
17.788 -#ifdef MPI_AMD64_ADD
17.789 - /* compiler fakeout? */
17.790 - if ((r3 == b0) && (r1 == b0) && (r0 == b0)) {
17.791 - MP_CHECKOK(s_mp_pad(r, 4));
17.792 - }
17.793 -#endif
17.794 - MP_CHECKOK(s_mp_pad(r, 4));
17.795 - MP_DIGIT(r, 3) = r3;
17.796 - MP_DIGIT(r, 2) = r2;
17.797 - MP_DIGIT(r, 1) = r1;
17.798 - MP_DIGIT(r, 0) = r0;
17.799 - MP_SIGN(r) = MP_ZPOS;
17.800 - MP_USED(r) = 4;
17.801 - s_mp_clamp(r);
17.802 -
17.803 - CLEANUP:
17.804 - return res;
17.805 -}
17.806 -
17.807 -/* 5 words */
17.808 -mp_err
17.809 -ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
17.810 - const GFMethod *meth)
17.811 -{
17.812 - mp_err res = MP_OKAY;
17.813 - mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0;
17.814 - mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
17.815 - mp_digit borrow;
17.816 -
17.817 - switch(MP_USED(a)) {
17.818 - case 5:
17.819 - r4 = MP_DIGIT(a,4);
17.820 - case 4:
17.821 - r3 = MP_DIGIT(a,3);
17.822 - case 3:
17.823 - r2 = MP_DIGIT(a,2);
17.824 - case 2:
17.825 - r1 = MP_DIGIT(a,1);
17.826 - case 1:
17.827 - r0 = MP_DIGIT(a,0);
17.828 - }
17.829 - switch(MP_USED(b)) {
17.830 - case 5:
17.831 - b4 = MP_DIGIT(b,4);
17.832 - case 4:
17.833 - b3 = MP_DIGIT(b,3);
17.834 - case 3:
17.835 - b2 = MP_DIGIT(b,2);
17.836 - case 2:
17.837 - b1 = MP_DIGIT(b,1);
17.838 - case 1:
17.839 - b0 = MP_DIGIT(b,0);
17.840 - }
17.841 -
17.842 - MP_SUB_BORROW(r0, b0, r0, 0, borrow);
17.843 - MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
17.844 - MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
17.845 - MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
17.846 - MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
17.847 -
17.848 - /* Do quick 'add' if we've gone under 0
17.849 - * (subtract the 2's complement of the curve field) */
17.850 - if (borrow) {
17.851 - b4 = MP_DIGIT(&meth->irr,4);
17.852 - b3 = MP_DIGIT(&meth->irr,3);
17.853 - b2 = MP_DIGIT(&meth->irr,2);
17.854 - b1 = MP_DIGIT(&meth->irr,1);
17.855 - b0 = MP_DIGIT(&meth->irr,0);
17.856 - MP_ADD_CARRY(b0, r0, r0, 0, borrow);
17.857 - MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
17.858 - MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
17.859 - MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
17.860 - }
17.861 - MP_CHECKOK(s_mp_pad(r, 5));
17.862 - MP_DIGIT(r, 4) = r4;
17.863 - MP_DIGIT(r, 3) = r3;
17.864 - MP_DIGIT(r, 2) = r2;
17.865 - MP_DIGIT(r, 1) = r1;
17.866 - MP_DIGIT(r, 0) = r0;
17.867 - MP_SIGN(r) = MP_ZPOS;
17.868 - MP_USED(r) = 5;
17.869 - s_mp_clamp(r);
17.870 -
17.871 - CLEANUP:
17.872 - return res;
17.873 -}
17.874 -
17.875 -/* 6 words */
17.876 -mp_err
17.877 -ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
17.878 - const GFMethod *meth)
17.879 -{
17.880 - mp_err res = MP_OKAY;
17.881 - mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0;
17.882 - mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
17.883 - mp_digit borrow;
17.884 -
17.885 - switch(MP_USED(a)) {
17.886 - case 6:
17.887 - r5 = MP_DIGIT(a,5);
17.888 - case 5:
17.889 - r4 = MP_DIGIT(a,4);
17.890 - case 4:
17.891 - r3 = MP_DIGIT(a,3);
17.892 - case 3:
17.893 - r2 = MP_DIGIT(a,2);
17.894 - case 2:
17.895 - r1 = MP_DIGIT(a,1);
17.896 - case 1:
17.897 - r0 = MP_DIGIT(a,0);
17.898 - }
17.899 - switch(MP_USED(b)) {
17.900 - case 6:
17.901 - b5 = MP_DIGIT(b,5);
17.902 - case 5:
17.903 - b4 = MP_DIGIT(b,4);
17.904 - case 4:
17.905 - b3 = MP_DIGIT(b,3);
17.906 - case 3:
17.907 - b2 = MP_DIGIT(b,2);
17.908 - case 2:
17.909 - b1 = MP_DIGIT(b,1);
17.910 - case 1:
17.911 - b0 = MP_DIGIT(b,0);
17.912 - }
17.913 -
17.914 - MP_SUB_BORROW(r0, b0, r0, 0, borrow);
17.915 - MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
17.916 - MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
17.917 - MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
17.918 - MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
17.919 - MP_SUB_BORROW(r5, b5, r5, borrow, borrow);
17.920 -
17.921 - /* Do quick 'add' if we've gone under 0
17.922 - * (subtract the 2's complement of the curve field) */
17.923 - if (borrow) {
17.924 - b5 = MP_DIGIT(&meth->irr,5);
17.925 - b4 = MP_DIGIT(&meth->irr,4);
17.926 - b3 = MP_DIGIT(&meth->irr,3);
17.927 - b2 = MP_DIGIT(&meth->irr,2);
17.928 - b1 = MP_DIGIT(&meth->irr,1);
17.929 - b0 = MP_DIGIT(&meth->irr,0);
17.930 - MP_ADD_CARRY(b0, r0, r0, 0, borrow);
17.931 - MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
17.932 - MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
17.933 - MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
17.934 - MP_ADD_CARRY(b4, r4, r4, borrow, borrow);
17.935 - }
17.936 -
17.937 - MP_CHECKOK(s_mp_pad(r, 6));
17.938 - MP_DIGIT(r, 5) = r5;
17.939 - MP_DIGIT(r, 4) = r4;
17.940 - MP_DIGIT(r, 3) = r3;
17.941 - MP_DIGIT(r, 2) = r2;
17.942 - MP_DIGIT(r, 1) = r1;
17.943 - MP_DIGIT(r, 0) = r0;
17.944 - MP_SIGN(r) = MP_ZPOS;
17.945 - MP_USED(r) = 6;
17.946 - s_mp_clamp(r);
17.947 -
17.948 - CLEANUP:
17.949 - return res;
17.950 -}
17.951 -
17.952 -
17.953 -/* Reduces an integer to a field element. */
17.954 -mp_err
17.955 -ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
17.956 -{
17.957 - return mp_mod(a, &meth->irr, r);
17.958 -}
17.959 -
17.960 -/* Multiplies two field elements. */
17.961 -mp_err
17.962 -ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
17.963 - const GFMethod *meth)
17.964 -{
17.965 - return mp_mulmod(a, b, &meth->irr, r);
17.966 -}
17.967 -
17.968 -/* Squares a field element. */
17.969 -mp_err
17.970 -ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
17.971 -{
17.972 - return mp_sqrmod(a, &meth->irr, r);
17.973 -}
17.974 -
17.975 -/* Divides two field elements. If a is NULL, then returns the inverse of
17.976 - * b. */
17.977 -mp_err
17.978 -ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
17.979 - const GFMethod *meth)
17.980 -{
17.981 - mp_err res = MP_OKAY;
17.982 - mp_int t;
17.983 -
17.984 - /* If a is NULL, then return the inverse of b, otherwise return a/b. */
17.985 - if (a == NULL) {
17.986 - return mp_invmod(b, &meth->irr, r);
17.987 - } else {
17.988 - /* MPI doesn't support divmod, so we implement it using invmod and
17.989 - * mulmod. */
17.990 - MP_CHECKOK(mp_init(&t, FLAG(b)));
17.991 - MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
17.992 - MP_CHECKOK(mp_mulmod(a, &t, &meth->irr, r));
17.993 - CLEANUP:
17.994 - mp_clear(&t);
17.995 - return res;
17.996 - }
17.997 -}
17.998 -
17.999 -/* Wrapper functions for generic binary polynomial field arithmetic. */
17.1000 -
17.1001 -/* Adds two field elements. */
17.1002 -mp_err
17.1003 -ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
17.1004 - const GFMethod *meth)
17.1005 -{
17.1006 - return mp_badd(a, b, r);
17.1007 -}
17.1008 -
17.1009 -/* Negates a field element. Note that for binary polynomial fields, the
17.1010 - * negation of a field element is the field element itself. */
17.1011 -mp_err
17.1012 -ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
17.1013 -{
17.1014 - if (a == r) {
17.1015 - return MP_OKAY;
17.1016 - } else {
17.1017 - return mp_copy(a, r);
17.1018 - }
17.1019 -}
17.1020 -
17.1021 -/* Reduces a binary polynomial to a field element. */
17.1022 -mp_err
17.1023 -ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
17.1024 -{
17.1025 - return mp_bmod(a, meth->irr_arr, r);
17.1026 -}
17.1027 -
17.1028 -/* Multiplies two field elements. */
17.1029 -mp_err
17.1030 -ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
17.1031 - const GFMethod *meth)
17.1032 -{
17.1033 - return mp_bmulmod(a, b, meth->irr_arr, r);
17.1034 -}
17.1035 -
17.1036 -/* Squares a field element. */
17.1037 -mp_err
17.1038 -ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
17.1039 -{
17.1040 - return mp_bsqrmod(a, meth->irr_arr, r);
17.1041 -}
17.1042 -
17.1043 -/* Divides two field elements. If a is NULL, then returns the inverse of
17.1044 - * b. */
17.1045 -mp_err
17.1046 -ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
17.1047 - const GFMethod *meth)
17.1048 -{
17.1049 - mp_err res = MP_OKAY;
17.1050 - mp_int t;
17.1051 -
17.1052 - /* If a is NULL, then return the inverse of b, otherwise return a/b. */
17.1053 - if (a == NULL) {
17.1054 - /* The GF(2^m) portion of MPI doesn't support invmod, so we
17.1055 - * compute 1/b. */
17.1056 - MP_CHECKOK(mp_init(&t, FLAG(b)));
17.1057 - MP_CHECKOK(mp_set_int(&t, 1));
17.1058 - MP_CHECKOK(mp_bdivmod(&t, b, &meth->irr, meth->irr_arr, r));
17.1059 - CLEANUP:
17.1060 - mp_clear(&t);
17.1061 - return res;
17.1062 - } else {
17.1063 - return mp_bdivmod(a, b, &meth->irr, meth->irr_arr, r);
17.1064 - }
17.1065 -}
18.1 --- a/src/share/native/sun/security/ec/ecl_mult.c Tue Oct 13 15:25:58 2009 -0700
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,378 +0,0 @@
18.4 -/* *********************************************************************
18.5 - *
18.6 - * Sun elects to have this file available under and governed by the
18.7 - * Mozilla Public License Version 1.1 ("MPL") (see
18.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
18.9 - * of doubt and subject to the following, Sun also elects to allow
18.10 - * licensees to use this file under the MPL, the GNU General Public
18.11 - * License version 2 only or the Lesser General Public License version
18.12 - * 2.1 only. Any references to the "GNU General Public License version 2
18.13 - * or later" or "GPL" in the following shall be construed to mean the
18.14 - * GNU General Public License version 2 only. Any references to the "GNU
18.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
18.16 - * following shall be construed to mean the GNU Lesser General Public
18.17 - * License version 2.1 only. However, the following notice accompanied
18.18 - * the original version of this file:
18.19 - *
18.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
18.21 - *
18.22 - * The contents of this file are subject to the Mozilla Public License Version
18.23 - * 1.1 (the "License"); you may not use this file except in compliance with
18.24 - * the License. You may obtain a copy of the License at
18.25 - * http://www.mozilla.org/MPL/
18.26 - *
18.27 - * Software distributed under the License is distributed on an "AS IS" basis,
18.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
18.29 - * for the specific language governing rights and limitations under the
18.30 - * License.
18.31 - *
18.32 - * The Original Code is the elliptic curve math library.
18.33 - *
18.34 - * The Initial Developer of the Original Code is
18.35 - * Sun Microsystems, Inc.
18.36 - * Portions created by the Initial Developer are Copyright (C) 2003
18.37 - * the Initial Developer. All Rights Reserved.
18.38 - *
18.39 - * Contributor(s):
18.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
18.41 - *
18.42 - * Alternatively, the contents of this file may be used under the terms of
18.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
18.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
18.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
18.46 - * of those above. If you wish to allow use of your version of this file only
18.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
18.48 - * use your version of this file under the terms of the MPL, indicate your
18.49 - * decision by deleting the provisions above and replace them with the notice
18.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
18.51 - * the provisions above, a recipient may use your version of this file under
18.52 - * the terms of any one of the MPL, the GPL or the LGPL.
18.53 - *
18.54 - *********************************************************************** */
18.55 -/*
18.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
18.57 - * Use is subject to license terms.
18.58 - */
18.59 -
18.60 -#pragma ident "%Z%%M% %I% %E% SMI"
18.61 -
18.62 -#include "mpi.h"
18.63 -#include "mplogic.h"
18.64 -#include "ecl.h"
18.65 -#include "ecl-priv.h"
18.66 -#ifndef _KERNEL
18.67 -#include <stdlib.h>
18.68 -#endif
18.69 -
18.70 -/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x,
18.71 - * y). If x, y = NULL, then P is assumed to be the generator (base point)
18.72 - * of the group of points on the elliptic curve. Input and output values
18.73 - * are assumed to be NOT field-encoded. */
18.74 -mp_err
18.75 -ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
18.76 - const mp_int *py, mp_int *rx, mp_int *ry)
18.77 -{
18.78 - mp_err res = MP_OKAY;
18.79 - mp_int kt;
18.80 -
18.81 - ARGCHK((k != NULL) && (group != NULL), MP_BADARG);
18.82 - MP_DIGITS(&kt) = 0;
18.83 -
18.84 - /* want scalar to be less than or equal to group order */
18.85 - if (mp_cmp(k, &group->order) > 0) {
18.86 - MP_CHECKOK(mp_init(&kt, FLAG(k)));
18.87 - MP_CHECKOK(mp_mod(k, &group->order, &kt));
18.88 - } else {
18.89 - MP_SIGN(&kt) = MP_ZPOS;
18.90 - MP_USED(&kt) = MP_USED(k);
18.91 - MP_ALLOC(&kt) = MP_ALLOC(k);
18.92 - MP_DIGITS(&kt) = MP_DIGITS(k);
18.93 - }
18.94 -
18.95 - if ((px == NULL) || (py == NULL)) {
18.96 - if (group->base_point_mul) {
18.97 - MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group));
18.98 - } else {
18.99 - MP_CHECKOK(group->
18.100 - point_mul(&kt, &group->genx, &group->geny, rx, ry,
18.101 - group));
18.102 - }
18.103 - } else {
18.104 - if (group->meth->field_enc) {
18.105 - MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
18.106 - MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
18.107 - MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
18.108 - } else {
18.109 - MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
18.110 - }
18.111 - }
18.112 - if (group->meth->field_dec) {
18.113 - MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
18.114 - MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
18.115 - }
18.116 -
18.117 - CLEANUP:
18.118 - if (MP_DIGITS(&kt) != MP_DIGITS(k)) {
18.119 - mp_clear(&kt);
18.120 - }
18.121 - return res;
18.122 -}
18.123 -
18.124 -/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
18.125 - * k2 * P(x, y), where G is the generator (base point) of the group of
18.126 - * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
18.127 - * Input and output values are assumed to be NOT field-encoded. */
18.128 -mp_err
18.129 -ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
18.130 - const mp_int *py, mp_int *rx, mp_int *ry,
18.131 - const ECGroup *group)
18.132 -{
18.133 - mp_err res = MP_OKAY;
18.134 - mp_int sx, sy;
18.135 -
18.136 - ARGCHK(group != NULL, MP_BADARG);
18.137 - ARGCHK(!((k1 == NULL)
18.138 - && ((k2 == NULL) || (px == NULL)
18.139 - || (py == NULL))), MP_BADARG);
18.140 -
18.141 - /* if some arguments are not defined used ECPoint_mul */
18.142 - if (k1 == NULL) {
18.143 - return ECPoint_mul(group, k2, px, py, rx, ry);
18.144 - } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
18.145 - return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
18.146 - }
18.147 -
18.148 - MP_DIGITS(&sx) = 0;
18.149 - MP_DIGITS(&sy) = 0;
18.150 - MP_CHECKOK(mp_init(&sx, FLAG(k1)));
18.151 - MP_CHECKOK(mp_init(&sy, FLAG(k1)));
18.152 -
18.153 - MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy));
18.154 - MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry));
18.155 -
18.156 - if (group->meth->field_enc) {
18.157 - MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth));
18.158 - MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth));
18.159 - MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth));
18.160 - MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth));
18.161 - }
18.162 -
18.163 - MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group));
18.164 -
18.165 - if (group->meth->field_dec) {
18.166 - MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
18.167 - MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
18.168 - }
18.169 -
18.170 - CLEANUP:
18.171 - mp_clear(&sx);
18.172 - mp_clear(&sy);
18.173 - return res;
18.174 -}
18.175 -
18.176 -/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
18.177 - * k2 * P(x, y), where G is the generator (base point) of the group of
18.178 - * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
18.179 - * Input and output values are assumed to be NOT field-encoded. Uses
18.180 - * algorithm 15 (simultaneous multiple point multiplication) from Brown,
18.181 - * Hankerson, Lopez, Menezes. Software Implementation of the NIST
18.182 - * Elliptic Curves over Prime Fields. */
18.183 -mp_err
18.184 -ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
18.185 - const mp_int *py, mp_int *rx, mp_int *ry,
18.186 - const ECGroup *group)
18.187 -{
18.188 - mp_err res = MP_OKAY;
18.189 - mp_int precomp[4][4][2];
18.190 - const mp_int *a, *b;
18.191 - int i, j;
18.192 - int ai, bi, d;
18.193 -
18.194 - ARGCHK(group != NULL, MP_BADARG);
18.195 - ARGCHK(!((k1 == NULL)
18.196 - && ((k2 == NULL) || (px == NULL)
18.197 - || (py == NULL))), MP_BADARG);
18.198 -
18.199 - /* if some arguments are not defined used ECPoint_mul */
18.200 - if (k1 == NULL) {
18.201 - return ECPoint_mul(group, k2, px, py, rx, ry);
18.202 - } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
18.203 - return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
18.204 - }
18.205 -
18.206 - /* initialize precomputation table */
18.207 - for (i = 0; i < 4; i++) {
18.208 - for (j = 0; j < 4; j++) {
18.209 - MP_DIGITS(&precomp[i][j][0]) = 0;
18.210 - MP_DIGITS(&precomp[i][j][1]) = 0;
18.211 - }
18.212 - }
18.213 - for (i = 0; i < 4; i++) {
18.214 - for (j = 0; j < 4; j++) {
18.215 - MP_CHECKOK( mp_init_size(&precomp[i][j][0],
18.216 - ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) );
18.217 - MP_CHECKOK( mp_init_size(&precomp[i][j][1],
18.218 - ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) );
18.219 - }
18.220 - }
18.221 -
18.222 - /* fill precomputation table */
18.223 - /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
18.224 - if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
18.225 - a = k2;
18.226 - b = k1;
18.227 - if (group->meth->field_enc) {
18.228 - MP_CHECKOK(group->meth->
18.229 - field_enc(px, &precomp[1][0][0], group->meth));
18.230 - MP_CHECKOK(group->meth->
18.231 - field_enc(py, &precomp[1][0][1], group->meth));
18.232 - } else {
18.233 - MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
18.234 - MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
18.235 - }
18.236 - MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
18.237 - MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
18.238 - } else {
18.239 - a = k1;
18.240 - b = k2;
18.241 - MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
18.242 - MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
18.243 - if (group->meth->field_enc) {
18.244 - MP_CHECKOK(group->meth->
18.245 - field_enc(px, &precomp[0][1][0], group->meth));
18.246 - MP_CHECKOK(group->meth->
18.247 - field_enc(py, &precomp[0][1][1], group->meth));
18.248 - } else {
18.249 - MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
18.250 - MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
18.251 - }
18.252 - }
18.253 - /* precompute [*][0][*] */
18.254 - mp_zero(&precomp[0][0][0]);
18.255 - mp_zero(&precomp[0][0][1]);
18.256 - MP_CHECKOK(group->
18.257 - point_dbl(&precomp[1][0][0], &precomp[1][0][1],
18.258 - &precomp[2][0][0], &precomp[2][0][1], group));
18.259 - MP_CHECKOK(group->
18.260 - point_add(&precomp[1][0][0], &precomp[1][0][1],
18.261 - &precomp[2][0][0], &precomp[2][0][1],
18.262 - &precomp[3][0][0], &precomp[3][0][1], group));
18.263 - /* precompute [*][1][*] */
18.264 - for (i = 1; i < 4; i++) {
18.265 - MP_CHECKOK(group->
18.266 - point_add(&precomp[0][1][0], &precomp[0][1][1],
18.267 - &precomp[i][0][0], &precomp[i][0][1],
18.268 - &precomp[i][1][0], &precomp[i][1][1], group));
18.269 - }
18.270 - /* precompute [*][2][*] */
18.271 - MP_CHECKOK(group->
18.272 - point_dbl(&precomp[0][1][0], &precomp[0][1][1],
18.273 - &precomp[0][2][0], &precomp[0][2][1], group));
18.274 - for (i = 1; i < 4; i++) {
18.275 - MP_CHECKOK(group->
18.276 - point_add(&precomp[0][2][0], &precomp[0][2][1],
18.277 - &precomp[i][0][0], &precomp[i][0][1],
18.278 - &precomp[i][2][0], &precomp[i][2][1], group));
18.279 - }
18.280 - /* precompute [*][3][*] */
18.281 - MP_CHECKOK(group->
18.282 - point_add(&precomp[0][1][0], &precomp[0][1][1],
18.283 - &precomp[0][2][0], &precomp[0][2][1],
18.284 - &precomp[0][3][0], &precomp[0][3][1], group));
18.285 - for (i = 1; i < 4; i++) {
18.286 - MP_CHECKOK(group->
18.287 - point_add(&precomp[0][3][0], &precomp[0][3][1],
18.288 - &precomp[i][0][0], &precomp[i][0][1],
18.289 - &precomp[i][3][0], &precomp[i][3][1], group));
18.290 - }
18.291 -
18.292 - d = (mpl_significant_bits(a) + 1) / 2;
18.293 -
18.294 - /* R = inf */
18.295 - mp_zero(rx);
18.296 - mp_zero(ry);
18.297 -
18.298 - for (i = d - 1; i >= 0; i--) {
18.299 - ai = MP_GET_BIT(a, 2 * i + 1);
18.300 - ai <<= 1;
18.301 - ai |= MP_GET_BIT(a, 2 * i);
18.302 - bi = MP_GET_BIT(b, 2 * i + 1);
18.303 - bi <<= 1;
18.304 - bi |= MP_GET_BIT(b, 2 * i);
18.305 - /* R = 2^2 * R */
18.306 - MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
18.307 - MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
18.308 - /* R = R + (ai * A + bi * B) */
18.309 - MP_CHECKOK(group->
18.310 - point_add(rx, ry, &precomp[ai][bi][0],
18.311 - &precomp[ai][bi][1], rx, ry, group));
18.312 - }
18.313 -
18.314 - if (group->meth->field_dec) {
18.315 - MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
18.316 - MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
18.317 - }
18.318 -
18.319 - CLEANUP:
18.320 - for (i = 0; i < 4; i++) {
18.321 - for (j = 0; j < 4; j++) {
18.322 - mp_clear(&precomp[i][j][0]);
18.323 - mp_clear(&precomp[i][j][1]);
18.324 - }
18.325 - }
18.326 - return res;
18.327 -}
18.328 -
18.329 -/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
18.330 - * k2 * P(x, y), where G is the generator (base point) of the group of
18.331 - * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
18.332 - * Input and output values are assumed to be NOT field-encoded. */
18.333 -mp_err
18.334 -ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
18.335 - const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry)
18.336 -{
18.337 - mp_err res = MP_OKAY;
18.338 - mp_int k1t, k2t;
18.339 - const mp_int *k1p, *k2p;
18.340 -
18.341 - MP_DIGITS(&k1t) = 0;
18.342 - MP_DIGITS(&k2t) = 0;
18.343 -
18.344 - ARGCHK(group != NULL, MP_BADARG);
18.345 -
18.346 - /* want scalar to be less than or equal to group order */
18.347 - if (k1 != NULL) {
18.348 - if (mp_cmp(k1, &group->order) >= 0) {
18.349 - MP_CHECKOK(mp_init(&k1t, FLAG(k1)));
18.350 - MP_CHECKOK(mp_mod(k1, &group->order, &k1t));
18.351 - k1p = &k1t;
18.352 - } else {
18.353 - k1p = k1;
18.354 - }
18.355 - } else {
18.356 - k1p = k1;
18.357 - }
18.358 - if (k2 != NULL) {
18.359 - if (mp_cmp(k2, &group->order) >= 0) {
18.360 - MP_CHECKOK(mp_init(&k2t, FLAG(k2)));
18.361 - MP_CHECKOK(mp_mod(k2, &group->order, &k2t));
18.362 - k2p = &k2t;
18.363 - } else {
18.364 - k2p = k2;
18.365 - }
18.366 - } else {
18.367 - k2p = k2;
18.368 - }
18.369 -
18.370 - /* if points_mul is defined, then use it */
18.371 - if (group->points_mul) {
18.372 - res = group->points_mul(k1p, k2p, px, py, rx, ry, group);
18.373 - } else {
18.374 - res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
18.375 - }
18.376 -
18.377 - CLEANUP:
18.378 - mp_clear(&k1t);
18.379 - mp_clear(&k2t);
18.380 - return res;
18.381 -}
19.1 --- a/src/share/native/sun/security/ec/ecp.h Tue Oct 13 15:25:58 2009 -0700
19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3 @@ -1,160 +0,0 @@
19.4 -/* *********************************************************************
19.5 - *
19.6 - * Sun elects to have this file available under and governed by the
19.7 - * Mozilla Public License Version 1.1 ("MPL") (see
19.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
19.9 - * of doubt and subject to the following, Sun also elects to allow
19.10 - * licensees to use this file under the MPL, the GNU General Public
19.11 - * License version 2 only or the Lesser General Public License version
19.12 - * 2.1 only. Any references to the "GNU General Public License version 2
19.13 - * or later" or "GPL" in the following shall be construed to mean the
19.14 - * GNU General Public License version 2 only. Any references to the "GNU
19.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
19.16 - * following shall be construed to mean the GNU Lesser General Public
19.17 - * License version 2.1 only. However, the following notice accompanied
19.18 - * the original version of this file:
19.19 - *
19.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
19.21 - *
19.22 - * The contents of this file are subject to the Mozilla Public License Version
19.23 - * 1.1 (the "License"); you may not use this file except in compliance with
19.24 - * the License. You may obtain a copy of the License at
19.25 - * http://www.mozilla.org/MPL/
19.26 - *
19.27 - * Software distributed under the License is distributed on an "AS IS" basis,
19.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19.29 - * for the specific language governing rights and limitations under the
19.30 - * License.
19.31 - *
19.32 - * The Original Code is the elliptic curve math library for prime field curves.
19.33 - *
19.34 - * The Initial Developer of the Original Code is
19.35 - * Sun Microsystems, Inc.
19.36 - * Portions created by the Initial Developer are Copyright (C) 2003
19.37 - * the Initial Developer. All Rights Reserved.
19.38 - *
19.39 - * Contributor(s):
19.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
19.41 - *
19.42 - * Alternatively, the contents of this file may be used under the terms of
19.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
19.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
19.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
19.46 - * of those above. If you wish to allow use of your version of this file only
19.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
19.48 - * use your version of this file under the terms of the MPL, indicate your
19.49 - * decision by deleting the provisions above and replace them with the notice
19.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
19.51 - * the provisions above, a recipient may use your version of this file under
19.52 - * the terms of any one of the MPL, the GPL or the LGPL.
19.53 - *
19.54 - *********************************************************************** */
19.55 -/*
19.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
19.57 - * Use is subject to license terms.
19.58 - */
19.59 -
19.60 -#ifndef _ECP_H
19.61 -#define _ECP_H
19.62 -
19.63 -#pragma ident "%Z%%M% %I% %E% SMI"
19.64 -
19.65 -#include "ecl-priv.h"
19.66 -
19.67 -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
19.68 -mp_err ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py);
19.69 -
19.70 -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
19.71 -mp_err ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py);
19.72 -
19.73 -/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
19.74 - * qy). Uses affine coordinates. */
19.75 -mp_err ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py,
19.76 - const mp_int *qx, const mp_int *qy, mp_int *rx,
19.77 - mp_int *ry, const ECGroup *group);
19.78 -
19.79 -/* Computes R = P - Q. Uses affine coordinates. */
19.80 -mp_err ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py,
19.81 - const mp_int *qx, const mp_int *qy, mp_int *rx,
19.82 - mp_int *ry, const ECGroup *group);
19.83 -
19.84 -/* Computes R = 2P. Uses affine coordinates. */
19.85 -mp_err ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
19.86 - mp_int *ry, const ECGroup *group);
19.87 -
19.88 -/* Validates a point on a GFp curve. */
19.89 -mp_err ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
19.90 -
19.91 -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
19.92 -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
19.93 - * a, b and p are the elliptic curve coefficients and the prime that
19.94 - * determines the field GFp. Uses affine coordinates. */
19.95 -mp_err ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px,
19.96 - const mp_int *py, mp_int *rx, mp_int *ry,
19.97 - const ECGroup *group);
19.98 -#endif
19.99 -
19.100 -/* Converts a point P(px, py) from affine coordinates to Jacobian
19.101 - * projective coordinates R(rx, ry, rz). */
19.102 -mp_err ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
19.103 - mp_int *ry, mp_int *rz, const ECGroup *group);
19.104 -
19.105 -/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
19.106 - * affine coordinates R(rx, ry). */
19.107 -mp_err ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py,
19.108 - const mp_int *pz, mp_int *rx, mp_int *ry,
19.109 - const ECGroup *group);
19.110 -
19.111 -/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
19.112 - * coordinates. */
19.113 -mp_err ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py,
19.114 - const mp_int *pz);
19.115 -
19.116 -/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
19.117 - * coordinates. */
19.118 -mp_err ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz);
19.119 -
19.120 -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
19.121 - * (qx, qy, qz). Uses Jacobian coordinates. */
19.122 -mp_err ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py,
19.123 - const mp_int *pz, const mp_int *qx,
19.124 - const mp_int *qy, mp_int *rx, mp_int *ry,
19.125 - mp_int *rz, const ECGroup *group);
19.126 -
19.127 -/* Computes R = 2P. Uses Jacobian coordinates. */
19.128 -mp_err ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py,
19.129 - const mp_int *pz, mp_int *rx, mp_int *ry,
19.130 - mp_int *rz, const ECGroup *group);
19.131 -
19.132 -#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
19.133 -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
19.134 - * a, b and p are the elliptic curve coefficients and the prime that
19.135 - * determines the field GFp. Uses Jacobian coordinates. */
19.136 -mp_err ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px,
19.137 - const mp_int *py, mp_int *rx, mp_int *ry,
19.138 - const ECGroup *group);
19.139 -#endif
19.140 -
19.141 -/* Computes R(x, y) = k1 * G + k2 * P(x, y), where G is the generator
19.142 - * (base point) of the group of points on the elliptic curve. Allows k1 =
19.143 - * NULL or { k2, P } = NULL. Implemented using mixed Jacobian-affine
19.144 - * coordinates. Input and output values are assumed to be NOT
19.145 - * field-encoded and are in affine form. */
19.146 -mp_err
19.147 - ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
19.148 - const mp_int *py, mp_int *rx, mp_int *ry,
19.149 - const ECGroup *group);
19.150 -
19.151 -/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
19.152 - * curve points P and R can be identical. Uses mixed Modified-Jacobian
19.153 - * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
19.154 - * additions. Assumes input is already field-encoded using field_enc, and
19.155 - * returns output that is still field-encoded. Uses 5-bit window NAF
19.156 - * method (algorithm 11) for scalar-point multiplication from Brown,
19.157 - * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
19.158 - * Curves Over Prime Fields. */
19.159 -mp_err
19.160 - ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
19.161 - mp_int *rx, mp_int *ry, const ECGroup *group);
19.162 -
19.163 -#endif /* _ECP_H */
20.1 --- a/src/share/native/sun/security/ec/ecp_192.c Tue Oct 13 15:25:58 2009 -0700
20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3 @@ -1,538 +0,0 @@
20.4 -/* *********************************************************************
20.5 - *
20.6 - * Sun elects to have this file available under and governed by the
20.7 - * Mozilla Public License Version 1.1 ("MPL") (see
20.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
20.9 - * of doubt and subject to the following, Sun also elects to allow
20.10 - * licensees to use this file under the MPL, the GNU General Public
20.11 - * License version 2 only or the Lesser General Public License version
20.12 - * 2.1 only. Any references to the "GNU General Public License version 2
20.13 - * or later" or "GPL" in the following shall be construed to mean the
20.14 - * GNU General Public License version 2 only. Any references to the "GNU
20.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
20.16 - * following shall be construed to mean the GNU Lesser General Public
20.17 - * License version 2.1 only. However, the following notice accompanied
20.18 - * the original version of this file:
20.19 - *
20.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
20.21 - *
20.22 - * The contents of this file are subject to the Mozilla Public License Version
20.23 - * 1.1 (the "License"); you may not use this file except in compliance with
20.24 - * the License. You may obtain a copy of the License at
20.25 - * http://www.mozilla.org/MPL/
20.26 - *
20.27 - * Software distributed under the License is distributed on an "AS IS" basis,
20.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20.29 - * for the specific language governing rights and limitations under the
20.30 - * License.
20.31 - *
20.32 - * The Original Code is the elliptic curve math library for prime field curves.
20.33 - *
20.34 - * The Initial Developer of the Original Code is
20.35 - * Sun Microsystems, Inc.
20.36 - * Portions created by the Initial Developer are Copyright (C) 2003
20.37 - * the Initial Developer. All Rights Reserved.
20.38 - *
20.39 - * Contributor(s):
20.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
20.41 - *
20.42 - * Alternatively, the contents of this file may be used under the terms of
20.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
20.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
20.46 - * of those above. If you wish to allow use of your version of this file only
20.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
20.48 - * use your version of this file under the terms of the MPL, indicate your
20.49 - * decision by deleting the provisions above and replace them with the notice
20.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
20.51 - * the provisions above, a recipient may use your version of this file under
20.52 - * the terms of any one of the MPL, the GPL or the LGPL.
20.53 - *
20.54 - *********************************************************************** */
20.55 -/*
20.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
20.57 - * Use is subject to license terms.
20.58 - */
20.59 -
20.60 -#pragma ident "%Z%%M% %I% %E% SMI"
20.61 -
20.62 -#include "ecp.h"
20.63 -#include "mpi.h"
20.64 -#include "mplogic.h"
20.65 -#include "mpi-priv.h"
20.66 -#ifndef _KERNEL
20.67 -#include <stdlib.h>
20.68 -#endif
20.69 -
20.70 -#define ECP192_DIGITS ECL_CURVE_DIGITS(192)
20.71 -
20.72 -/* Fast modular reduction for p192 = 2^192 - 2^64 - 1. a can be r. Uses
20.73 - * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
20.74 - * Implementation of the NIST Elliptic Curves over Prime Fields. */
20.75 -mp_err
20.76 -ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
20.77 -{
20.78 - mp_err res = MP_OKAY;
20.79 - mp_size a_used = MP_USED(a);
20.80 - mp_digit r3;
20.81 -#ifndef MPI_AMD64_ADD
20.82 - mp_digit carry;
20.83 -#endif
20.84 -#ifdef ECL_THIRTY_TWO_BIT
20.85 - mp_digit a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
20.86 - mp_digit r0a, r0b, r1a, r1b, r2a, r2b;
20.87 -#else
20.88 - mp_digit a5 = 0, a4 = 0, a3 = 0;
20.89 - mp_digit r0, r1, r2;
20.90 -#endif
20.91 -
20.92 - /* reduction not needed if a is not larger than field size */
20.93 - if (a_used < ECP192_DIGITS) {
20.94 - if (a == r) {
20.95 - return MP_OKAY;
20.96 - }
20.97 - return mp_copy(a, r);
20.98 - }
20.99 -
20.100 - /* for polynomials larger than twice the field size, use regular
20.101 - * reduction */
20.102 - if (a_used > ECP192_DIGITS*2) {
20.103 - MP_CHECKOK(mp_mod(a, &meth->irr, r));
20.104 - } else {
20.105 - /* copy out upper words of a */
20.106 -
20.107 -#ifdef ECL_THIRTY_TWO_BIT
20.108 -
20.109 - /* in all the math below,
20.110 - * nXb is most signifiant, nXa is least significant */
20.111 - switch (a_used) {
20.112 - case 12:
20.113 - a5b = MP_DIGIT(a, 11);
20.114 - case 11:
20.115 - a5a = MP_DIGIT(a, 10);
20.116 - case 10:
20.117 - a4b = MP_DIGIT(a, 9);
20.118 - case 9:
20.119 - a4a = MP_DIGIT(a, 8);
20.120 - case 8:
20.121 - a3b = MP_DIGIT(a, 7);
20.122 - case 7:
20.123 - a3a = MP_DIGIT(a, 6);
20.124 - }
20.125 -
20.126 -
20.127 - r2b= MP_DIGIT(a, 5);
20.128 - r2a= MP_DIGIT(a, 4);
20.129 - r1b = MP_DIGIT(a, 3);
20.130 - r1a = MP_DIGIT(a, 2);
20.131 - r0b = MP_DIGIT(a, 1);
20.132 - r0a = MP_DIGIT(a, 0);
20.133 -
20.134 - /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
20.135 - MP_ADD_CARRY(r0a, a3a, r0a, 0, carry);
20.136 - MP_ADD_CARRY(r0b, a3b, r0b, carry, carry);
20.137 - MP_ADD_CARRY(r1a, a3a, r1a, carry, carry);
20.138 - MP_ADD_CARRY(r1b, a3b, r1b, carry, carry);
20.139 - MP_ADD_CARRY(r2a, a4a, r2a, carry, carry);
20.140 - MP_ADD_CARRY(r2b, a4b, r2b, carry, carry);
20.141 - r3 = carry; carry = 0;
20.142 - MP_ADD_CARRY(r0a, a5a, r0a, 0, carry);
20.143 - MP_ADD_CARRY(r0b, a5b, r0b, carry, carry);
20.144 - MP_ADD_CARRY(r1a, a5a, r1a, carry, carry);
20.145 - MP_ADD_CARRY(r1b, a5b, r1b, carry, carry);
20.146 - MP_ADD_CARRY(r2a, a5a, r2a, carry, carry);
20.147 - MP_ADD_CARRY(r2b, a5b, r2b, carry, carry);
20.148 - r3 += carry;
20.149 - MP_ADD_CARRY(r1a, a4a, r1a, 0, carry);
20.150 - MP_ADD_CARRY(r1b, a4b, r1b, carry, carry);
20.151 - MP_ADD_CARRY(r2a, 0, r2a, carry, carry);
20.152 - MP_ADD_CARRY(r2b, 0, r2b, carry, carry);
20.153 - r3 += carry;
20.154 -
20.155 - /* reduce out the carry */
20.156 - while (r3) {
20.157 - MP_ADD_CARRY(r0a, r3, r0a, 0, carry);
20.158 - MP_ADD_CARRY(r0b, 0, r0b, carry, carry);
20.159 - MP_ADD_CARRY(r1a, r3, r1a, carry, carry);
20.160 - MP_ADD_CARRY(r1b, 0, r1b, carry, carry);
20.161 - MP_ADD_CARRY(r2a, 0, r2a, carry, carry);
20.162 - MP_ADD_CARRY(r2b, 0, r2b, carry, carry);
20.163 - r3 = carry;
20.164 - }
20.165 -
20.166 - /* check for final reduction */
20.167 - /*
20.168 - * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
20.169 - * 0xffffffffffffffff. That means we can only be over and need
20.170 - * one more reduction
20.171 - * if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
20.172 - * and
20.173 - * r1 == 0xffffffffffffffffff or
20.174 - * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
20.175 - * In all cases, we subtract the field (or add the 2's
20.176 - * complement value (1,1,0)). (r0, r1, r2)
20.177 - */
20.178 - if (((r2b == 0xffffffff) && (r2a == 0xffffffff)
20.179 - && (r1b == 0xffffffff) ) &&
20.180 - ((r1a == 0xffffffff) ||
20.181 - (r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
20.182 - (r0b == 0xffffffff)) ) {
20.183 - /* do a quick subtract */
20.184 - MP_ADD_CARRY(r0a, 1, r0a, 0, carry);
20.185 - r0b += carry;
20.186 - r1a = r1b = r2a = r2b = 0;
20.187 - }
20.188 -
20.189 - /* set the lower words of r */
20.190 - if (a != r) {
20.191 - MP_CHECKOK(s_mp_pad(r, 6));
20.192 - }
20.193 - MP_DIGIT(r, 5) = r2b;
20.194 - MP_DIGIT(r, 4) = r2a;
20.195 - MP_DIGIT(r, 3) = r1b;
20.196 - MP_DIGIT(r, 2) = r1a;
20.197 - MP_DIGIT(r, 1) = r0b;
20.198 - MP_DIGIT(r, 0) = r0a;
20.199 - MP_USED(r) = 6;
20.200 -#else
20.201 - switch (a_used) {
20.202 - case 6:
20.203 - a5 = MP_DIGIT(a, 5);
20.204 - case 5:
20.205 - a4 = MP_DIGIT(a, 4);
20.206 - case 4:
20.207 - a3 = MP_DIGIT(a, 3);
20.208 - }
20.209 -
20.210 - r2 = MP_DIGIT(a, 2);
20.211 - r1 = MP_DIGIT(a, 1);
20.212 - r0 = MP_DIGIT(a, 0);
20.213 -
20.214 - /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
20.215 -#ifndef MPI_AMD64_ADD
20.216 - MP_ADD_CARRY(r0, a3, r0, 0, carry);
20.217 - MP_ADD_CARRY(r1, a3, r1, carry, carry);
20.218 - MP_ADD_CARRY(r2, a4, r2, carry, carry);
20.219 - r3 = carry;
20.220 - MP_ADD_CARRY(r0, a5, r0, 0, carry);
20.221 - MP_ADD_CARRY(r1, a5, r1, carry, carry);
20.222 - MP_ADD_CARRY(r2, a5, r2, carry, carry);
20.223 - r3 += carry;
20.224 - MP_ADD_CARRY(r1, a4, r1, 0, carry);
20.225 - MP_ADD_CARRY(r2, 0, r2, carry, carry);
20.226 - r3 += carry;
20.227 -
20.228 -#else
20.229 - r2 = MP_DIGIT(a, 2);
20.230 - r1 = MP_DIGIT(a, 1);
20.231 - r0 = MP_DIGIT(a, 0);
20.232 -
20.233 - /* set the lower words of r */
20.234 - __asm__ (
20.235 - "xorq %3,%3 \n\t"
20.236 - "addq %4,%0 \n\t"
20.237 - "adcq %4,%1 \n\t"
20.238 - "adcq %5,%2 \n\t"
20.239 - "adcq $0,%3 \n\t"
20.240 - "addq %6,%0 \n\t"
20.241 - "adcq %6,%1 \n\t"
20.242 - "adcq %6,%2 \n\t"
20.243 - "adcq $0,%3 \n\t"
20.244 - "addq %5,%1 \n\t"
20.245 - "adcq $0,%2 \n\t"
20.246 - "adcq $0,%3 \n\t"
20.247 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3),
20.248 - "=r"(a4), "=r"(a5)
20.249 - : "0" (r0), "1" (r1), "2" (r2), "3" (r3),
20.250 - "4" (a3), "5" (a4), "6"(a5)
20.251 - : "%cc" );
20.252 -#endif
20.253 -
20.254 - /* reduce out the carry */
20.255 - while (r3) {
20.256 -#ifndef MPI_AMD64_ADD
20.257 - MP_ADD_CARRY(r0, r3, r0, 0, carry);
20.258 - MP_ADD_CARRY(r1, r3, r1, carry, carry);
20.259 - MP_ADD_CARRY(r2, 0, r2, carry, carry);
20.260 - r3 = carry;
20.261 -#else
20.262 - a3=r3;
20.263 - __asm__ (
20.264 - "xorq %3,%3 \n\t"
20.265 - "addq %4,%0 \n\t"
20.266 - "adcq %4,%1 \n\t"
20.267 - "adcq $0,%2 \n\t"
20.268 - "adcq $0,%3 \n\t"
20.269 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3)
20.270 - : "0" (r0), "1" (r1), "2" (r2), "3" (r3), "4"(a3)
20.271 - : "%cc" );
20.272 -#endif
20.273 - }
20.274 -
20.275 - /* check for final reduction */
20.276 - /*
20.277 - * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
20.278 - * 0xffffffffffffffff. That means we can only be over and need
20.279 - * one more reduction
20.280 - * if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
20.281 - * and
20.282 - * r1 == 0xffffffffffffffffff or
20.283 - * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
20.284 - * In all cases, we subtract the field (or add the 2's
20.285 - * complement value (1,1,0)). (r0, r1, r2)
20.286 - */
20.287 - if (r3 || ((r2 == MP_DIGIT_MAX) &&
20.288 - ((r1 == MP_DIGIT_MAX) ||
20.289 - ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
20.290 - /* do a quick subtract */
20.291 - r0++;
20.292 - r1 = r2 = 0;
20.293 - }
20.294 - /* set the lower words of r */
20.295 - if (a != r) {
20.296 - MP_CHECKOK(s_mp_pad(r, 3));
20.297 - }
20.298 - MP_DIGIT(r, 2) = r2;
20.299 - MP_DIGIT(r, 1) = r1;
20.300 - MP_DIGIT(r, 0) = r0;
20.301 - MP_USED(r) = 3;
20.302 -#endif
20.303 - }
20.304 -
20.305 - CLEANUP:
20.306 - return res;
20.307 -}
20.308 -
20.309 -#ifndef ECL_THIRTY_TWO_BIT
20.310 -/* Compute the sum of 192 bit curves. Do the work in-line since the
20.311 - * number of words are so small, we don't want to overhead of mp function
20.312 - * calls. Uses optimized modular reduction for p192.
20.313 - */
20.314 -mp_err
20.315 -ec_GFp_nistp192_add(const mp_int *a, const mp_int *b, mp_int *r,
20.316 - const GFMethod *meth)
20.317 -{
20.318 - mp_err res = MP_OKAY;
20.319 - mp_digit a0 = 0, a1 = 0, a2 = 0;
20.320 - mp_digit r0 = 0, r1 = 0, r2 = 0;
20.321 - mp_digit carry;
20.322 -
20.323 - switch(MP_USED(a)) {
20.324 - case 3:
20.325 - a2 = MP_DIGIT(a,2);
20.326 - case 2:
20.327 - a1 = MP_DIGIT(a,1);
20.328 - case 1:
20.329 - a0 = MP_DIGIT(a,0);
20.330 - }
20.331 - switch(MP_USED(b)) {
20.332 - case 3:
20.333 - r2 = MP_DIGIT(b,2);
20.334 - case 2:
20.335 - r1 = MP_DIGIT(b,1);
20.336 - case 1:
20.337 - r0 = MP_DIGIT(b,0);
20.338 - }
20.339 -
20.340 -#ifndef MPI_AMD64_ADD
20.341 - MP_ADD_CARRY(a0, r0, r0, 0, carry);
20.342 - MP_ADD_CARRY(a1, r1, r1, carry, carry);
20.343 - MP_ADD_CARRY(a2, r2, r2, carry, carry);
20.344 -#else
20.345 - __asm__ (
20.346 - "xorq %3,%3 \n\t"
20.347 - "addq %4,%0 \n\t"
20.348 - "adcq %5,%1 \n\t"
20.349 - "adcq %6,%2 \n\t"
20.350 - "adcq $0,%3 \n\t"
20.351 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
20.352 - : "r" (a0), "r" (a1), "r" (a2), "0" (r0),
20.353 - "1" (r1), "2" (r2)
20.354 - : "%cc" );
20.355 -#endif
20.356 -
20.357 - /* Do quick 'subract' if we've gone over
20.358 - * (add the 2's complement of the curve field) */
20.359 - if (carry || ((r2 == MP_DIGIT_MAX) &&
20.360 - ((r1 == MP_DIGIT_MAX) ||
20.361 - ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
20.362 -#ifndef MPI_AMD64_ADD
20.363 - MP_ADD_CARRY(r0, 1, r0, 0, carry);
20.364 - MP_ADD_CARRY(r1, 1, r1, carry, carry);
20.365 - MP_ADD_CARRY(r2, 0, r2, carry, carry);
20.366 -#else
20.367 - __asm__ (
20.368 - "addq $1,%0 \n\t"
20.369 - "adcq $1,%1 \n\t"
20.370 - "adcq $0,%2 \n\t"
20.371 - : "=r"(r0), "=r"(r1), "=r"(r2)
20.372 - : "0" (r0), "1" (r1), "2" (r2)
20.373 - : "%cc" );
20.374 -#endif
20.375 - }
20.376 -
20.377 -
20.378 - MP_CHECKOK(s_mp_pad(r, 3));
20.379 - MP_DIGIT(r, 2) = r2;
20.380 - MP_DIGIT(r, 1) = r1;
20.381 - MP_DIGIT(r, 0) = r0;
20.382 - MP_SIGN(r) = MP_ZPOS;
20.383 - MP_USED(r) = 3;
20.384 - s_mp_clamp(r);
20.385 -
20.386 -
20.387 - CLEANUP:
20.388 - return res;
20.389 -}
20.390 -
20.391 -/* Compute the diff of 192 bit curves. Do the work in-line since the
20.392 - * number of words are so small, we don't want to overhead of mp function
20.393 - * calls. Uses optimized modular reduction for p192.
20.394 - */
20.395 -mp_err
20.396 -ec_GFp_nistp192_sub(const mp_int *a, const mp_int *b, mp_int *r,
20.397 - const GFMethod *meth)
20.398 -{
20.399 - mp_err res = MP_OKAY;
20.400 - mp_digit b0 = 0, b1 = 0, b2 = 0;
20.401 - mp_digit r0 = 0, r1 = 0, r2 = 0;
20.402 - mp_digit borrow;
20.403 -
20.404 - switch(MP_USED(a)) {
20.405 - case 3:
20.406 - r2 = MP_DIGIT(a,2);
20.407 - case 2:
20.408 - r1 = MP_DIGIT(a,1);
20.409 - case 1:
20.410 - r0 = MP_DIGIT(a,0);
20.411 - }
20.412 -
20.413 - switch(MP_USED(b)) {
20.414 - case 3:
20.415 - b2 = MP_DIGIT(b,2);
20.416 - case 2:
20.417 - b1 = MP_DIGIT(b,1);
20.418 - case 1:
20.419 - b0 = MP_DIGIT(b,0);
20.420 - }
20.421 -
20.422 -#ifndef MPI_AMD64_ADD
20.423 - MP_SUB_BORROW(r0, b0, r0, 0, borrow);
20.424 - MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
20.425 - MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
20.426 -#else
20.427 - __asm__ (
20.428 - "xorq %3,%3 \n\t"
20.429 - "subq %4,%0 \n\t"
20.430 - "sbbq %5,%1 \n\t"
20.431 - "sbbq %6,%2 \n\t"
20.432 - "adcq $0,%3 \n\t"
20.433 - : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(borrow)
20.434 - : "r" (b0), "r" (b1), "r" (b2), "0" (r0),
20.435 - "1" (r1), "2" (r2)
20.436 - : "%cc" );
20.437 -#endif
20.438 -
20.439 - /* Do quick 'add' if we've gone under 0
20.440 - * (subtract the 2's complement of the curve field) */
20.441 - if (borrow) {
20.442 -#ifndef MPI_AMD64_ADD
20.443 - MP_SUB_BORROW(r0, 1, r0, 0, borrow);
20.444 - MP_SUB_BORROW(r1, 1, r1, borrow, borrow);
20.445 - MP_SUB_BORROW(r2, 0, r2, borrow, borrow);
20.446 -#else
20.447 - __asm__ (
20.448 - "subq $1,%0 \n\t"
20.449 - "sbbq $1,%1 \n\t"
20.450 - "sbbq $0,%2 \n\t"
20.451 - : "=r"(r0), "=r"(r1), "=r"(r2)
20.452 - : "0" (r0), "1" (r1), "2" (r2)
20.453 - : "%cc" );
20.454 -#endif
20.455 - }
20.456 -
20.457 - MP_CHECKOK(s_mp_pad(r, 3));
20.458 - MP_DIGIT(r, 2) = r2;
20.459 - MP_DIGIT(r, 1) = r1;
20.460 - MP_DIGIT(r, 0) = r0;
20.461 - MP_SIGN(r) = MP_ZPOS;
20.462 - MP_USED(r) = 3;
20.463 - s_mp_clamp(r);
20.464 -
20.465 - CLEANUP:
20.466 - return res;
20.467 -}
20.468 -
20.469 -#endif
20.470 -
20.471 -/* Compute the square of polynomial a, reduce modulo p192. Store the
20.472 - * result in r. r could be a. Uses optimized modular reduction for p192.
20.473 - */
20.474 -mp_err
20.475 -ec_GFp_nistp192_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
20.476 -{
20.477 - mp_err res = MP_OKAY;
20.478 -
20.479 - MP_CHECKOK(mp_sqr(a, r));
20.480 - MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
20.481 - CLEANUP:
20.482 - return res;
20.483 -}
20.484 -
20.485 -/* Compute the product of two polynomials a and b, reduce modulo p192.
20.486 - * Store the result in r. r could be a or b; a could be b. Uses
20.487 - * optimized modular reduction for p192. */
20.488 -mp_err
20.489 -ec_GFp_nistp192_mul(const mp_int *a, const mp_int *b, mp_int *r,
20.490 - const GFMethod *meth)
20.491 -{
20.492 - mp_err res = MP_OKAY;
20.493 -
20.494 - MP_CHECKOK(mp_mul(a, b, r));
20.495 - MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
20.496 - CLEANUP:
20.497 - return res;
20.498 -}
20.499 -
20.500 -/* Divides two field elements. If a is NULL, then returns the inverse of
20.501 - * b. */
20.502 -mp_err
20.503 -ec_GFp_nistp192_div(const mp_int *a, const mp_int *b, mp_int *r,
20.504 - const GFMethod *meth)
20.505 -{
20.506 - mp_err res = MP_OKAY;
20.507 - mp_int t;
20.508 -
20.509 - /* If a is NULL, then return the inverse of b, otherwise return a/b. */
20.510 - if (a == NULL) {
20.511 - return mp_invmod(b, &meth->irr, r);
20.512 - } else {
20.513 - /* MPI doesn't support divmod, so we implement it using invmod and
20.514 - * mulmod. */
20.515 - MP_CHECKOK(mp_init(&t, FLAG(b)));
20.516 - MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
20.517 - MP_CHECKOK(mp_mul(a, &t, r));
20.518 - MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
20.519 - CLEANUP:
20.520 - mp_clear(&t);
20.521 - return res;
20.522 - }
20.523 -}
20.524 -
20.525 -/* Wire in fast field arithmetic and precomputation of base point for
20.526 - * named curves. */
20.527 -mp_err
20.528 -ec_group_set_gfp192(ECGroup *group, ECCurveName name)
20.529 -{
20.530 - if (name == ECCurve_NIST_P192) {
20.531 - group->meth->field_mod = &ec_GFp_nistp192_mod;
20.532 - group->meth->field_mul = &ec_GFp_nistp192_mul;
20.533 - group->meth->field_sqr = &ec_GFp_nistp192_sqr;
20.534 - group->meth->field_div = &ec_GFp_nistp192_div;
20.535 -#ifndef ECL_THIRTY_TWO_BIT
20.536 - group->meth->field_add = &ec_GFp_nistp192_add;
20.537 - group->meth->field_sub = &ec_GFp_nistp192_sub;
20.538 -#endif
20.539 - }
20.540 - return MP_OKAY;
20.541 -}
21.1 --- a/src/share/native/sun/security/ec/ecp_224.c Tue Oct 13 15:25:58 2009 -0700
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,394 +0,0 @@
21.4 -/* *********************************************************************
21.5 - *
21.6 - * Sun elects to have this file available under and governed by the
21.7 - * Mozilla Public License Version 1.1 ("MPL") (see
21.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
21.9 - * of doubt and subject to the following, Sun also elects to allow
21.10 - * licensees to use this file under the MPL, the GNU General Public
21.11 - * License version 2 only or the Lesser General Public License version
21.12 - * 2.1 only. Any references to the "GNU General Public License version 2
21.13 - * or later" or "GPL" in the following shall be construed to mean the
21.14 - * GNU General Public License version 2 only. Any references to the "GNU
21.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
21.16 - * following shall be construed to mean the GNU Lesser General Public
21.17 - * License version 2.1 only. However, the following notice accompanied
21.18 - * the original version of this file:
21.19 - *
21.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
21.21 - *
21.22 - * The contents of this file are subject to the Mozilla Public License Version
21.23 - * 1.1 (the "License"); you may not use this file except in compliance with
21.24 - * the License. You may obtain a copy of the License at
21.25 - * http://www.mozilla.org/MPL/
21.26 - *
21.27 - * Software distributed under the License is distributed on an "AS IS" basis,
21.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
21.29 - * for the specific language governing rights and limitations under the
21.30 - * License.
21.31 - *
21.32 - * The Original Code is the elliptic curve math library for prime field curves.
21.33 - *
21.34 - * The Initial Developer of the Original Code is
21.35 - * Sun Microsystems, Inc.
21.36 - * Portions created by the Initial Developer are Copyright (C) 2003
21.37 - * the Initial Developer. All Rights Reserved.
21.38 - *
21.39 - * Contributor(s):
21.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
21.41 - *
21.42 - * Alternatively, the contents of this file may be used under the terms of
21.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
21.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
21.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
21.46 - * of those above. If you wish to allow use of your version of this file only
21.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
21.48 - * use your version of this file under the terms of the MPL, indicate your
21.49 - * decision by deleting the provisions above and replace them with the notice
21.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
21.51 - * the provisions above, a recipient may use your version of this file under
21.52 - * the terms of any one of the MPL, the GPL or the LGPL.
21.53 - *
21.54 - *********************************************************************** */
21.55 -/*
21.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
21.57 - * Use is subject to license terms.
21.58 - */
21.59 -
21.60 -#pragma ident "%Z%%M% %I% %E% SMI"
21.61 -
21.62 -#include "ecp.h"
21.63 -#include "mpi.h"
21.64 -#include "mplogic.h"
21.65 -#include "mpi-priv.h"
21.66 -#ifndef _KERNEL
21.67 -#include <stdlib.h>
21.68 -#endif
21.69 -
21.70 -#define ECP224_DIGITS ECL_CURVE_DIGITS(224)
21.71 -
21.72 -/* Fast modular reduction for p224 = 2^224 - 2^96 + 1. a can be r. Uses
21.73 - * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
21.74 - * Implementation of the NIST Elliptic Curves over Prime Fields. */
21.75 -mp_err
21.76 -ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
21.77 -{
21.78 - mp_err res = MP_OKAY;
21.79 - mp_size a_used = MP_USED(a);
21.80 -
21.81 - int r3b;
21.82 - mp_digit carry;
21.83 -#ifdef ECL_THIRTY_TWO_BIT
21.84 - mp_digit a6a = 0, a6b = 0,
21.85 - a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
21.86 - mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a;
21.87 -#else
21.88 - mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0;
21.89 - mp_digit a6b = 0, a6a_a5b = 0, a5b = 0, a5a_a4b = 0, a4a_a3b = 0;
21.90 - mp_digit r0, r1, r2, r3;
21.91 -#endif
21.92 -
21.93 - /* reduction not needed if a is not larger than field size */
21.94 - if (a_used < ECP224_DIGITS) {
21.95 - if (a == r) return MP_OKAY;
21.96 - return mp_copy(a, r);
21.97 - }
21.98 - /* for polynomials larger than twice the field size, use regular
21.99 - * reduction */
21.100 - if (a_used > ECL_CURVE_DIGITS(224*2)) {
21.101 - MP_CHECKOK(mp_mod(a, &meth->irr, r));
21.102 - } else {
21.103 -#ifdef ECL_THIRTY_TWO_BIT
21.104 - /* copy out upper words of a */
21.105 - switch (a_used) {
21.106 - case 14:
21.107 - a6b = MP_DIGIT(a, 13);
21.108 - case 13:
21.109 - a6a = MP_DIGIT(a, 12);
21.110 - case 12:
21.111 - a5b = MP_DIGIT(a, 11);
21.112 - case 11:
21.113 - a5a = MP_DIGIT(a, 10);
21.114 - case 10:
21.115 - a4b = MP_DIGIT(a, 9);
21.116 - case 9:
21.117 - a4a = MP_DIGIT(a, 8);
21.118 - case 8:
21.119 - a3b = MP_DIGIT(a, 7);
21.120 - }
21.121 - r3a = MP_DIGIT(a, 6);
21.122 - r2b= MP_DIGIT(a, 5);
21.123 - r2a= MP_DIGIT(a, 4);
21.124 - r1b = MP_DIGIT(a, 3);
21.125 - r1a = MP_DIGIT(a, 2);
21.126 - r0b = MP_DIGIT(a, 1);
21.127 - r0a = MP_DIGIT(a, 0);
21.128 -
21.129 -
21.130 - /* implement r = (a3a,a2,a1,a0)
21.131 - +(a5a, a4,a3b, 0)
21.132 - +( 0, a6,a5b, 0)
21.133 - -( 0 0, 0|a6b, a6a|a5b )
21.134 - -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
21.135 - MP_ADD_CARRY (r1b, a3b, r1b, 0, carry);
21.136 - MP_ADD_CARRY (r2a, a4a, r2a, carry, carry);
21.137 - MP_ADD_CARRY (r2b, a4b, r2b, carry, carry);
21.138 - MP_ADD_CARRY (r3a, a5a, r3a, carry, carry);
21.139 - r3b = carry;
21.140 - MP_ADD_CARRY (r1b, a5b, r1b, 0, carry);
21.141 - MP_ADD_CARRY (r2a, a6a, r2a, carry, carry);
21.142 - MP_ADD_CARRY (r2b, a6b, r2b, carry, carry);
21.143 - MP_ADD_CARRY (r3a, 0, r3a, carry, carry);
21.144 - r3b += carry;
21.145 - MP_SUB_BORROW(r0a, a3b, r0a, 0, carry);
21.146 - MP_SUB_BORROW(r0b, a4a, r0b, carry, carry);
21.147 - MP_SUB_BORROW(r1a, a4b, r1a, carry, carry);
21.148 - MP_SUB_BORROW(r1b, a5a, r1b, carry, carry);
21.149 - MP_SUB_BORROW(r2a, a5b, r2a, carry, carry);
21.150 - MP_SUB_BORROW(r2b, a6a, r2b, carry, carry);
21.151 - MP_SUB_BORROW(r3a, a6b, r3a, carry, carry);
21.152 - r3b -= carry;
21.153 - MP_SUB_BORROW(r0a, a5b, r0a, 0, carry);
21.154 - MP_SUB_BORROW(r0b, a6a, r0b, carry, carry);
21.155 - MP_SUB_BORROW(r1a, a6b, r1a, carry, carry);
21.156 - if (carry) {
21.157 - MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
21.158 - MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
21.159 - MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
21.160 - MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
21.161 - r3b -= carry;
21.162 - }
21.163 -
21.164 - while (r3b > 0) {
21.165 - int tmp;
21.166 - MP_ADD_CARRY(r1b, r3b, r1b, 0, carry);
21.167 - if (carry) {
21.168 - MP_ADD_CARRY(r2a, 0, r2a, carry, carry);
21.169 - MP_ADD_CARRY(r2b, 0, r2b, carry, carry);
21.170 - MP_ADD_CARRY(r3a, 0, r3a, carry, carry);
21.171 - }
21.172 - tmp = carry;
21.173 - MP_SUB_BORROW(r0a, r3b, r0a, 0, carry);
21.174 - if (carry) {
21.175 - MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
21.176 - MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
21.177 - MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
21.178 - MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
21.179 - MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
21.180 - MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
21.181 - tmp -= carry;
21.182 - }
21.183 - r3b = tmp;
21.184 - }
21.185 -
21.186 - while (r3b < 0) {
21.187 - mp_digit maxInt = MP_DIGIT_MAX;
21.188 - MP_ADD_CARRY (r0a, 1, r0a, 0, carry);
21.189 - MP_ADD_CARRY (r0b, 0, r0b, carry, carry);
21.190 - MP_ADD_CARRY (r1a, 0, r1a, carry, carry);
21.191 - MP_ADD_CARRY (r1b, maxInt, r1b, carry, carry);
21.192 - MP_ADD_CARRY (r2a, maxInt, r2a, carry, carry);
21.193 - MP_ADD_CARRY (r2b, maxInt, r2b, carry, carry);
21.194 - MP_ADD_CARRY (r3a, maxInt, r3a, carry, carry);
21.195 - r3b += carry;
21.196 - }
21.197 - /* check for final reduction */
21.198 - /* now the only way we are over is if the top 4 words are all ones */
21.199 - if ((r3a == MP_DIGIT_MAX) && (r2b == MP_DIGIT_MAX)
21.200 - && (r2a == MP_DIGIT_MAX) && (r1b == MP_DIGIT_MAX) &&
21.201 - ((r1a != 0) || (r0b != 0) || (r0a != 0)) ) {
21.202 - /* one last subraction */
21.203 - MP_SUB_BORROW(r0a, 1, r0a, 0, carry);
21.204 - MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
21.205 - MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
21.206 - r1b = r2a = r2b = r3a = 0;
21.207 - }
21.208 -
21.209 -
21.210 - if (a != r) {
21.211 - MP_CHECKOK(s_mp_pad(r, 7));
21.212 - }
21.213 - /* set the lower words of r */
21.214 - MP_SIGN(r) = MP_ZPOS;
21.215 - MP_USED(r) = 7;
21.216 - MP_DIGIT(r, 6) = r3a;
21.217 - MP_DIGIT(r, 5) = r2b;
21.218 - MP_DIGIT(r, 4) = r2a;
21.219 - MP_DIGIT(r, 3) = r1b;
21.220 - MP_DIGIT(r, 2) = r1a;
21.221 - MP_DIGIT(r, 1) = r0b;
21.222 - MP_DIGIT(r, 0) = r0a;
21.223 -#else
21.224 - /* copy out upper words of a */
21.225 - switch (a_used) {
21.226 - case 7:
21.227 - a6 = MP_DIGIT(a, 6);
21.228 - a6b = a6 >> 32;
21.229 - a6a_a5b = a6 << 32;
21.230 - case 6:
21.231 - a5 = MP_DIGIT(a, 5);
21.232 - a5b = a5 >> 32;
21.233 - a6a_a5b |= a5b;
21.234 - a5b = a5b << 32;
21.235 - a5a_a4b = a5 << 32;
21.236 - a5a = a5 & 0xffffffff;
21.237 - case 5:
21.238 - a4 = MP_DIGIT(a, 4);
21.239 - a5a_a4b |= a4 >> 32;
21.240 - a4a_a3b = a4 << 32;
21.241 - case 4:
21.242 - a3b = MP_DIGIT(a, 3) >> 32;
21.243 - a4a_a3b |= a3b;
21.244 - a3b = a3b << 32;
21.245 - }
21.246 -
21.247 - r3 = MP_DIGIT(a, 3) & 0xffffffff;
21.248 - r2 = MP_DIGIT(a, 2);
21.249 - r1 = MP_DIGIT(a, 1);
21.250 - r0 = MP_DIGIT(a, 0);
21.251 -
21.252 - /* implement r = (a3a,a2,a1,a0)
21.253 - +(a5a, a4,a3b, 0)
21.254 - +( 0, a6,a5b, 0)
21.255 - -( 0 0, 0|a6b, a6a|a5b )
21.256 - -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
21.257 - MP_ADD_CARRY (r1, a3b, r1, 0, carry);
21.258 - MP_ADD_CARRY (r2, a4 , r2, carry, carry);
21.259 - MP_ADD_CARRY (r3, a5a, r3, carry, carry);
21.260 - MP_ADD_CARRY (r1, a5b, r1, 0, carry);
21.261 - MP_ADD_CARRY (r2, a6 , r2, carry, carry);
21.262 - MP_ADD_CARRY (r3, 0, r3, carry, carry);
21.263 -
21.264 - MP_SUB_BORROW(r0, a4a_a3b, r0, 0, carry);
21.265 - MP_SUB_BORROW(r1, a5a_a4b, r1, carry, carry);
21.266 - MP_SUB_BORROW(r2, a6a_a5b, r2, carry, carry);
21.267 - MP_SUB_BORROW(r3, a6b , r3, carry, carry);
21.268 - MP_SUB_BORROW(r0, a6a_a5b, r0, 0, carry);
21.269 - MP_SUB_BORROW(r1, a6b , r1, carry, carry);
21.270 - if (carry) {
21.271 - MP_SUB_BORROW(r2, 0, r2, carry, carry);
21.272 - MP_SUB_BORROW(r3, 0, r3, carry, carry);
21.273 - }
21.274 -
21.275 -
21.276 - /* if the value is negative, r3 has a 2's complement
21.277 - * high value */
21.278 - r3b = (int)(r3 >>32);
21.279 - while (r3b > 0) {
21.280 - r3 &= 0xffffffff;
21.281 - MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry);
21.282 - if (carry) {
21.283 - MP_ADD_CARRY(r2, 0, r2, carry, carry);
21.284 - MP_ADD_CARRY(r3, 0, r3, carry, carry);
21.285 - }
21.286 - MP_SUB_BORROW(r0, r3b, r0, 0, carry);
21.287 - if (carry) {
21.288 - MP_SUB_BORROW(r1, 0, r1, carry, carry);
21.289 - MP_SUB_BORROW(r2, 0, r2, carry, carry);
21.290 - MP_SUB_BORROW(r3, 0, r3, carry, carry);
21.291 - }
21.292 - r3b = (int)(r3 >>32);
21.293 - }
21.294 -
21.295 - while (r3b < 0) {
21.296 - MP_ADD_CARRY (r0, 1, r0, 0, carry);
21.297 - MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry);
21.298 - MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry);
21.299 - MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry);
21.300 - r3b = (int)(r3 >>32);
21.301 - }
21.302 - /* check for final reduction */
21.303 - /* now the only way we are over is if the top 4 words are all ones */
21.304 - if ((r3 == (MP_DIGIT_MAX >> 32)) && (r2 == MP_DIGIT_MAX)
21.305 - && ((r1 & MP_DIGIT_MAX << 32)== MP_DIGIT_MAX << 32) &&
21.306 - ((r1 != MP_DIGIT_MAX << 32 ) || (r0 != 0)) ) {
21.307 - /* one last subraction */
21.308 - MP_SUB_BORROW(r0, 1, r0, 0, carry);
21.309 - MP_SUB_BORROW(r1, 0, r1, carry, carry);
21.310 - r2 = r3 = 0;
21.311 - }
21.312 -
21.313 -
21.314 - if (a != r) {
21.315 - MP_CHECKOK(s_mp_pad(r, 4));
21.316 - }
21.317 - /* set the lower words of r */
21.318 - MP_SIGN(r) = MP_ZPOS;
21.319 - MP_USED(r) = 4;
21.320 - MP_DIGIT(r, 3) = r3;
21.321 - MP_DIGIT(r, 2) = r2;
21.322 - MP_DIGIT(r, 1) = r1;
21.323 - MP_DIGIT(r, 0) = r0;
21.324 -#endif
21.325 - }
21.326 -
21.327 - CLEANUP:
21.328 - return res;
21.329 -}
21.330 -
21.331 -/* Compute the square of polynomial a, reduce modulo p224. Store the
21.332 - * result in r. r could be a. Uses optimized modular reduction for p224.
21.333 - */
21.334 -mp_err
21.335 -ec_GFp_nistp224_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
21.336 -{
21.337 - mp_err res = MP_OKAY;
21.338 -
21.339 - MP_CHECKOK(mp_sqr(a, r));
21.340 - MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
21.341 - CLEANUP:
21.342 - return res;
21.343 -}
21.344 -
21.345 -/* Compute the product of two polynomials a and b, reduce modulo p224.
21.346 - * Store the result in r. r could be a or b; a could be b. Uses
21.347 - * optimized modular reduction for p224. */
21.348 -mp_err
21.349 -ec_GFp_nistp224_mul(const mp_int *a, const mp_int *b, mp_int *r,
21.350 - const GFMethod *meth)
21.351 -{
21.352 - mp_err res = MP_OKAY;
21.353 -
21.354 - MP_CHECKOK(mp_mul(a, b, r));
21.355 - MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
21.356 - CLEANUP:
21.357 - return res;
21.358 -}
21.359 -
21.360 -/* Divides two field elements. If a is NULL, then returns the inverse of
21.361 - * b. */
21.362 -mp_err
21.363 -ec_GFp_nistp224_div(const mp_int *a, const mp_int *b, mp_int *r,
21.364 - const GFMethod *meth)
21.365 -{
21.366 - mp_err res = MP_OKAY;
21.367 - mp_int t;
21.368 -
21.369 - /* If a is NULL, then return the inverse of b, otherwise return a/b. */
21.370 - if (a == NULL) {
21.371 - return mp_invmod(b, &meth->irr, r);
21.372 - } else {
21.373 - /* MPI doesn't support divmod, so we implement it using invmod and
21.374 - * mulmod. */
21.375 - MP_CHECKOK(mp_init(&t, FLAG(b)));
21.376 - MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
21.377 - MP_CHECKOK(mp_mul(a, &t, r));
21.378 - MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
21.379 - CLEANUP:
21.380 - mp_clear(&t);
21.381 - return res;
21.382 - }
21.383 -}
21.384 -
21.385 -/* Wire in fast field arithmetic and precomputation of base point for
21.386 - * named curves. */
21.387 -mp_err
21.388 -ec_group_set_gfp224(ECGroup *group, ECCurveName name)
21.389 -{
21.390 - if (name == ECCurve_NIST_P224) {
21.391 - group->meth->field_mod = &ec_GFp_nistp224_mod;
21.392 - group->meth->field_mul = &ec_GFp_nistp224_mul;
21.393 - group->meth->field_sqr = &ec_GFp_nistp224_sqr;
21.394 - group->meth->field_div = &ec_GFp_nistp224_div;
21.395 - }
21.396 - return MP_OKAY;
21.397 -}
22.1 --- a/src/share/native/sun/security/ec/ecp_256.c Tue Oct 13 15:25:58 2009 -0700
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,451 +0,0 @@
22.4 -/* *********************************************************************
22.5 - *
22.6 - * Sun elects to have this file available under and governed by the
22.7 - * Mozilla Public License Version 1.1 ("MPL") (see
22.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
22.9 - * of doubt and subject to the following, Sun also elects to allow
22.10 - * licensees to use this file under the MPL, the GNU General Public
22.11 - * License version 2 only or the Lesser General Public License version
22.12 - * 2.1 only. Any references to the "GNU General Public License version 2
22.13 - * or later" or "GPL" in the following shall be construed to mean the
22.14 - * GNU General Public License version 2 only. Any references to the "GNU
22.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
22.16 - * following shall be construed to mean the GNU Lesser General Public
22.17 - * License version 2.1 only. However, the following notice accompanied
22.18 - * the original version of this file:
22.19 - *
22.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
22.21 - *
22.22 - * The contents of this file are subject to the Mozilla Public License Version
22.23 - * 1.1 (the "License"); you may not use this file except in compliance with
22.24 - * the License. You may obtain a copy of the License at
22.25 - * http://www.mozilla.org/MPL/
22.26 - *
22.27 - * Software distributed under the License is distributed on an "AS IS" basis,
22.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
22.29 - * for the specific language governing rights and limitations under the
22.30 - * License.
22.31 - *
22.32 - * The Original Code is the elliptic curve math library for prime field curves.
22.33 - *
22.34 - * The Initial Developer of the Original Code is
22.35 - * Sun Microsystems, Inc.
22.36 - * Portions created by the Initial Developer are Copyright (C) 2003
22.37 - * the Initial Developer. All Rights Reserved.
22.38 - *
22.39 - * Contributor(s):
22.40 - * Douglas Stebila <douglas@stebila.ca>
22.41 - *
22.42 - * Alternatively, the contents of this file may be used under the terms of
22.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
22.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
22.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
22.46 - * of those above. If you wish to allow use of your version of this file only
22.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
22.48 - * use your version of this file under the terms of the MPL, indicate your
22.49 - * decision by deleting the provisions above and replace them with the notice
22.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
22.51 - * the provisions above, a recipient may use your version of this file under
22.52 - * the terms of any one of the MPL, the GPL or the LGPL.
22.53 - *
22.54 - *********************************************************************** */
22.55 -/*
22.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
22.57 - * Use is subject to license terms.
22.58 - */
22.59 -
22.60 -#pragma ident "%Z%%M% %I% %E% SMI"
22.61 -
22.62 -#include "ecp.h"
22.63 -#include "mpi.h"
22.64 -#include "mplogic.h"
22.65 -#include "mpi-priv.h"
22.66 -#ifndef _KERNEL
22.67 -#include <stdlib.h>
22.68 -#endif
22.69 -
22.70 -/* Fast modular reduction for p256 = 2^256 - 2^224 + 2^192+ 2^96 - 1. a can be r.
22.71 - * Uses algorithm 2.29 from Hankerson, Menezes, Vanstone. Guide to
22.72 - * Elliptic Curve Cryptography. */
22.73 -mp_err
22.74 -ec_GFp_nistp256_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
22.75 -{
22.76 - mp_err res = MP_OKAY;
22.77 - mp_size a_used = MP_USED(a);
22.78 - int a_bits = mpl_significant_bits(a);
22.79 - mp_digit carry;
22.80 -
22.81 -#ifdef ECL_THIRTY_TWO_BIT
22.82 - mp_digit a8=0, a9=0, a10=0, a11=0, a12=0, a13=0, a14=0, a15=0;
22.83 - mp_digit r0, r1, r2, r3, r4, r5, r6, r7;
22.84 - int r8; /* must be a signed value ! */
22.85 -#else
22.86 - mp_digit a4=0, a5=0, a6=0, a7=0;
22.87 - mp_digit a4h, a4l, a5h, a5l, a6h, a6l, a7h, a7l;
22.88 - mp_digit r0, r1, r2, r3;
22.89 - int r4; /* must be a signed value ! */
22.90 -#endif
22.91 - /* for polynomials larger than twice the field size
22.92 - * use regular reduction */
22.93 - if (a_bits < 256) {
22.94 - if (a == r) return MP_OKAY;
22.95 - return mp_copy(a,r);
22.96 - }
22.97 - if (a_bits > 512) {
22.98 - MP_CHECKOK(mp_mod(a, &meth->irr, r));
22.99 - } else {
22.100 -
22.101 -#ifdef ECL_THIRTY_TWO_BIT
22.102 - switch (a_used) {
22.103 - case 16:
22.104 - a15 = MP_DIGIT(a,15);
22.105 - case 15:
22.106 - a14 = MP_DIGIT(a,14);
22.107 - case 14:
22.108 - a13 = MP_DIGIT(a,13);
22.109 - case 13:
22.110 - a12 = MP_DIGIT(a,12);
22.111 - case 12:
22.112 - a11 = MP_DIGIT(a,11);
22.113 - case 11:
22.114 - a10 = MP_DIGIT(a,10);
22.115 - case 10:
22.116 - a9 = MP_DIGIT(a,9);
22.117 - case 9:
22.118 - a8 = MP_DIGIT(a,8);
22.119 - }
22.120 -
22.121 - r0 = MP_DIGIT(a,0);
22.122 - r1 = MP_DIGIT(a,1);
22.123 - r2 = MP_DIGIT(a,2);
22.124 - r3 = MP_DIGIT(a,3);
22.125 - r4 = MP_DIGIT(a,4);
22.126 - r5 = MP_DIGIT(a,5);
22.127 - r6 = MP_DIGIT(a,6);
22.128 - r7 = MP_DIGIT(a,7);
22.129 -
22.130 - /* sum 1 */
22.131 - MP_ADD_CARRY(r3, a11, r3, 0, carry);
22.132 - MP_ADD_CARRY(r4, a12, r4, carry, carry);
22.133 - MP_ADD_CARRY(r5, a13, r5, carry, carry);
22.134 - MP_ADD_CARRY(r6, a14, r6, carry, carry);
22.135 - MP_ADD_CARRY(r7, a15, r7, carry, carry);
22.136 - r8 = carry;
22.137 - MP_ADD_CARRY(r3, a11, r3, 0, carry);
22.138 - MP_ADD_CARRY(r4, a12, r4, carry, carry);
22.139 - MP_ADD_CARRY(r5, a13, r5, carry, carry);
22.140 - MP_ADD_CARRY(r6, a14, r6, carry, carry);
22.141 - MP_ADD_CARRY(r7, a15, r7, carry, carry);
22.142 - r8 += carry;
22.143 - /* sum 2 */
22.144 - MP_ADD_CARRY(r3, a12, r3, 0, carry);
22.145 - MP_ADD_CARRY(r4, a13, r4, carry, carry);
22.146 - MP_ADD_CARRY(r5, a14, r5, carry, carry);
22.147 - MP_ADD_CARRY(r6, a15, r6, carry, carry);
22.148 - MP_ADD_CARRY(r7, 0, r7, carry, carry);
22.149 - r8 += carry;
22.150 - /* combine last bottom of sum 3 with second sum 2 */
22.151 - MP_ADD_CARRY(r0, a8, r0, 0, carry);
22.152 - MP_ADD_CARRY(r1, a9, r1, carry, carry);
22.153 - MP_ADD_CARRY(r2, a10, r2, carry, carry);
22.154 - MP_ADD_CARRY(r3, a12, r3, carry, carry);
22.155 - MP_ADD_CARRY(r4, a13, r4, carry, carry);
22.156 - MP_ADD_CARRY(r5, a14, r5, carry, carry);
22.157 - MP_ADD_CARRY(r6, a15, r6, carry, carry);
22.158 - MP_ADD_CARRY(r7, a15, r7, carry, carry); /* from sum 3 */
22.159 - r8 += carry;
22.160 - /* sum 3 (rest of it)*/
22.161 - MP_ADD_CARRY(r6, a14, r6, 0, carry);
22.162 - MP_ADD_CARRY(r7, 0, r7, carry, carry);
22.163 - r8 += carry;
22.164 - /* sum 4 (rest of it)*/
22.165 - MP_ADD_CARRY(r0, a9, r0, 0, carry);
22.166 - MP_ADD_CARRY(r1, a10, r1, carry, carry);
22.167 - MP_ADD_CARRY(r2, a11, r2, carry, carry);
22.168 - MP_ADD_CARRY(r3, a13, r3, carry, carry);
22.169 - MP_ADD_CARRY(r4, a14, r4, carry, carry);
22.170 - MP_ADD_CARRY(r5, a15, r5, carry, carry);
22.171 - MP_ADD_CARRY(r6, a13, r6, carry, carry);
22.172 - MP_ADD_CARRY(r7, a8, r7, carry, carry);
22.173 - r8 += carry;
22.174 - /* diff 5 */
22.175 - MP_SUB_BORROW(r0, a11, r0, 0, carry);
22.176 - MP_SUB_BORROW(r1, a12, r1, carry, carry);
22.177 - MP_SUB_BORROW(r2, a13, r2, carry, carry);
22.178 - MP_SUB_BORROW(r3, 0, r3, carry, carry);
22.179 - MP_SUB_BORROW(r4, 0, r4, carry, carry);
22.180 - MP_SUB_BORROW(r5, 0, r5, carry, carry);
22.181 - MP_SUB_BORROW(r6, a8, r6, carry, carry);
22.182 - MP_SUB_BORROW(r7, a10, r7, carry, carry);
22.183 - r8 -= carry;
22.184 - /* diff 6 */
22.185 - MP_SUB_BORROW(r0, a12, r0, 0, carry);
22.186 - MP_SUB_BORROW(r1, a13, r1, carry, carry);
22.187 - MP_SUB_BORROW(r2, a14, r2, carry, carry);
22.188 - MP_SUB_BORROW(r3, a15, r3, carry, carry);
22.189 - MP_SUB_BORROW(r4, 0, r4, carry, carry);
22.190 - MP_SUB_BORROW(r5, 0, r5, carry, carry);
22.191 - MP_SUB_BORROW(r6, a9, r6, carry, carry);
22.192 - MP_SUB_BORROW(r7, a11, r7, carry, carry);
22.193 - r8 -= carry;
22.194 - /* diff 7 */
22.195 - MP_SUB_BORROW(r0, a13, r0, 0, carry);
22.196 - MP_SUB_BORROW(r1, a14, r1, carry, carry);
22.197 - MP_SUB_BORROW(r2, a15, r2, carry, carry);
22.198 - MP_SUB_BORROW(r3, a8, r3, carry, carry);
22.199 - MP_SUB_BORROW(r4, a9, r4, carry, carry);
22.200 - MP_SUB_BORROW(r5, a10, r5, carry, carry);
22.201 - MP_SUB_BORROW(r6, 0, r6, carry, carry);
22.202 - MP_SUB_BORROW(r7, a12, r7, carry, carry);
22.203 - r8 -= carry;
22.204 - /* diff 8 */
22.205 - MP_SUB_BORROW(r0, a14, r0, 0, carry);
22.206 - MP_SUB_BORROW(r1, a15, r1, carry, carry);
22.207 - MP_SUB_BORROW(r2, 0, r2, carry, carry);
22.208 - MP_SUB_BORROW(r3, a9, r3, carry, carry);
22.209 - MP_SUB_BORROW(r4, a10, r4, carry, carry);
22.210 - MP_SUB_BORROW(r5, a11, r5, carry, carry);
22.211 - MP_SUB_BORROW(r6, 0, r6, carry, carry);
22.212 - MP_SUB_BORROW(r7, a13, r7, carry, carry);
22.213 - r8 -= carry;
22.214 -
22.215 - /* reduce the overflows */
22.216 - while (r8 > 0) {
22.217 - mp_digit r8_d = r8;
22.218 - MP_ADD_CARRY(r0, r8_d, r0, 0, carry);
22.219 - MP_ADD_CARRY(r1, 0, r1, carry, carry);
22.220 - MP_ADD_CARRY(r2, 0, r2, carry, carry);
22.221 - MP_ADD_CARRY(r3, -r8_d, r3, carry, carry);
22.222 - MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry, carry);
22.223 - MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry, carry);
22.224 - MP_ADD_CARRY(r6, -(r8_d+1), r6, carry, carry);
22.225 - MP_ADD_CARRY(r7, (r8_d-1), r7, carry, carry);
22.226 - r8 = carry;
22.227 - }
22.228 -
22.229 - /* reduce the underflows */
22.230 - while (r8 < 0) {
22.231 - mp_digit r8_d = -r8;
22.232 - MP_SUB_BORROW(r0, r8_d, r0, 0, carry);
22.233 - MP_SUB_BORROW(r1, 0, r1, carry, carry);
22.234 - MP_SUB_BORROW(r2, 0, r2, carry, carry);
22.235 - MP_SUB_BORROW(r3, -r8_d, r3, carry, carry);
22.236 - MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry, carry);
22.237 - MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry, carry);
22.238 - MP_SUB_BORROW(r6, -(r8_d+1), r6, carry, carry);
22.239 - MP_SUB_BORROW(r7, (r8_d-1), r7, carry, carry);
22.240 - r8 = -carry;
22.241 - }
22.242 - if (a != r) {
22.243 - MP_CHECKOK(s_mp_pad(r,8));
22.244 - }
22.245 - MP_SIGN(r) = MP_ZPOS;
22.246 - MP_USED(r) = 8;
22.247 -
22.248 - MP_DIGIT(r,7) = r7;
22.249 - MP_DIGIT(r,6) = r6;
22.250 - MP_DIGIT(r,5) = r5;
22.251 - MP_DIGIT(r,4) = r4;
22.252 - MP_DIGIT(r,3) = r3;
22.253 - MP_DIGIT(r,2) = r2;
22.254 - MP_DIGIT(r,1) = r1;
22.255 - MP_DIGIT(r,0) = r0;
22.256 -
22.257 - /* final reduction if necessary */
22.258 - if ((r7 == MP_DIGIT_MAX) &&
22.259 - ((r6 > 1) || ((r6 == 1) &&
22.260 - (r5 || r4 || r3 ||
22.261 - ((r2 == MP_DIGIT_MAX) && (r1 == MP_DIGIT_MAX)
22.262 - && (r0 == MP_DIGIT_MAX)))))) {
22.263 - MP_CHECKOK(mp_sub(r, &meth->irr, r));
22.264 - }
22.265 -#ifdef notdef
22.266 -
22.267 -
22.268 - /* smooth the negatives */
22.269 - while (MP_SIGN(r) != MP_ZPOS) {
22.270 - MP_CHECKOK(mp_add(r, &meth->irr, r));
22.271 - }
22.272 - while (MP_USED(r) > 8) {
22.273 - MP_CHECKOK(mp_sub(r, &meth->irr, r));
22.274 - }
22.275 -
22.276 - /* final reduction if necessary */
22.277 - if (MP_DIGIT(r,7) >= MP_DIGIT(&meth->irr,7)) {
22.278 - if (mp_cmp(r,&meth->irr) != MP_LT) {
22.279 - MP_CHECKOK(mp_sub(r, &meth->irr, r));
22.280 - }
22.281 - }
22.282 -#endif
22.283 - s_mp_clamp(r);
22.284 -#else
22.285 - switch (a_used) {
22.286 - case 8:
22.287 - a7 = MP_DIGIT(a,7);
22.288 - case 7:
22.289 - a6 = MP_DIGIT(a,6);
22.290 - case 6:
22.291 - a5 = MP_DIGIT(a,5);
22.292 - case 5:
22.293 - a4 = MP_DIGIT(a,4);
22.294 - }
22.295 - a7l = a7 << 32;
22.296 - a7h = a7 >> 32;
22.297 - a6l = a6 << 32;
22.298 - a6h = a6 >> 32;
22.299 - a5l = a5 << 32;
22.300 - a5h = a5 >> 32;
22.301 - a4l = a4 << 32;
22.302 - a4h = a4 >> 32;
22.303 - r3 = MP_DIGIT(a,3);
22.304 - r2 = MP_DIGIT(a,2);
22.305 - r1 = MP_DIGIT(a,1);
22.306 - r0 = MP_DIGIT(a,0);
22.307 -
22.308 - /* sum 1 */
22.309 - MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
22.310 - MP_ADD_CARRY(r2, a6, r2, carry, carry);
22.311 - MP_ADD_CARRY(r3, a7, r3, carry, carry);
22.312 - r4 = carry;
22.313 - MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
22.314 - MP_ADD_CARRY(r2, a6, r2, carry, carry);
22.315 - MP_ADD_CARRY(r3, a7, r3, carry, carry);
22.316 - r4 += carry;
22.317 - /* sum 2 */
22.318 - MP_ADD_CARRY(r1, a6l, r1, 0, carry);
22.319 - MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
22.320 - MP_ADD_CARRY(r3, a7h, r3, carry, carry);
22.321 - r4 += carry;
22.322 - MP_ADD_CARRY(r1, a6l, r1, 0, carry);
22.323 - MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
22.324 - MP_ADD_CARRY(r3, a7h, r3, carry, carry);
22.325 - r4 += carry;
22.326 -
22.327 - /* sum 3 */
22.328 - MP_ADD_CARRY(r0, a4, r0, 0, carry);
22.329 - MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry);
22.330 - MP_ADD_CARRY(r2, 0, r2, carry, carry);
22.331 - MP_ADD_CARRY(r3, a7, r3, carry, carry);
22.332 - r4 += carry;
22.333 - /* sum 4 */
22.334 - MP_ADD_CARRY(r0, a4h | a5l, r0, 0, carry);
22.335 - MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry);
22.336 - MP_ADD_CARRY(r2, a7, r2, carry, carry);
22.337 - MP_ADD_CARRY(r3, a6h | a4l, r3, carry, carry);
22.338 - r4 += carry;
22.339 - /* diff 5 */
22.340 - MP_SUB_BORROW(r0, a5h | a6l, r0, 0, carry);
22.341 - MP_SUB_BORROW(r1, a6h, r1, carry, carry);
22.342 - MP_SUB_BORROW(r2, 0, r2, carry, carry);
22.343 - MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry, carry);
22.344 - r4 -= carry;
22.345 - /* diff 6 */
22.346 - MP_SUB_BORROW(r0, a6, r0, 0, carry);
22.347 - MP_SUB_BORROW(r1, a7, r1, carry, carry);
22.348 - MP_SUB_BORROW(r2, 0, r2, carry, carry);
22.349 - MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry, carry);
22.350 - r4 -= carry;
22.351 - /* diff 7 */
22.352 - MP_SUB_BORROW(r0, a6h|a7l, r0, 0, carry);
22.353 - MP_SUB_BORROW(r1, a7h|a4l, r1, carry, carry);
22.354 - MP_SUB_BORROW(r2, a4h|a5l, r2, carry, carry);
22.355 - MP_SUB_BORROW(r3, a6l, r3, carry, carry);
22.356 - r4 -= carry;
22.357 - /* diff 8 */
22.358 - MP_SUB_BORROW(r0, a7, r0, 0, carry);
22.359 - MP_SUB_BORROW(r1, a4h<<32, r1, carry, carry);
22.360 - MP_SUB_BORROW(r2, a5, r2, carry, carry);
22.361 - MP_SUB_BORROW(r3, a6h<<32, r3, carry, carry);
22.362 - r4 -= carry;
22.363 -
22.364 - /* reduce the overflows */
22.365 - while (r4 > 0) {
22.366 - mp_digit r4_long = r4;
22.367 - mp_digit r4l = (r4_long << 32);
22.368 - MP_ADD_CARRY(r0, r4_long, r0, 0, carry);
22.369 - MP_ADD_CARRY(r1, -r4l, r1, carry, carry);
22.370 - MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry);
22.371 - MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry);
22.372 - r4 = carry;
22.373 - }
22.374 -
22.375 - /* reduce the underflows */
22.376 - while (r4 < 0) {
22.377 - mp_digit r4_long = -r4;
22.378 - mp_digit r4l = (r4_long << 32);
22.379 - MP_SUB_BORROW(r0, r4_long, r0, 0, carry);
22.380 - MP_SUB_BORROW(r1, -r4l, r1, carry, carry);
22.381 - MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry, carry);
22.382 - MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry, carry);
22.383 - r4 = -carry;
22.384 - }
22.385 -
22.386 - if (a != r) {
22.387 - MP_CHECKOK(s_mp_pad(r,4));
22.388 - }
22.389 - MP_SIGN(r) = MP_ZPOS;
22.390 - MP_USED(r) = 4;
22.391 -
22.392 - MP_DIGIT(r,3) = r3;
22.393 - MP_DIGIT(r,2) = r2;
22.394 - MP_DIGIT(r,1) = r1;
22.395 - MP_DIGIT(r,0) = r0;
22.396 -
22.397 - /* final reduction if necessary */
22.398 - if ((r3 > 0xFFFFFFFF00000001ULL) ||
22.399 - ((r3 == 0xFFFFFFFF00000001ULL) &&
22.400 - (r2 || (r1 >> 32)||
22.401 - (r1 == 0xFFFFFFFFULL && r0 == MP_DIGIT_MAX)))) {
22.402 - /* very rare, just use mp_sub */
22.403 - MP_CHECKOK(mp_sub(r, &meth->irr, r));
22.404 - }
22.405 -
22.406 - s_mp_clamp(r);
22.407 -#endif
22.408 - }
22.409 -
22.410 - CLEANUP:
22.411 - return res;
22.412 -}
22.413 -
22.414 -/* Compute the square of polynomial a, reduce modulo p256. Store the
22.415 - * result in r. r could be a. Uses optimized modular reduction for p256.
22.416 - */
22.417 -mp_err
22.418 -ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
22.419 -{
22.420 - mp_err res = MP_OKAY;
22.421 -
22.422 - MP_CHECKOK(mp_sqr(a, r));
22.423 - MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
22.424 - CLEANUP:
22.425 - return res;
22.426 -}
22.427 -
22.428 -/* Compute the product of two polynomials a and b, reduce modulo p256.
22.429 - * Store the result in r. r could be a or b; a could be b. Uses
22.430 - * optimized modular reduction for p256. */
22.431 -mp_err
22.432 -ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r,
22.433 - const GFMethod *meth)
22.434 -{
22.435 - mp_err res = MP_OKAY;
22.436 -
22.437 - MP_CHECKOK(mp_mul(a, b, r));
22.438 - MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
22.439 - CLEANUP:
22.440 - return res;
22.441 -}
22.442 -
22.443 -/* Wire in fast field arithmetic and precomputation of base point for
22.444 - * named curves. */
22.445 -mp_err
22.446 -ec_group_set_gfp256(ECGroup *group, ECCurveName name)
22.447 -{
22.448 - if (name == ECCurve_NIST_P256) {
22.449 - group->meth->field_mod = &ec_GFp_nistp256_mod;
22.450 - group->meth->field_mul = &ec_GFp_nistp256_mul;
22.451 - group->meth->field_sqr = &ec_GFp_nistp256_sqr;
22.452 - }
22.453 - return MP_OKAY;
22.454 -}
23.1 --- a/src/share/native/sun/security/ec/ecp_384.c Tue Oct 13 15:25:58 2009 -0700
23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3 @@ -1,315 +0,0 @@
23.4 -/* *********************************************************************
23.5 - *
23.6 - * Sun elects to have this file available under and governed by the
23.7 - * Mozilla Public License Version 1.1 ("MPL") (see
23.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
23.9 - * of doubt and subject to the following, Sun also elects to allow
23.10 - * licensees to use this file under the MPL, the GNU General Public
23.11 - * License version 2 only or the Lesser General Public License version
23.12 - * 2.1 only. Any references to the "GNU General Public License version 2
23.13 - * or later" or "GPL" in the following shall be construed to mean the
23.14 - * GNU General Public License version 2 only. Any references to the "GNU
23.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
23.16 - * following shall be construed to mean the GNU Lesser General Public
23.17 - * License version 2.1 only. However, the following notice accompanied
23.18 - * the original version of this file:
23.19 - *
23.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
23.21 - *
23.22 - * The contents of this file are subject to the Mozilla Public License Version
23.23 - * 1.1 (the "License"); you may not use this file except in compliance with
23.24 - * the License. You may obtain a copy of the License at
23.25 - * http://www.mozilla.org/MPL/
23.26 - *
23.27 - * Software distributed under the License is distributed on an "AS IS" basis,
23.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
23.29 - * for the specific language governing rights and limitations under the
23.30 - * License.
23.31 - *
23.32 - * The Original Code is the elliptic curve math library for prime field curves.
23.33 - *
23.34 - * The Initial Developer of the Original Code is
23.35 - * Sun Microsystems, Inc.
23.36 - * Portions created by the Initial Developer are Copyright (C) 2003
23.37 - * the Initial Developer. All Rights Reserved.
23.38 - *
23.39 - * Contributor(s):
23.40 - * Douglas Stebila <douglas@stebila.ca>
23.41 - *
23.42 - * Alternatively, the contents of this file may be used under the terms of
23.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
23.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
23.46 - * of those above. If you wish to allow use of your version of this file only
23.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
23.48 - * use your version of this file under the terms of the MPL, indicate your
23.49 - * decision by deleting the provisions above and replace them with the notice
23.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
23.51 - * the provisions above, a recipient may use your version of this file under
23.52 - * the terms of any one of the MPL, the GPL or the LGPL.
23.53 - *
23.54 - *********************************************************************** */
23.55 -/*
23.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23.57 - * Use is subject to license terms.
23.58 - */
23.59 -
23.60 -#pragma ident "%Z%%M% %I% %E% SMI"
23.61 -
23.62 -#include "ecp.h"
23.63 -#include "mpi.h"
23.64 -#include "mplogic.h"
23.65 -#include "mpi-priv.h"
23.66 -#ifndef _KERNEL
23.67 -#include <stdlib.h>
23.68 -#endif
23.69 -
23.70 -/* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1. a can be r.
23.71 - * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to
23.72 - * Elliptic Curve Cryptography. */
23.73 -mp_err
23.74 -ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
23.75 -{
23.76 - mp_err res = MP_OKAY;
23.77 - int a_bits = mpl_significant_bits(a);
23.78 - int i;
23.79 -
23.80 - /* m1, m2 are statically-allocated mp_int of exactly the size we need */
23.81 - mp_int m[10];
23.82 -
23.83 -#ifdef ECL_THIRTY_TWO_BIT
23.84 - mp_digit s[10][12];
23.85 - for (i = 0; i < 10; i++) {
23.86 - MP_SIGN(&m[i]) = MP_ZPOS;
23.87 - MP_ALLOC(&m[i]) = 12;
23.88 - MP_USED(&m[i]) = 12;
23.89 - MP_DIGITS(&m[i]) = s[i];
23.90 - }
23.91 -#else
23.92 - mp_digit s[10][6];
23.93 - for (i = 0; i < 10; i++) {
23.94 - MP_SIGN(&m[i]) = MP_ZPOS;
23.95 - MP_ALLOC(&m[i]) = 6;
23.96 - MP_USED(&m[i]) = 6;
23.97 - MP_DIGITS(&m[i]) = s[i];
23.98 - }
23.99 -#endif
23.100 -
23.101 -#ifdef ECL_THIRTY_TWO_BIT
23.102 - /* for polynomials larger than twice the field size or polynomials
23.103 - * not using all words, use regular reduction */
23.104 - if ((a_bits > 768) || (a_bits <= 736)) {
23.105 - MP_CHECKOK(mp_mod(a, &meth->irr, r));
23.106 - } else {
23.107 - for (i = 0; i < 12; i++) {
23.108 - s[0][i] = MP_DIGIT(a, i);
23.109 - }
23.110 - s[1][0] = 0;
23.111 - s[1][1] = 0;
23.112 - s[1][2] = 0;
23.113 - s[1][3] = 0;
23.114 - s[1][4] = MP_DIGIT(a, 21);
23.115 - s[1][5] = MP_DIGIT(a, 22);
23.116 - s[1][6] = MP_DIGIT(a, 23);
23.117 - s[1][7] = 0;
23.118 - s[1][8] = 0;
23.119 - s[1][9] = 0;
23.120 - s[1][10] = 0;
23.121 - s[1][11] = 0;
23.122 - for (i = 0; i < 12; i++) {
23.123 - s[2][i] = MP_DIGIT(a, i+12);
23.124 - }
23.125 - s[3][0] = MP_DIGIT(a, 21);
23.126 - s[3][1] = MP_DIGIT(a, 22);
23.127 - s[3][2] = MP_DIGIT(a, 23);
23.128 - for (i = 3; i < 12; i++) {
23.129 - s[3][i] = MP_DIGIT(a, i+9);
23.130 - }
23.131 - s[4][0] = 0;
23.132 - s[4][1] = MP_DIGIT(a, 23);
23.133 - s[4][2] = 0;
23.134 - s[4][3] = MP_DIGIT(a, 20);
23.135 - for (i = 4; i < 12; i++) {
23.136 - s[4][i] = MP_DIGIT(a, i+8);
23.137 - }
23.138 - s[5][0] = 0;
23.139 - s[5][1] = 0;
23.140 - s[5][2] = 0;
23.141 - s[5][3] = 0;
23.142 - s[5][4] = MP_DIGIT(a, 20);
23.143 - s[5][5] = MP_DIGIT(a, 21);
23.144 - s[5][6] = MP_DIGIT(a, 22);
23.145 - s[5][7] = MP_DIGIT(a, 23);
23.146 - s[5][8] = 0;
23.147 - s[5][9] = 0;
23.148 - s[5][10] = 0;
23.149 - s[5][11] = 0;
23.150 - s[6][0] = MP_DIGIT(a, 20);
23.151 - s[6][1] = 0;
23.152 - s[6][2] = 0;
23.153 - s[6][3] = MP_DIGIT(a, 21);
23.154 - s[6][4] = MP_DIGIT(a, 22);
23.155 - s[6][5] = MP_DIGIT(a, 23);
23.156 - s[6][6] = 0;
23.157 - s[6][7] = 0;
23.158 - s[6][8] = 0;
23.159 - s[6][9] = 0;
23.160 - s[6][10] = 0;
23.161 - s[6][11] = 0;
23.162 - s[7][0] = MP_DIGIT(a, 23);
23.163 - for (i = 1; i < 12; i++) {
23.164 - s[7][i] = MP_DIGIT(a, i+11);
23.165 - }
23.166 - s[8][0] = 0;
23.167 - s[8][1] = MP_DIGIT(a, 20);
23.168 - s[8][2] = MP_DIGIT(a, 21);
23.169 - s[8][3] = MP_DIGIT(a, 22);
23.170 - s[8][4] = MP_DIGIT(a, 23);
23.171 - s[8][5] = 0;
23.172 - s[8][6] = 0;
23.173 - s[8][7] = 0;
23.174 - s[8][8] = 0;
23.175 - s[8][9] = 0;
23.176 - s[8][10] = 0;
23.177 - s[8][11] = 0;
23.178 - s[9][0] = 0;
23.179 - s[9][1] = 0;
23.180 - s[9][2] = 0;
23.181 - s[9][3] = MP_DIGIT(a, 23);
23.182 - s[9][4] = MP_DIGIT(a, 23);
23.183 - s[9][5] = 0;
23.184 - s[9][6] = 0;
23.185 - s[9][7] = 0;
23.186 - s[9][8] = 0;
23.187 - s[9][9] = 0;
23.188 - s[9][10] = 0;
23.189 - s[9][11] = 0;
23.190 -
23.191 - MP_CHECKOK(mp_add(&m[0], &m[1], r));
23.192 - MP_CHECKOK(mp_add(r, &m[1], r));
23.193 - MP_CHECKOK(mp_add(r, &m[2], r));
23.194 - MP_CHECKOK(mp_add(r, &m[3], r));
23.195 - MP_CHECKOK(mp_add(r, &m[4], r));
23.196 - MP_CHECKOK(mp_add(r, &m[5], r));
23.197 - MP_CHECKOK(mp_add(r, &m[6], r));
23.198 - MP_CHECKOK(mp_sub(r, &m[7], r));
23.199 - MP_CHECKOK(mp_sub(r, &m[8], r));
23.200 - MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
23.201 - s_mp_clamp(r);
23.202 - }
23.203 -#else
23.204 - /* for polynomials larger than twice the field size or polynomials
23.205 - * not using all words, use regular reduction */
23.206 - if ((a_bits > 768) || (a_bits <= 736)) {
23.207 - MP_CHECKOK(mp_mod(a, &meth->irr, r));
23.208 - } else {
23.209 - for (i = 0; i < 6; i++) {
23.210 - s[0][i] = MP_DIGIT(a, i);
23.211 - }
23.212 - s[1][0] = 0;
23.213 - s[1][1] = 0;
23.214 - s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
23.215 - s[1][3] = MP_DIGIT(a, 11) >> 32;
23.216 - s[1][4] = 0;
23.217 - s[1][5] = 0;
23.218 - for (i = 0; i < 6; i++) {
23.219 - s[2][i] = MP_DIGIT(a, i+6);
23.220 - }
23.221 - s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
23.222 - s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
23.223 - for (i = 2; i < 6; i++) {
23.224 - s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32);
23.225 - }
23.226 - s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32;
23.227 - s[4][1] = MP_DIGIT(a, 10) << 32;
23.228 - for (i = 2; i < 6; i++) {
23.229 - s[4][i] = MP_DIGIT(a, i+4);
23.230 - }
23.231 - s[5][0] = 0;
23.232 - s[5][1] = 0;
23.233 - s[5][2] = MP_DIGIT(a, 10);
23.234 - s[5][3] = MP_DIGIT(a, 11);
23.235 - s[5][4] = 0;
23.236 - s[5][5] = 0;
23.237 - s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32;
23.238 - s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32;
23.239 - s[6][2] = MP_DIGIT(a, 11);
23.240 - s[6][3] = 0;
23.241 - s[6][4] = 0;
23.242 - s[6][5] = 0;
23.243 - s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
23.244 - for (i = 1; i < 6; i++) {
23.245 - s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32);
23.246 - }
23.247 - s[8][0] = MP_DIGIT(a, 10) << 32;
23.248 - s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
23.249 - s[8][2] = MP_DIGIT(a, 11) >> 32;
23.250 - s[8][3] = 0;
23.251 - s[8][4] = 0;
23.252 - s[8][5] = 0;
23.253 - s[9][0] = 0;
23.254 - s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32;
23.255 - s[9][2] = MP_DIGIT(a, 11) >> 32;
23.256 - s[9][3] = 0;
23.257 - s[9][4] = 0;
23.258 - s[9][5] = 0;
23.259 -
23.260 - MP_CHECKOK(mp_add(&m[0], &m[1], r));
23.261 - MP_CHECKOK(mp_add(r, &m[1], r));
23.262 - MP_CHECKOK(mp_add(r, &m[2], r));
23.263 - MP_CHECKOK(mp_add(r, &m[3], r));
23.264 - MP_CHECKOK(mp_add(r, &m[4], r));
23.265 - MP_CHECKOK(mp_add(r, &m[5], r));
23.266 - MP_CHECKOK(mp_add(r, &m[6], r));
23.267 - MP_CHECKOK(mp_sub(r, &m[7], r));
23.268 - MP_CHECKOK(mp_sub(r, &m[8], r));
23.269 - MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
23.270 - s_mp_clamp(r);
23.271 - }
23.272 -#endif
23.273 -
23.274 - CLEANUP:
23.275 - return res;
23.276 -}
23.277 -
23.278 -/* Compute the square of polynomial a, reduce modulo p384. Store the
23.279 - * result in r. r could be a. Uses optimized modular reduction for p384.
23.280 - */
23.281 -mp_err
23.282 -ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
23.283 -{
23.284 - mp_err res = MP_OKAY;
23.285 -
23.286 - MP_CHECKOK(mp_sqr(a, r));
23.287 - MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
23.288 - CLEANUP:
23.289 - return res;
23.290 -}
23.291 -
23.292 -/* Compute the product of two polynomials a and b, reduce modulo p384.
23.293 - * Store the result in r. r could be a or b; a could be b. Uses
23.294 - * optimized modular reduction for p384. */
23.295 -mp_err
23.296 -ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
23.297 - const GFMethod *meth)
23.298 -{
23.299 - mp_err res = MP_OKAY;
23.300 -
23.301 - MP_CHECKOK(mp_mul(a, b, r));
23.302 - MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
23.303 - CLEANUP:
23.304 - return res;
23.305 -}
23.306 -
23.307 -/* Wire in fast field arithmetic and precomputation of base point for
23.308 - * named curves. */
23.309 -mp_err
23.310 -ec_group_set_gfp384(ECGroup *group, ECCurveName name)
23.311 -{
23.312 - if (name == ECCurve_NIST_P384) {
23.313 - group->meth->field_mod = &ec_GFp_nistp384_mod;
23.314 - group->meth->field_mul = &ec_GFp_nistp384_mul;
23.315 - group->meth->field_sqr = &ec_GFp_nistp384_sqr;
23.316 - }
23.317 - return MP_OKAY;
23.318 -}
24.1 --- a/src/share/native/sun/security/ec/ecp_521.c Tue Oct 13 15:25:58 2009 -0700
24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3 @@ -1,192 +0,0 @@
24.4 -/* *********************************************************************
24.5 - *
24.6 - * Sun elects to have this file available under and governed by the
24.7 - * Mozilla Public License Version 1.1 ("MPL") (see
24.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
24.9 - * of doubt and subject to the following, Sun also elects to allow
24.10 - * licensees to use this file under the MPL, the GNU General Public
24.11 - * License version 2 only or the Lesser General Public License version
24.12 - * 2.1 only. Any references to the "GNU General Public License version 2
24.13 - * or later" or "GPL" in the following shall be construed to mean the
24.14 - * GNU General Public License version 2 only. Any references to the "GNU
24.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
24.16 - * following shall be construed to mean the GNU Lesser General Public
24.17 - * License version 2.1 only. However, the following notice accompanied
24.18 - * the original version of this file:
24.19 - *
24.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
24.21 - *
24.22 - * The contents of this file are subject to the Mozilla Public License Version
24.23 - * 1.1 (the "License"); you may not use this file except in compliance with
24.24 - * the License. You may obtain a copy of the License at
24.25 - * http://www.mozilla.org/MPL/
24.26 - *
24.27 - * Software distributed under the License is distributed on an "AS IS" basis,
24.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
24.29 - * for the specific language governing rights and limitations under the
24.30 - * License.
24.31 - *
24.32 - * The Original Code is the elliptic curve math library for prime field curves.
24.33 - *
24.34 - * The Initial Developer of the Original Code is
24.35 - * Sun Microsystems, Inc.
24.36 - * Portions created by the Initial Developer are Copyright (C) 2003
24.37 - * the Initial Developer. All Rights Reserved.
24.38 - *
24.39 - * Contributor(s):
24.40 - * Douglas Stebila <douglas@stebila.ca>
24.41 - *
24.42 - * Alternatively, the contents of this file may be used under the terms of
24.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
24.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
24.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
24.46 - * of those above. If you wish to allow use of your version of this file only
24.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
24.48 - * use your version of this file under the terms of the MPL, indicate your
24.49 - * decision by deleting the provisions above and replace them with the notice
24.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
24.51 - * the provisions above, a recipient may use your version of this file under
24.52 - * the terms of any one of the MPL, the GPL or the LGPL.
24.53 - *
24.54 - *********************************************************************** */
24.55 -/*
24.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24.57 - * Use is subject to license terms.
24.58 - */
24.59 -
24.60 -#pragma ident "%Z%%M% %I% %E% SMI"
24.61 -
24.62 -#include "ecp.h"
24.63 -#include "mpi.h"
24.64 -#include "mplogic.h"
24.65 -#include "mpi-priv.h"
24.66 -#ifndef _KERNEL
24.67 -#include <stdlib.h>
24.68 -#endif
24.69 -
24.70 -#define ECP521_DIGITS ECL_CURVE_DIGITS(521)
24.71 -
24.72 -/* Fast modular reduction for p521 = 2^521 - 1. a can be r. Uses
24.73 - * algorithm 2.31 from Hankerson, Menezes, Vanstone. Guide to
24.74 - * Elliptic Curve Cryptography. */
24.75 -mp_err
24.76 -ec_GFp_nistp521_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
24.77 -{
24.78 - mp_err res = MP_OKAY;
24.79 - int a_bits = mpl_significant_bits(a);
24.80 - int i;
24.81 -
24.82 - /* m1, m2 are statically-allocated mp_int of exactly the size we need */
24.83 - mp_int m1;
24.84 -
24.85 - mp_digit s1[ECP521_DIGITS] = { 0 };
24.86 -
24.87 - MP_SIGN(&m1) = MP_ZPOS;
24.88 - MP_ALLOC(&m1) = ECP521_DIGITS;
24.89 - MP_USED(&m1) = ECP521_DIGITS;
24.90 - MP_DIGITS(&m1) = s1;
24.91 -
24.92 - if (a_bits < 521) {
24.93 - if (a==r) return MP_OKAY;
24.94 - return mp_copy(a, r);
24.95 - }
24.96 - /* for polynomials larger than twice the field size or polynomials
24.97 - * not using all words, use regular reduction */
24.98 - if (a_bits > (521*2)) {
24.99 - MP_CHECKOK(mp_mod(a, &meth->irr, r));
24.100 - } else {
24.101 -#define FIRST_DIGIT (ECP521_DIGITS-1)
24.102 - for (i = FIRST_DIGIT; i < MP_USED(a)-1; i++) {
24.103 - s1[i-FIRST_DIGIT] = (MP_DIGIT(a, i) >> 9)
24.104 - | (MP_DIGIT(a, 1+i) << (MP_DIGIT_BIT-9));
24.105 - }
24.106 - s1[i-FIRST_DIGIT] = MP_DIGIT(a, i) >> 9;
24.107 -
24.108 - if ( a != r ) {
24.109 - MP_CHECKOK(s_mp_pad(r,ECP521_DIGITS));
24.110 - for (i = 0; i < ECP521_DIGITS; i++) {
24.111 - MP_DIGIT(r,i) = MP_DIGIT(a, i);
24.112 - }
24.113 - }
24.114 - MP_USED(r) = ECP521_DIGITS;
24.115 - MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF;
24.116 -
24.117 - MP_CHECKOK(s_mp_add(r, &m1));
24.118 - if (MP_DIGIT(r, FIRST_DIGIT) & 0x200) {
24.119 - MP_CHECKOK(s_mp_add_d(r,1));
24.120 - MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF;
24.121 - }
24.122 - s_mp_clamp(r);
24.123 - }
24.124 -
24.125 - CLEANUP:
24.126 - return res;
24.127 -}
24.128 -
24.129 -/* Compute the square of polynomial a, reduce modulo p521. Store the
24.130 - * result in r. r could be a. Uses optimized modular reduction for p521.
24.131 - */
24.132 -mp_err
24.133 -ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
24.134 -{
24.135 - mp_err res = MP_OKAY;
24.136 -
24.137 - MP_CHECKOK(mp_sqr(a, r));
24.138 - MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
24.139 - CLEANUP:
24.140 - return res;
24.141 -}
24.142 -
24.143 -/* Compute the product of two polynomials a and b, reduce modulo p521.
24.144 - * Store the result in r. r could be a or b; a could be b. Uses
24.145 - * optimized modular reduction for p521. */
24.146 -mp_err
24.147 -ec_GFp_nistp521_mul(const mp_int *a, const mp_int *b, mp_int *r,
24.148 - const GFMethod *meth)
24.149 -{
24.150 - mp_err res = MP_OKAY;
24.151 -
24.152 - MP_CHECKOK(mp_mul(a, b, r));
24.153 - MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
24.154 - CLEANUP:
24.155 - return res;
24.156 -}
24.157 -
24.158 -/* Divides two field elements. If a is NULL, then returns the inverse of
24.159 - * b. */
24.160 -mp_err
24.161 -ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r,
24.162 - const GFMethod *meth)
24.163 -{
24.164 - mp_err res = MP_OKAY;
24.165 - mp_int t;
24.166 -
24.167 - /* If a is NULL, then return the inverse of b, otherwise return a/b. */
24.168 - if (a == NULL) {
24.169 - return mp_invmod(b, &meth->irr, r);
24.170 - } else {
24.171 - /* MPI doesn't support divmod, so we implement it using invmod and
24.172 - * mulmod. */
24.173 - MP_CHECKOK(mp_init(&t, FLAG(b)));
24.174 - MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
24.175 - MP_CHECKOK(mp_mul(a, &t, r));
24.176 - MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
24.177 - CLEANUP:
24.178 - mp_clear(&t);
24.179 - return res;
24.180 - }
24.181 -}
24.182 -
24.183 -/* Wire in fast field arithmetic and precomputation of base point for
24.184 - * named curves. */
24.185 -mp_err
24.186 -ec_group_set_gfp521(ECGroup *group, ECCurveName name)
24.187 -{
24.188 - if (name == ECCurve_NIST_P521) {
24.189 - group->meth->field_mod = &ec_GFp_nistp521_mod;
24.190 - group->meth->field_mul = &ec_GFp_nistp521_mul;
24.191 - group->meth->field_sqr = &ec_GFp_nistp521_sqr;
24.192 - group->meth->field_div = &ec_GFp_nistp521_div;
24.193 - }
24.194 - return MP_OKAY;
24.195 -}
25.1 --- a/src/share/native/sun/security/ec/ecp_aff.c Tue Oct 13 15:25:58 2009 -0700
25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
25.3 @@ -1,379 +0,0 @@
25.4 -/* *********************************************************************
25.5 - *
25.6 - * Sun elects to have this file available under and governed by the
25.7 - * Mozilla Public License Version 1.1 ("MPL") (see
25.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
25.9 - * of doubt and subject to the following, Sun also elects to allow
25.10 - * licensees to use this file under the MPL, the GNU General Public
25.11 - * License version 2 only or the Lesser General Public License version
25.12 - * 2.1 only. Any references to the "GNU General Public License version 2
25.13 - * or later" or "GPL" in the following shall be construed to mean the
25.14 - * GNU General Public License version 2 only. Any references to the "GNU
25.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
25.16 - * following shall be construed to mean the GNU Lesser General Public
25.17 - * License version 2.1 only. However, the following notice accompanied
25.18 - * the original version of this file:
25.19 - *
25.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
25.21 - *
25.22 - * The contents of this file are subject to the Mozilla Public License Version
25.23 - * 1.1 (the "License"); you may not use this file except in compliance with
25.24 - * the License. You may obtain a copy of the License at
25.25 - * http://www.mozilla.org/MPL/
25.26 - *
25.27 - * Software distributed under the License is distributed on an "AS IS" basis,
25.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
25.29 - * for the specific language governing rights and limitations under the
25.30 - * License.
25.31 - *
25.32 - * The Original Code is the elliptic curve math library for prime field curves.
25.33 - *
25.34 - * The Initial Developer of the Original Code is
25.35 - * Sun Microsystems, Inc.
25.36 - * Portions created by the Initial Developer are Copyright (C) 2003
25.37 - * the Initial Developer. All Rights Reserved.
25.38 - *
25.39 - * Contributor(s):
25.40 - * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
25.41 - * Stephen Fung <fungstep@hotmail.com>, and
25.42 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
25.43 - * Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
25.44 - * Nils Larsch <nla@trustcenter.de>, and
25.45 - * Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project
25.46 - *
25.47 - * Alternatively, the contents of this file may be used under the terms of
25.48 - * either the GNU General Public License Version 2 or later (the "GPL"), or
25.49 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
25.50 - * in which case the provisions of the GPL or the LGPL are applicable instead
25.51 - * of those above. If you wish to allow use of your version of this file only
25.52 - * under the terms of either the GPL or the LGPL, and not to allow others to
25.53 - * use your version of this file under the terms of the MPL, indicate your
25.54 - * decision by deleting the provisions above and replace them with the notice
25.55 - * and other provisions required by the GPL or the LGPL. If you do not delete
25.56 - * the provisions above, a recipient may use your version of this file under
25.57 - * the terms of any one of the MPL, the GPL or the LGPL.
25.58 - *
25.59 - *********************************************************************** */
25.60 -/*
25.61 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25.62 - * Use is subject to license terms.
25.63 - */
25.64 -
25.65 -#pragma ident "%Z%%M% %I% %E% SMI"
25.66 -
25.67 -#include "ecp.h"
25.68 -#include "mplogic.h"
25.69 -#ifndef _KERNEL
25.70 -#include <stdlib.h>
25.71 -#endif
25.72 -
25.73 -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
25.74 -mp_err
25.75 -ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py)
25.76 -{
25.77 -
25.78 - if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
25.79 - return MP_YES;
25.80 - } else {
25.81 - return MP_NO;
25.82 - }
25.83 -
25.84 -}
25.85 -
25.86 -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
25.87 -mp_err
25.88 -ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py)
25.89 -{
25.90 - mp_zero(px);
25.91 - mp_zero(py);
25.92 - return MP_OKAY;
25.93 -}
25.94 -
25.95 -/* Computes R = P + Q based on IEEE P1363 A.10.1. Elliptic curve points P,
25.96 - * Q, and R can all be identical. Uses affine coordinates. Assumes input
25.97 - * is already field-encoded using field_enc, and returns output that is
25.98 - * still field-encoded. */
25.99 -mp_err
25.100 -ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
25.101 - const mp_int *qy, mp_int *rx, mp_int *ry,
25.102 - const ECGroup *group)
25.103 -{
25.104 - mp_err res = MP_OKAY;
25.105 - mp_int lambda, temp, tempx, tempy;
25.106 -
25.107 - MP_DIGITS(&lambda) = 0;
25.108 - MP_DIGITS(&temp) = 0;
25.109 - MP_DIGITS(&tempx) = 0;
25.110 - MP_DIGITS(&tempy) = 0;
25.111 - MP_CHECKOK(mp_init(&lambda, FLAG(px)));
25.112 - MP_CHECKOK(mp_init(&temp, FLAG(px)));
25.113 - MP_CHECKOK(mp_init(&tempx, FLAG(px)));
25.114 - MP_CHECKOK(mp_init(&tempy, FLAG(px)));
25.115 - /* if P = inf, then R = Q */
25.116 - if (ec_GFp_pt_is_inf_aff(px, py) == 0) {
25.117 - MP_CHECKOK(mp_copy(qx, rx));
25.118 - MP_CHECKOK(mp_copy(qy, ry));
25.119 - res = MP_OKAY;
25.120 - goto CLEANUP;
25.121 - }
25.122 - /* if Q = inf, then R = P */
25.123 - if (ec_GFp_pt_is_inf_aff(qx, qy) == 0) {
25.124 - MP_CHECKOK(mp_copy(px, rx));
25.125 - MP_CHECKOK(mp_copy(py, ry));
25.126 - res = MP_OKAY;
25.127 - goto CLEANUP;
25.128 - }
25.129 - /* if px != qx, then lambda = (py-qy) / (px-qx) */
25.130 - if (mp_cmp(px, qx) != 0) {
25.131 - MP_CHECKOK(group->meth->field_sub(py, qy, &tempy, group->meth));
25.132 - MP_CHECKOK(group->meth->field_sub(px, qx, &tempx, group->meth));
25.133 - MP_CHECKOK(group->meth->
25.134 - field_div(&tempy, &tempx, &lambda, group->meth));
25.135 - } else {
25.136 - /* if py != qy or qy = 0, then R = inf */
25.137 - if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
25.138 - mp_zero(rx);
25.139 - mp_zero(ry);
25.140 - res = MP_OKAY;
25.141 - goto CLEANUP;
25.142 - }
25.143 - /* lambda = (3qx^2+a) / (2qy) */
25.144 - MP_CHECKOK(group->meth->field_sqr(qx, &tempx, group->meth));
25.145 - MP_CHECKOK(mp_set_int(&temp, 3));
25.146 - if (group->meth->field_enc) {
25.147 - MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
25.148 - }
25.149 - MP_CHECKOK(group->meth->
25.150 - field_mul(&tempx, &temp, &tempx, group->meth));
25.151 - MP_CHECKOK(group->meth->
25.152 - field_add(&tempx, &group->curvea, &tempx, group->meth));
25.153 - MP_CHECKOK(mp_set_int(&temp, 2));
25.154 - if (group->meth->field_enc) {
25.155 - MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
25.156 - }
25.157 - MP_CHECKOK(group->meth->field_mul(qy, &temp, &tempy, group->meth));
25.158 - MP_CHECKOK(group->meth->
25.159 - field_div(&tempx, &tempy, &lambda, group->meth));
25.160 - }
25.161 - /* rx = lambda^2 - px - qx */
25.162 - MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
25.163 - MP_CHECKOK(group->meth->field_sub(&tempx, px, &tempx, group->meth));
25.164 - MP_CHECKOK(group->meth->field_sub(&tempx, qx, &tempx, group->meth));
25.165 - /* ry = (x1-x2) * lambda - y1 */
25.166 - MP_CHECKOK(group->meth->field_sub(qx, &tempx, &tempy, group->meth));
25.167 - MP_CHECKOK(group->meth->
25.168 - field_mul(&tempy, &lambda, &tempy, group->meth));
25.169 - MP_CHECKOK(group->meth->field_sub(&tempy, qy, &tempy, group->meth));
25.170 - MP_CHECKOK(mp_copy(&tempx, rx));
25.171 - MP_CHECKOK(mp_copy(&tempy, ry));
25.172 -
25.173 - CLEANUP:
25.174 - mp_clear(&lambda);
25.175 - mp_clear(&temp);
25.176 - mp_clear(&tempx);
25.177 - mp_clear(&tempy);
25.178 - return res;
25.179 -}
25.180 -
25.181 -/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
25.182 - * identical. Uses affine coordinates. Assumes input is already
25.183 - * field-encoded using field_enc, and returns output that is still
25.184 - * field-encoded. */
25.185 -mp_err
25.186 -ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
25.187 - const mp_int *qy, mp_int *rx, mp_int *ry,
25.188 - const ECGroup *group)
25.189 -{
25.190 - mp_err res = MP_OKAY;
25.191 - mp_int nqy;
25.192 -
25.193 - MP_DIGITS(&nqy) = 0;
25.194 - MP_CHECKOK(mp_init(&nqy, FLAG(px)));
25.195 - /* nqy = -qy */
25.196 - MP_CHECKOK(group->meth->field_neg(qy, &nqy, group->meth));
25.197 - res = group->point_add(px, py, qx, &nqy, rx, ry, group);
25.198 - CLEANUP:
25.199 - mp_clear(&nqy);
25.200 - return res;
25.201 -}
25.202 -
25.203 -/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
25.204 - * affine coordinates. Assumes input is already field-encoded using
25.205 - * field_enc, and returns output that is still field-encoded. */
25.206 -mp_err
25.207 -ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
25.208 - mp_int *ry, const ECGroup *group)
25.209 -{
25.210 - return ec_GFp_pt_add_aff(px, py, px, py, rx, ry, group);
25.211 -}
25.212 -
25.213 -/* by default, this routine is unused and thus doesn't need to be compiled */
25.214 -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
25.215 -/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
25.216 - * R can be identical. Uses affine coordinates. Assumes input is already
25.217 - * field-encoded using field_enc, and returns output that is still
25.218 - * field-encoded. */
25.219 -mp_err
25.220 -ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
25.221 - mp_int *rx, mp_int *ry, const ECGroup *group)
25.222 -{
25.223 - mp_err res = MP_OKAY;
25.224 - mp_int k, k3, qx, qy, sx, sy;
25.225 - int b1, b3, i, l;
25.226 -
25.227 - MP_DIGITS(&k) = 0;
25.228 - MP_DIGITS(&k3) = 0;
25.229 - MP_DIGITS(&qx) = 0;
25.230 - MP_DIGITS(&qy) = 0;
25.231 - MP_DIGITS(&sx) = 0;
25.232 - MP_DIGITS(&sy) = 0;
25.233 - MP_CHECKOK(mp_init(&k));
25.234 - MP_CHECKOK(mp_init(&k3));
25.235 - MP_CHECKOK(mp_init(&qx));
25.236 - MP_CHECKOK(mp_init(&qy));
25.237 - MP_CHECKOK(mp_init(&sx));
25.238 - MP_CHECKOK(mp_init(&sy));
25.239 -
25.240 - /* if n = 0 then r = inf */
25.241 - if (mp_cmp_z(n) == 0) {
25.242 - mp_zero(rx);
25.243 - mp_zero(ry);
25.244 - res = MP_OKAY;
25.245 - goto CLEANUP;
25.246 - }
25.247 - /* Q = P, k = n */
25.248 - MP_CHECKOK(mp_copy(px, &qx));
25.249 - MP_CHECKOK(mp_copy(py, &qy));
25.250 - MP_CHECKOK(mp_copy(n, &k));
25.251 - /* if n < 0 then Q = -Q, k = -k */
25.252 - if (mp_cmp_z(n) < 0) {
25.253 - MP_CHECKOK(group->meth->field_neg(&qy, &qy, group->meth));
25.254 - MP_CHECKOK(mp_neg(&k, &k));
25.255 - }
25.256 -#ifdef ECL_DEBUG /* basic double and add method */
25.257 - l = mpl_significant_bits(&k) - 1;
25.258 - MP_CHECKOK(mp_copy(&qx, &sx));
25.259 - MP_CHECKOK(mp_copy(&qy, &sy));
25.260 - for (i = l - 1; i >= 0; i--) {
25.261 - /* S = 2S */
25.262 - MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
25.263 - /* if k_i = 1, then S = S + Q */
25.264 - if (mpl_get_bit(&k, i) != 0) {
25.265 - MP_CHECKOK(group->
25.266 - point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
25.267 - }
25.268 - }
25.269 -#else /* double and add/subtract method from
25.270 - * standard */
25.271 - /* k3 = 3 * k */
25.272 - MP_CHECKOK(mp_set_int(&k3, 3));
25.273 - MP_CHECKOK(mp_mul(&k, &k3, &k3));
25.274 - /* S = Q */
25.275 - MP_CHECKOK(mp_copy(&qx, &sx));
25.276 - MP_CHECKOK(mp_copy(&qy, &sy));
25.277 - /* l = index of high order bit in binary representation of 3*k */
25.278 - l = mpl_significant_bits(&k3) - 1;
25.279 - /* for i = l-1 downto 1 */
25.280 - for (i = l - 1; i >= 1; i--) {
25.281 - /* S = 2S */
25.282 - MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
25.283 - b3 = MP_GET_BIT(&k3, i);
25.284 - b1 = MP_GET_BIT(&k, i);
25.285 - /* if k3_i = 1 and k_i = 0, then S = S + Q */
25.286 - if ((b3 == 1) && (b1 == 0)) {
25.287 - MP_CHECKOK(group->
25.288 - point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
25.289 - /* if k3_i = 0 and k_i = 1, then S = S - Q */
25.290 - } else if ((b3 == 0) && (b1 == 1)) {
25.291 - MP_CHECKOK(group->
25.292 - point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
25.293 - }
25.294 - }
25.295 -#endif
25.296 - /* output S */
25.297 - MP_CHECKOK(mp_copy(&sx, rx));
25.298 - MP_CHECKOK(mp_copy(&sy, ry));
25.299 -
25.300 - CLEANUP:
25.301 - mp_clear(&k);
25.302 - mp_clear(&k3);
25.303 - mp_clear(&qx);
25.304 - mp_clear(&qy);
25.305 - mp_clear(&sx);
25.306 - mp_clear(&sy);
25.307 - return res;
25.308 -}
25.309 -#endif
25.310 -
25.311 -/* Validates a point on a GFp curve. */
25.312 -mp_err
25.313 -ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
25.314 -{
25.315 - mp_err res = MP_NO;
25.316 - mp_int accl, accr, tmp, pxt, pyt;
25.317 -
25.318 - MP_DIGITS(&accl) = 0;
25.319 - MP_DIGITS(&accr) = 0;
25.320 - MP_DIGITS(&tmp) = 0;
25.321 - MP_DIGITS(&pxt) = 0;
25.322 - MP_DIGITS(&pyt) = 0;
25.323 - MP_CHECKOK(mp_init(&accl, FLAG(px)));
25.324 - MP_CHECKOK(mp_init(&accr, FLAG(px)));
25.325 - MP_CHECKOK(mp_init(&tmp, FLAG(px)));
25.326 - MP_CHECKOK(mp_init(&pxt, FLAG(px)));
25.327 - MP_CHECKOK(mp_init(&pyt, FLAG(px)));
25.328 -
25.329 - /* 1: Verify that publicValue is not the point at infinity */
25.330 - if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
25.331 - res = MP_NO;
25.332 - goto CLEANUP;
25.333 - }
25.334 - /* 2: Verify that the coordinates of publicValue are elements
25.335 - * of the field.
25.336 - */
25.337 - if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
25.338 - (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
25.339 - res = MP_NO;
25.340 - goto CLEANUP;
25.341 - }
25.342 - /* 3: Verify that publicValue is on the curve. */
25.343 - if (group->meth->field_enc) {
25.344 - group->meth->field_enc(px, &pxt, group->meth);
25.345 - group->meth->field_enc(py, &pyt, group->meth);
25.346 - } else {
25.347 - mp_copy(px, &pxt);
25.348 - mp_copy(py, &pyt);
25.349 - }
25.350 - /* left-hand side: y^2 */
25.351 - MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
25.352 - /* right-hand side: x^3 + a*x + b */
25.353 - MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
25.354 - MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
25.355 - MP_CHECKOK( group->meth->field_mul(&group->curvea, &pxt, &tmp, group->meth) );
25.356 - MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
25.357 - MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
25.358 - /* check LHS - RHS == 0 */
25.359 - MP_CHECKOK( group->meth->field_sub(&accl, &accr, &accr, group->meth) );
25.360 - if (mp_cmp_z(&accr) != 0) {
25.361 - res = MP_NO;
25.362 - goto CLEANUP;
25.363 - }
25.364 - /* 4: Verify that the order of the curve times the publicValue
25.365 - * is the point at infinity.
25.366 - */
25.367 - MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
25.368 - if (ec_GFp_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
25.369 - res = MP_NO;
25.370 - goto CLEANUP;
25.371 - }
25.372 -
25.373 - res = MP_YES;
25.374 -
25.375 -CLEANUP:
25.376 - mp_clear(&accl);
25.377 - mp_clear(&accr);
25.378 - mp_clear(&tmp);
25.379 - mp_clear(&pxt);
25.380 - mp_clear(&pyt);
25.381 - return res;
25.382 -}
26.1 --- a/src/share/native/sun/security/ec/ecp_jac.c Tue Oct 13 15:25:58 2009 -0700
26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
26.3 @@ -1,575 +0,0 @@
26.4 -/* *********************************************************************
26.5 - *
26.6 - * Sun elects to have this file available under and governed by the
26.7 - * Mozilla Public License Version 1.1 ("MPL") (see
26.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
26.9 - * of doubt and subject to the following, Sun also elects to allow
26.10 - * licensees to use this file under the MPL, the GNU General Public
26.11 - * License version 2 only or the Lesser General Public License version
26.12 - * 2.1 only. Any references to the "GNU General Public License version 2
26.13 - * or later" or "GPL" in the following shall be construed to mean the
26.14 - * GNU General Public License version 2 only. Any references to the "GNU
26.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
26.16 - * following shall be construed to mean the GNU Lesser General Public
26.17 - * License version 2.1 only. However, the following notice accompanied
26.18 - * the original version of this file:
26.19 - *
26.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
26.21 - *
26.22 - * The contents of this file are subject to the Mozilla Public License Version
26.23 - * 1.1 (the "License"); you may not use this file except in compliance with
26.24 - * the License. You may obtain a copy of the License at
26.25 - * http://www.mozilla.org/MPL/
26.26 - *
26.27 - * Software distributed under the License is distributed on an "AS IS" basis,
26.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
26.29 - * for the specific language governing rights and limitations under the
26.30 - * License.
26.31 - *
26.32 - * The Original Code is the elliptic curve math library for prime field curves.
26.33 - *
26.34 - * The Initial Developer of the Original Code is
26.35 - * Sun Microsystems, Inc.
26.36 - * Portions created by the Initial Developer are Copyright (C) 2003
26.37 - * the Initial Developer. All Rights Reserved.
26.38 - *
26.39 - * Contributor(s):
26.40 - * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
26.41 - * Stephen Fung <fungstep@hotmail.com>, and
26.42 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
26.43 - * Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
26.44 - * Nils Larsch <nla@trustcenter.de>, and
26.45 - * Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project
26.46 - *
26.47 - * Alternatively, the contents of this file may be used under the terms of
26.48 - * either the GNU General Public License Version 2 or later (the "GPL"), or
26.49 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26.50 - * in which case the provisions of the GPL or the LGPL are applicable instead
26.51 - * of those above. If you wish to allow use of your version of this file only
26.52 - * under the terms of either the GPL or the LGPL, and not to allow others to
26.53 - * use your version of this file under the terms of the MPL, indicate your
26.54 - * decision by deleting the provisions above and replace them with the notice
26.55 - * and other provisions required by the GPL or the LGPL. If you do not delete
26.56 - * the provisions above, a recipient may use your version of this file under
26.57 - * the terms of any one of the MPL, the GPL or the LGPL.
26.58 - *
26.59 - *********************************************************************** */
26.60 -/*
26.61 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
26.62 - * Use is subject to license terms.
26.63 - */
26.64 -
26.65 -#pragma ident "%Z%%M% %I% %E% SMI"
26.66 -
26.67 -#include "ecp.h"
26.68 -#include "mplogic.h"
26.69 -#ifndef _KERNEL
26.70 -#include <stdlib.h>
26.71 -#endif
26.72 -#ifdef ECL_DEBUG
26.73 -#include <assert.h>
26.74 -#endif
26.75 -
26.76 -/* Converts a point P(px, py) from affine coordinates to Jacobian
26.77 - * projective coordinates R(rx, ry, rz). Assumes input is already
26.78 - * field-encoded using field_enc, and returns output that is still
26.79 - * field-encoded. */
26.80 -mp_err
26.81 -ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
26.82 - mp_int *ry, mp_int *rz, const ECGroup *group)
26.83 -{
26.84 - mp_err res = MP_OKAY;
26.85 -
26.86 - if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
26.87 - MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
26.88 - } else {
26.89 - MP_CHECKOK(mp_copy(px, rx));
26.90 - MP_CHECKOK(mp_copy(py, ry));
26.91 - MP_CHECKOK(mp_set_int(rz, 1));
26.92 - if (group->meth->field_enc) {
26.93 - MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
26.94 - }
26.95 - }
26.96 - CLEANUP:
26.97 - return res;
26.98 -}
26.99 -
26.100 -/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
26.101 - * affine coordinates R(rx, ry). P and R can share x and y coordinates.
26.102 - * Assumes input is already field-encoded using field_enc, and returns
26.103 - * output that is still field-encoded. */
26.104 -mp_err
26.105 -ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
26.106 - mp_int *rx, mp_int *ry, const ECGroup *group)
26.107 -{
26.108 - mp_err res = MP_OKAY;
26.109 - mp_int z1, z2, z3;
26.110 -
26.111 - MP_DIGITS(&z1) = 0;
26.112 - MP_DIGITS(&z2) = 0;
26.113 - MP_DIGITS(&z3) = 0;
26.114 - MP_CHECKOK(mp_init(&z1, FLAG(px)));
26.115 - MP_CHECKOK(mp_init(&z2, FLAG(px)));
26.116 - MP_CHECKOK(mp_init(&z3, FLAG(px)));
26.117 -
26.118 - /* if point at infinity, then set point at infinity and exit */
26.119 - if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
26.120 - MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
26.121 - goto CLEANUP;
26.122 - }
26.123 -
26.124 - /* transform (px, py, pz) into (px / pz^2, py / pz^3) */
26.125 - if (mp_cmp_d(pz, 1) == 0) {
26.126 - MP_CHECKOK(mp_copy(px, rx));
26.127 - MP_CHECKOK(mp_copy(py, ry));
26.128 - } else {
26.129 - MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
26.130 - MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
26.131 - MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
26.132 - MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
26.133 - MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
26.134 - }
26.135 -
26.136 - CLEANUP:
26.137 - mp_clear(&z1);
26.138 - mp_clear(&z2);
26.139 - mp_clear(&z3);
26.140 - return res;
26.141 -}
26.142 -
26.143 -/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
26.144 - * coordinates. */
26.145 -mp_err
26.146 -ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
26.147 -{
26.148 - return mp_cmp_z(pz);
26.149 -}
26.150 -
26.151 -/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
26.152 - * coordinates. */
26.153 -mp_err
26.154 -ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
26.155 -{
26.156 - mp_zero(pz);
26.157 - return MP_OKAY;
26.158 -}
26.159 -
26.160 -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
26.161 - * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
26.162 - * Uses mixed Jacobian-affine coordinates. Assumes input is already
26.163 - * field-encoded using field_enc, and returns output that is still
26.164 - * field-encoded. Uses equation (2) from Brown, Hankerson, Lopez, and
26.165 - * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
26.166 - * Fields. */
26.167 -mp_err
26.168 -ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
26.169 - const mp_int *qx, const mp_int *qy, mp_int *rx,
26.170 - mp_int *ry, mp_int *rz, const ECGroup *group)
26.171 -{
26.172 - mp_err res = MP_OKAY;
26.173 - mp_int A, B, C, D, C2, C3;
26.174 -
26.175 - MP_DIGITS(&A) = 0;
26.176 - MP_DIGITS(&B) = 0;
26.177 - MP_DIGITS(&C) = 0;
26.178 - MP_DIGITS(&D) = 0;
26.179 - MP_DIGITS(&C2) = 0;
26.180 - MP_DIGITS(&C3) = 0;
26.181 - MP_CHECKOK(mp_init(&A, FLAG(px)));
26.182 - MP_CHECKOK(mp_init(&B, FLAG(px)));
26.183 - MP_CHECKOK(mp_init(&C, FLAG(px)));
26.184 - MP_CHECKOK(mp_init(&D, FLAG(px)));
26.185 - MP_CHECKOK(mp_init(&C2, FLAG(px)));
26.186 - MP_CHECKOK(mp_init(&C3, FLAG(px)));
26.187 -
26.188 - /* If either P or Q is the point at infinity, then return the other
26.189 - * point */
26.190 - if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
26.191 - MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
26.192 - goto CLEANUP;
26.193 - }
26.194 - if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
26.195 - MP_CHECKOK(mp_copy(px, rx));
26.196 - MP_CHECKOK(mp_copy(py, ry));
26.197 - MP_CHECKOK(mp_copy(pz, rz));
26.198 - goto CLEANUP;
26.199 - }
26.200 -
26.201 - /* A = qx * pz^2, B = qy * pz^3 */
26.202 - MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
26.203 - MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
26.204 - MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
26.205 - MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
26.206 -
26.207 - /* C = A - px, D = B - py */
26.208 - MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
26.209 - MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
26.210 -
26.211 - /* C2 = C^2, C3 = C^3 */
26.212 - MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
26.213 - MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
26.214 -
26.215 - /* rz = pz * C */
26.216 - MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
26.217 -
26.218 - /* C = px * C^2 */
26.219 - MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
26.220 - /* A = D^2 */
26.221 - MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));
26.222 -
26.223 - /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
26.224 - MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
26.225 - MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
26.226 - MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));
26.227 -
26.228 - /* C3 = py * C^3 */
26.229 - MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));
26.230 -
26.231 - /* ry = D * (px * C^2 - rx) - py * C^3 */
26.232 - MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
26.233 - MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
26.234 - MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));
26.235 -
26.236 - CLEANUP:
26.237 - mp_clear(&A);
26.238 - mp_clear(&B);
26.239 - mp_clear(&C);
26.240 - mp_clear(&D);
26.241 - mp_clear(&C2);
26.242 - mp_clear(&C3);
26.243 - return res;
26.244 -}
26.245 -
26.246 -/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
26.247 - * Jacobian coordinates.
26.248 - *
26.249 - * Assumes input is already field-encoded using field_enc, and returns
26.250 - * output that is still field-encoded.
26.251 - *
26.252 - * This routine implements Point Doubling in the Jacobian Projective
26.253 - * space as described in the paper "Efficient elliptic curve exponentiation
26.254 - * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
26.255 - */
26.256 -mp_err
26.257 -ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
26.258 - mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
26.259 -{
26.260 - mp_err res = MP_OKAY;
26.261 - mp_int t0, t1, M, S;
26.262 -
26.263 - MP_DIGITS(&t0) = 0;
26.264 - MP_DIGITS(&t1) = 0;
26.265 - MP_DIGITS(&M) = 0;
26.266 - MP_DIGITS(&S) = 0;
26.267 - MP_CHECKOK(mp_init(&t0, FLAG(px)));
26.268 - MP_CHECKOK(mp_init(&t1, FLAG(px)));
26.269 - MP_CHECKOK(mp_init(&M, FLAG(px)));
26.270 - MP_CHECKOK(mp_init(&S, FLAG(px)));
26.271 -
26.272 - if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
26.273 - MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
26.274 - goto CLEANUP;
26.275 - }
26.276 -
26.277 - if (mp_cmp_d(pz, 1) == 0) {
26.278 - /* M = 3 * px^2 + a */
26.279 - MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
26.280 - MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
26.281 - MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
26.282 - MP_CHECKOK(group->meth->
26.283 - field_add(&t0, &group->curvea, &M, group->meth));
26.284 - } else if (mp_cmp_int(&group->curvea, -3, FLAG(px)) == 0) {
26.285 - /* M = 3 * (px + pz^2) * (px - pz^2) */
26.286 - MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
26.287 - MP_CHECKOK(group->meth->field_add(px, &M, &t0, group->meth));
26.288 - MP_CHECKOK(group->meth->field_sub(px, &M, &t1, group->meth));
26.289 - MP_CHECKOK(group->meth->field_mul(&t0, &t1, &M, group->meth));
26.290 - MP_CHECKOK(group->meth->field_add(&M, &M, &t0, group->meth));
26.291 - MP_CHECKOK(group->meth->field_add(&t0, &M, &M, group->meth));
26.292 - } else {
26.293 - /* M = 3 * (px^2) + a * (pz^4) */
26.294 - MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
26.295 - MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
26.296 - MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
26.297 - MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
26.298 - MP_CHECKOK(group->meth->field_sqr(&M, &M, group->meth));
26.299 - MP_CHECKOK(group->meth->
26.300 - field_mul(&M, &group->curvea, &M, group->meth));
26.301 - MP_CHECKOK(group->meth->field_add(&M, &t0, &M, group->meth));
26.302 - }
26.303 -
26.304 - /* rz = 2 * py * pz */
26.305 - /* t0 = 4 * py^2 */
26.306 - if (mp_cmp_d(pz, 1) == 0) {
26.307 - MP_CHECKOK(group->meth->field_add(py, py, rz, group->meth));
26.308 - MP_CHECKOK(group->meth->field_sqr(rz, &t0, group->meth));
26.309 - } else {
26.310 - MP_CHECKOK(group->meth->field_add(py, py, &t0, group->meth));
26.311 - MP_CHECKOK(group->meth->field_mul(&t0, pz, rz, group->meth));
26.312 - MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
26.313 - }
26.314 -
26.315 - /* S = 4 * px * py^2 = px * (2 * py)^2 */
26.316 - MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));
26.317 -
26.318 - /* rx = M^2 - 2 * S */
26.319 - MP_CHECKOK(group->meth->field_add(&S, &S, &t1, group->meth));
26.320 - MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
26.321 - MP_CHECKOK(group->meth->field_sub(rx, &t1, rx, group->meth));
26.322 -
26.323 - /* ry = M * (S - rx) - 8 * py^4 */
26.324 - MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
26.325 - if (mp_isodd(&t1)) {
26.326 - MP_CHECKOK(mp_add(&t1, &group->meth->irr, &t1));
26.327 - }
26.328 - MP_CHECKOK(mp_div_2(&t1, &t1));
26.329 - MP_CHECKOK(group->meth->field_sub(&S, rx, &S, group->meth));
26.330 - MP_CHECKOK(group->meth->field_mul(&M, &S, &M, group->meth));
26.331 - MP_CHECKOK(group->meth->field_sub(&M, &t1, ry, group->meth));
26.332 -
26.333 - CLEANUP:
26.334 - mp_clear(&t0);
26.335 - mp_clear(&t1);
26.336 - mp_clear(&M);
26.337 - mp_clear(&S);
26.338 - return res;
26.339 -}
26.340 -
26.341 -/* by default, this routine is unused and thus doesn't need to be compiled */
26.342 -#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
26.343 -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
26.344 - * a, b and p are the elliptic curve coefficients and the prime that
26.345 - * determines the field GFp. Elliptic curve points P and R can be
26.346 - * identical. Uses mixed Jacobian-affine coordinates. Assumes input is
26.347 - * already field-encoded using field_enc, and returns output that is still
26.348 - * field-encoded. Uses 4-bit window method. */
26.349 -mp_err
26.350 -ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
26.351 - mp_int *rx, mp_int *ry, const ECGroup *group)
26.352 -{
26.353 - mp_err res = MP_OKAY;
26.354 - mp_int precomp[16][2], rz;
26.355 - int i, ni, d;
26.356 -
26.357 - MP_DIGITS(&rz) = 0;
26.358 - for (i = 0; i < 16; i++) {
26.359 - MP_DIGITS(&precomp[i][0]) = 0;
26.360 - MP_DIGITS(&precomp[i][1]) = 0;
26.361 - }
26.362 -
26.363 - ARGCHK(group != NULL, MP_BADARG);
26.364 - ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
26.365 -
26.366 - /* initialize precomputation table */
26.367 - for (i = 0; i < 16; i++) {
26.368 - MP_CHECKOK(mp_init(&precomp[i][0]));
26.369 - MP_CHECKOK(mp_init(&precomp[i][1]));
26.370 - }
26.371 -
26.372 - /* fill precomputation table */
26.373 - mp_zero(&precomp[0][0]);
26.374 - mp_zero(&precomp[0][1]);
26.375 - MP_CHECKOK(mp_copy(px, &precomp[1][0]));
26.376 - MP_CHECKOK(mp_copy(py, &precomp[1][1]));
26.377 - for (i = 2; i < 16; i++) {
26.378 - MP_CHECKOK(group->
26.379 - point_add(&precomp[1][0], &precomp[1][1],
26.380 - &precomp[i - 1][0], &precomp[i - 1][1],
26.381 - &precomp[i][0], &precomp[i][1], group));
26.382 - }
26.383 -
26.384 - d = (mpl_significant_bits(n) + 3) / 4;
26.385 -
26.386 - /* R = inf */
26.387 - MP_CHECKOK(mp_init(&rz));
26.388 - MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
26.389 -
26.390 - for (i = d - 1; i >= 0; i--) {
26.391 - /* compute window ni */
26.392 - ni = MP_GET_BIT(n, 4 * i + 3);
26.393 - ni <<= 1;
26.394 - ni |= MP_GET_BIT(n, 4 * i + 2);
26.395 - ni <<= 1;
26.396 - ni |= MP_GET_BIT(n, 4 * i + 1);
26.397 - ni <<= 1;
26.398 - ni |= MP_GET_BIT(n, 4 * i);
26.399 - /* R = 2^4 * R */
26.400 - MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
26.401 - MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
26.402 - MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
26.403 - MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
26.404 - /* R = R + (ni * P) */
26.405 - MP_CHECKOK(ec_GFp_pt_add_jac_aff
26.406 - (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
26.407 - &rz, group));
26.408 - }
26.409 -
26.410 - /* convert result S to affine coordinates */
26.411 - MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
26.412 -
26.413 - CLEANUP:
26.414 - mp_clear(&rz);
26.415 - for (i = 0; i < 16; i++) {
26.416 - mp_clear(&precomp[i][0]);
26.417 - mp_clear(&precomp[i][1]);
26.418 - }
26.419 - return res;
26.420 -}
26.421 -#endif
26.422 -
26.423 -/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
26.424 - * k2 * P(x, y), where G is the generator (base point) of the group of
26.425 - * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
26.426 - * Uses mixed Jacobian-affine coordinates. Input and output values are
26.427 - * assumed to be NOT field-encoded. Uses algorithm 15 (simultaneous
26.428 - * multiple point multiplication) from Brown, Hankerson, Lopez, Menezes.
26.429 - * Software Implementation of the NIST Elliptic Curves over Prime Fields. */
26.430 -mp_err
26.431 -ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
26.432 - const mp_int *py, mp_int *rx, mp_int *ry,
26.433 - const ECGroup *group)
26.434 -{
26.435 - mp_err res = MP_OKAY;
26.436 - mp_int precomp[4][4][2];
26.437 - mp_int rz;
26.438 - const mp_int *a, *b;
26.439 - int i, j;
26.440 - int ai, bi, d;
26.441 -
26.442 - for (i = 0; i < 4; i++) {
26.443 - for (j = 0; j < 4; j++) {
26.444 - MP_DIGITS(&precomp[i][j][0]) = 0;
26.445 - MP_DIGITS(&precomp[i][j][1]) = 0;
26.446 - }
26.447 - }
26.448 - MP_DIGITS(&rz) = 0;
26.449 -
26.450 - ARGCHK(group != NULL, MP_BADARG);
26.451 - ARGCHK(!((k1 == NULL)
26.452 - && ((k2 == NULL) || (px == NULL)
26.453 - || (py == NULL))), MP_BADARG);
26.454 -
26.455 - /* if some arguments are not defined used ECPoint_mul */
26.456 - if (k1 == NULL) {
26.457 - return ECPoint_mul(group, k2, px, py, rx, ry);
26.458 - } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
26.459 - return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
26.460 - }
26.461 -
26.462 - /* initialize precomputation table */
26.463 - for (i = 0; i < 4; i++) {
26.464 - for (j = 0; j < 4; j++) {
26.465 - MP_CHECKOK(mp_init(&precomp[i][j][0], FLAG(k1)));
26.466 - MP_CHECKOK(mp_init(&precomp[i][j][1], FLAG(k1)));
26.467 - }
26.468 - }
26.469 -
26.470 - /* fill precomputation table */
26.471 - /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
26.472 - if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
26.473 - a = k2;
26.474 - b = k1;
26.475 - if (group->meth->field_enc) {
26.476 - MP_CHECKOK(group->meth->
26.477 - field_enc(px, &precomp[1][0][0], group->meth));
26.478 - MP_CHECKOK(group->meth->
26.479 - field_enc(py, &precomp[1][0][1], group->meth));
26.480 - } else {
26.481 - MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
26.482 - MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
26.483 - }
26.484 - MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
26.485 - MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
26.486 - } else {
26.487 - a = k1;
26.488 - b = k2;
26.489 - MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
26.490 - MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
26.491 - if (group->meth->field_enc) {
26.492 - MP_CHECKOK(group->meth->
26.493 - field_enc(px, &precomp[0][1][0], group->meth));
26.494 - MP_CHECKOK(group->meth->
26.495 - field_enc(py, &precomp[0][1][1], group->meth));
26.496 - } else {
26.497 - MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
26.498 - MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
26.499 - }
26.500 - }
26.501 - /* precompute [*][0][*] */
26.502 - mp_zero(&precomp[0][0][0]);
26.503 - mp_zero(&precomp[0][0][1]);
26.504 - MP_CHECKOK(group->
26.505 - point_dbl(&precomp[1][0][0], &precomp[1][0][1],
26.506 - &precomp[2][0][0], &precomp[2][0][1], group));
26.507 - MP_CHECKOK(group->
26.508 - point_add(&precomp[1][0][0], &precomp[1][0][1],
26.509 - &precomp[2][0][0], &precomp[2][0][1],
26.510 - &precomp[3][0][0], &precomp[3][0][1], group));
26.511 - /* precompute [*][1][*] */
26.512 - for (i = 1; i < 4; i++) {
26.513 - MP_CHECKOK(group->
26.514 - point_add(&precomp[0][1][0], &precomp[0][1][1],
26.515 - &precomp[i][0][0], &precomp[i][0][1],
26.516 - &precomp[i][1][0], &precomp[i][1][1], group));
26.517 - }
26.518 - /* precompute [*][2][*] */
26.519 - MP_CHECKOK(group->
26.520 - point_dbl(&precomp[0][1][0], &precomp[0][1][1],
26.521 - &precomp[0][2][0], &precomp[0][2][1], group));
26.522 - for (i = 1; i < 4; i++) {
26.523 - MP_CHECKOK(group->
26.524 - point_add(&precomp[0][2][0], &precomp[0][2][1],
26.525 - &precomp[i][0][0], &precomp[i][0][1],
26.526 - &precomp[i][2][0], &precomp[i][2][1], group));
26.527 - }
26.528 - /* precompute [*][3][*] */
26.529 - MP_CHECKOK(group->
26.530 - point_add(&precomp[0][1][0], &precomp[0][1][1],
26.531 - &precomp[0][2][0], &precomp[0][2][1],
26.532 - &precomp[0][3][0], &precomp[0][3][1], group));
26.533 - for (i = 1; i < 4; i++) {
26.534 - MP_CHECKOK(group->
26.535 - point_add(&precomp[0][3][0], &precomp[0][3][1],
26.536 - &precomp[i][0][0], &precomp[i][0][1],
26.537 - &precomp[i][3][0], &precomp[i][3][1], group));
26.538 - }
26.539 -
26.540 - d = (mpl_significant_bits(a) + 1) / 2;
26.541 -
26.542 - /* R = inf */
26.543 - MP_CHECKOK(mp_init(&rz, FLAG(k1)));
26.544 - MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
26.545 -
26.546 - for (i = d - 1; i >= 0; i--) {
26.547 - ai = MP_GET_BIT(a, 2 * i + 1);
26.548 - ai <<= 1;
26.549 - ai |= MP_GET_BIT(a, 2 * i);
26.550 - bi = MP_GET_BIT(b, 2 * i + 1);
26.551 - bi <<= 1;
26.552 - bi |= MP_GET_BIT(b, 2 * i);
26.553 - /* R = 2^2 * R */
26.554 - MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
26.555 - MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
26.556 - /* R = R + (ai * A + bi * B) */
26.557 - MP_CHECKOK(ec_GFp_pt_add_jac_aff
26.558 - (rx, ry, &rz, &precomp[ai][bi][0], &precomp[ai][bi][1],
26.559 - rx, ry, &rz, group));
26.560 - }
26.561 -
26.562 - MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
26.563 -
26.564 - if (group->meth->field_dec) {
26.565 - MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
26.566 - MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
26.567 - }
26.568 -
26.569 - CLEANUP:
26.570 - mp_clear(&rz);
26.571 - for (i = 0; i < 4; i++) {
26.572 - for (j = 0; j < 4; j++) {
26.573 - mp_clear(&precomp[i][j][0]);
26.574 - mp_clear(&precomp[i][j][1]);
26.575 - }
26.576 - }
26.577 - return res;
26.578 -}
27.1 --- a/src/share/native/sun/security/ec/ecp_jm.c Tue Oct 13 15:25:58 2009 -0700
27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3 @@ -1,353 +0,0 @@
27.4 -/* *********************************************************************
27.5 - *
27.6 - * Sun elects to have this file available under and governed by the
27.7 - * Mozilla Public License Version 1.1 ("MPL") (see
27.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
27.9 - * of doubt and subject to the following, Sun also elects to allow
27.10 - * licensees to use this file under the MPL, the GNU General Public
27.11 - * License version 2 only or the Lesser General Public License version
27.12 - * 2.1 only. Any references to the "GNU General Public License version 2
27.13 - * or later" or "GPL" in the following shall be construed to mean the
27.14 - * GNU General Public License version 2 only. Any references to the "GNU
27.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
27.16 - * following shall be construed to mean the GNU Lesser General Public
27.17 - * License version 2.1 only. However, the following notice accompanied
27.18 - * the original version of this file:
27.19 - *
27.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
27.21 - *
27.22 - * The contents of this file are subject to the Mozilla Public License Version
27.23 - * 1.1 (the "License"); you may not use this file except in compliance with
27.24 - * the License. You may obtain a copy of the License at
27.25 - * http://www.mozilla.org/MPL/
27.26 - *
27.27 - * Software distributed under the License is distributed on an "AS IS" basis,
27.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
27.29 - * for the specific language governing rights and limitations under the
27.30 - * License.
27.31 - *
27.32 - * The Original Code is the elliptic curve math library for prime field curves.
27.33 - *
27.34 - * The Initial Developer of the Original Code is
27.35 - * Sun Microsystems, Inc.
27.36 - * Portions created by the Initial Developer are Copyright (C) 2003
27.37 - * the Initial Developer. All Rights Reserved.
27.38 - *
27.39 - * Contributor(s):
27.40 - * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
27.41 - *
27.42 - * Alternatively, the contents of this file may be used under the terms of
27.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
27.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
27.46 - * of those above. If you wish to allow use of your version of this file only
27.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
27.48 - * use your version of this file under the terms of the MPL, indicate your
27.49 - * decision by deleting the provisions above and replace them with the notice
27.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
27.51 - * the provisions above, a recipient may use your version of this file under
27.52 - * the terms of any one of the MPL, the GPL or the LGPL.
27.53 - *
27.54 - *********************************************************************** */
27.55 -/*
27.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
27.57 - * Use is subject to license terms.
27.58 - */
27.59 -
27.60 -#pragma ident "%Z%%M% %I% %E% SMI"
27.61 -
27.62 -#include "ecp.h"
27.63 -#include "ecl-priv.h"
27.64 -#include "mplogic.h"
27.65 -#ifndef _KERNEL
27.66 -#include <stdlib.h>
27.67 -#endif
27.68 -
27.69 -#define MAX_SCRATCH 6
27.70 -
27.71 -/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
27.72 - * Modified Jacobian coordinates.
27.73 - *
27.74 - * Assumes input is already field-encoded using field_enc, and returns
27.75 - * output that is still field-encoded.
27.76 - *
27.77 - */
27.78 -mp_err
27.79 -ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
27.80 - const mp_int *paz4, mp_int *rx, mp_int *ry, mp_int *rz,
27.81 - mp_int *raz4, mp_int scratch[], const ECGroup *group)
27.82 -{
27.83 - mp_err res = MP_OKAY;
27.84 - mp_int *t0, *t1, *M, *S;
27.85 -
27.86 - t0 = &scratch[0];
27.87 - t1 = &scratch[1];
27.88 - M = &scratch[2];
27.89 - S = &scratch[3];
27.90 -
27.91 -#if MAX_SCRATCH < 4
27.92 -#error "Scratch array defined too small "
27.93 -#endif
27.94 -
27.95 - /* Check for point at infinity */
27.96 - if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
27.97 - /* Set r = pt at infinity by setting rz = 0 */
27.98 -
27.99 - MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
27.100 - goto CLEANUP;
27.101 - }
27.102 -
27.103 - /* M = 3 (px^2) + a*(pz^4) */
27.104 - MP_CHECKOK(group->meth->field_sqr(px, t0, group->meth));
27.105 - MP_CHECKOK(group->meth->field_add(t0, t0, M, group->meth));
27.106 - MP_CHECKOK(group->meth->field_add(t0, M, t0, group->meth));
27.107 - MP_CHECKOK(group->meth->field_add(t0, paz4, M, group->meth));
27.108 -
27.109 - /* rz = 2 * py * pz */
27.110 - MP_CHECKOK(group->meth->field_mul(py, pz, S, group->meth));
27.111 - MP_CHECKOK(group->meth->field_add(S, S, rz, group->meth));
27.112 -
27.113 - /* t0 = 2y^2 , t1 = 8y^4 */
27.114 - MP_CHECKOK(group->meth->field_sqr(py, t0, group->meth));
27.115 - MP_CHECKOK(group->meth->field_add(t0, t0, t0, group->meth));
27.116 - MP_CHECKOK(group->meth->field_sqr(t0, t1, group->meth));
27.117 - MP_CHECKOK(group->meth->field_add(t1, t1, t1, group->meth));
27.118 -
27.119 - /* S = 4 * px * py^2 = 2 * px * t0 */
27.120 - MP_CHECKOK(group->meth->field_mul(px, t0, S, group->meth));
27.121 - MP_CHECKOK(group->meth->field_add(S, S, S, group->meth));
27.122 -
27.123 -
27.124 - /* rx = M^2 - 2S */
27.125 - MP_CHECKOK(group->meth->field_sqr(M, rx, group->meth));
27.126 - MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
27.127 - MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
27.128 -
27.129 - /* ry = M * (S - rx) - t1 */
27.130 - MP_CHECKOK(group->meth->field_sub(S, rx, S, group->meth));
27.131 - MP_CHECKOK(group->meth->field_mul(S, M, ry, group->meth));
27.132 - MP_CHECKOK(group->meth->field_sub(ry, t1, ry, group->meth));
27.133 -
27.134 - /* ra*z^4 = 2*t1*(apz4) */
27.135 - MP_CHECKOK(group->meth->field_mul(paz4, t1, raz4, group->meth));
27.136 - MP_CHECKOK(group->meth->field_add(raz4, raz4, raz4, group->meth));
27.137 -
27.138 -
27.139 - CLEANUP:
27.140 - return res;
27.141 -}
27.142 -
27.143 -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
27.144 - * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
27.145 - * Uses mixed Modified_Jacobian-affine coordinates. Assumes input is
27.146 - * already field-encoded using field_enc, and returns output that is still
27.147 - * field-encoded. */
27.148 -mp_err
27.149 -ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
27.150 - const mp_int *paz4, const mp_int *qx,
27.151 - const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz,
27.152 - mp_int *raz4, mp_int scratch[], const ECGroup *group)
27.153 -{
27.154 - mp_err res = MP_OKAY;
27.155 - mp_int *A, *B, *C, *D, *C2, *C3;
27.156 -
27.157 - A = &scratch[0];
27.158 - B = &scratch[1];
27.159 - C = &scratch[2];
27.160 - D = &scratch[3];
27.161 - C2 = &scratch[4];
27.162 - C3 = &scratch[5];
27.163 -
27.164 -#if MAX_SCRATCH < 6
27.165 -#error "Scratch array defined too small "
27.166 -#endif
27.167 -
27.168 - /* If either P or Q is the point at infinity, then return the other
27.169 - * point */
27.170 - if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
27.171 - MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
27.172 - MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
27.173 - MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
27.174 - MP_CHECKOK(group->meth->
27.175 - field_mul(raz4, &group->curvea, raz4, group->meth));
27.176 - goto CLEANUP;
27.177 - }
27.178 - if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
27.179 - MP_CHECKOK(mp_copy(px, rx));
27.180 - MP_CHECKOK(mp_copy(py, ry));
27.181 - MP_CHECKOK(mp_copy(pz, rz));
27.182 - MP_CHECKOK(mp_copy(paz4, raz4));
27.183 - goto CLEANUP;
27.184 - }
27.185 -
27.186 - /* A = qx * pz^2, B = qy * pz^3 */
27.187 - MP_CHECKOK(group->meth->field_sqr(pz, A, group->meth));
27.188 - MP_CHECKOK(group->meth->field_mul(A, pz, B, group->meth));
27.189 - MP_CHECKOK(group->meth->field_mul(A, qx, A, group->meth));
27.190 - MP_CHECKOK(group->meth->field_mul(B, qy, B, group->meth));
27.191 -
27.192 - /* C = A - px, D = B - py */
27.193 - MP_CHECKOK(group->meth->field_sub(A, px, C, group->meth));
27.194 - MP_CHECKOK(group->meth->field_sub(B, py, D, group->meth));
27.195 -
27.196 - /* C2 = C^2, C3 = C^3 */
27.197 - MP_CHECKOK(group->meth->field_sqr(C, C2, group->meth));
27.198 - MP_CHECKOK(group->meth->field_mul(C, C2, C3, group->meth));
27.199 -
27.200 - /* rz = pz * C */
27.201 - MP_CHECKOK(group->meth->field_mul(pz, C, rz, group->meth));
27.202 -
27.203 - /* C = px * C^2 */
27.204 - MP_CHECKOK(group->meth->field_mul(px, C2, C, group->meth));
27.205 - /* A = D^2 */
27.206 - MP_CHECKOK(group->meth->field_sqr(D, A, group->meth));
27.207 -
27.208 - /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
27.209 - MP_CHECKOK(group->meth->field_add(C, C, rx, group->meth));
27.210 - MP_CHECKOK(group->meth->field_add(C3, rx, rx, group->meth));
27.211 - MP_CHECKOK(group->meth->field_sub(A, rx, rx, group->meth));
27.212 -
27.213 - /* C3 = py * C^3 */
27.214 - MP_CHECKOK(group->meth->field_mul(py, C3, C3, group->meth));
27.215 -
27.216 - /* ry = D * (px * C^2 - rx) - py * C^3 */
27.217 - MP_CHECKOK(group->meth->field_sub(C, rx, ry, group->meth));
27.218 - MP_CHECKOK(group->meth->field_mul(D, ry, ry, group->meth));
27.219 - MP_CHECKOK(group->meth->field_sub(ry, C3, ry, group->meth));
27.220 -
27.221 - /* raz4 = a * rz^4 */
27.222 - MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
27.223 - MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
27.224 - MP_CHECKOK(group->meth->
27.225 - field_mul(raz4, &group->curvea, raz4, group->meth));
27.226 -CLEANUP:
27.227 - return res;
27.228 -}
27.229 -
27.230 -/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
27.231 - * curve points P and R can be identical. Uses mixed Modified-Jacobian
27.232 - * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
27.233 - * additions. Assumes input is already field-encoded using field_enc, and
27.234 - * returns output that is still field-encoded. Uses 5-bit window NAF
27.235 - * method (algorithm 11) for scalar-point multiplication from Brown,
27.236 - * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
27.237 - * Curves Over Prime Fields. */
27.238 -mp_err
27.239 -ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
27.240 - mp_int *rx, mp_int *ry, const ECGroup *group)
27.241 -{
27.242 - mp_err res = MP_OKAY;
27.243 - mp_int precomp[16][2], rz, tpx, tpy;
27.244 - mp_int raz4;
27.245 - mp_int scratch[MAX_SCRATCH];
27.246 - signed char *naf = NULL;
27.247 - int i, orderBitSize;
27.248 -
27.249 - MP_DIGITS(&rz) = 0;
27.250 - MP_DIGITS(&raz4) = 0;
27.251 - MP_DIGITS(&tpx) = 0;
27.252 - MP_DIGITS(&tpy) = 0;
27.253 - for (i = 0; i < 16; i++) {
27.254 - MP_DIGITS(&precomp[i][0]) = 0;
27.255 - MP_DIGITS(&precomp[i][1]) = 0;
27.256 - }
27.257 - for (i = 0; i < MAX_SCRATCH; i++) {
27.258 - MP_DIGITS(&scratch[i]) = 0;
27.259 - }
27.260 -
27.261 - ARGCHK(group != NULL, MP_BADARG);
27.262 - ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
27.263 -
27.264 - /* initialize precomputation table */
27.265 - MP_CHECKOK(mp_init(&tpx, FLAG(n)));
27.266 - MP_CHECKOK(mp_init(&tpy, FLAG(n)));;
27.267 - MP_CHECKOK(mp_init(&rz, FLAG(n)));
27.268 - MP_CHECKOK(mp_init(&raz4, FLAG(n)));
27.269 -
27.270 - for (i = 0; i < 16; i++) {
27.271 - MP_CHECKOK(mp_init(&precomp[i][0], FLAG(n)));
27.272 - MP_CHECKOK(mp_init(&precomp[i][1], FLAG(n)));
27.273 - }
27.274 - for (i = 0; i < MAX_SCRATCH; i++) {
27.275 - MP_CHECKOK(mp_init(&scratch[i], FLAG(n)));
27.276 - }
27.277 -
27.278 - /* Set out[8] = P */
27.279 - MP_CHECKOK(mp_copy(px, &precomp[8][0]));
27.280 - MP_CHECKOK(mp_copy(py, &precomp[8][1]));
27.281 -
27.282 - /* Set (tpx, tpy) = 2P */
27.283 - MP_CHECKOK(group->
27.284 - point_dbl(&precomp[8][0], &precomp[8][1], &tpx, &tpy,
27.285 - group));
27.286 -
27.287 - /* Set 3P, 5P, ..., 15P */
27.288 - for (i = 8; i < 15; i++) {
27.289 - MP_CHECKOK(group->
27.290 - point_add(&precomp[i][0], &precomp[i][1], &tpx, &tpy,
27.291 - &precomp[i + 1][0], &precomp[i + 1][1],
27.292 - group));
27.293 - }
27.294 -
27.295 - /* Set -15P, -13P, ..., -P */
27.296 - for (i = 0; i < 8; i++) {
27.297 - MP_CHECKOK(mp_copy(&precomp[15 - i][0], &precomp[i][0]));
27.298 - MP_CHECKOK(group->meth->
27.299 - field_neg(&precomp[15 - i][1], &precomp[i][1],
27.300 - group->meth));
27.301 - }
27.302 -
27.303 - /* R = inf */
27.304 - MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
27.305 -
27.306 - orderBitSize = mpl_significant_bits(&group->order);
27.307 -
27.308 - /* Allocate memory for NAF */
27.309 -#ifdef _KERNEL
27.310 - naf = (signed char *) kmem_alloc((orderBitSize + 1), FLAG(n));
27.311 -#else
27.312 - naf = (signed char *) malloc(sizeof(signed char) * (orderBitSize + 1));
27.313 - if (naf == NULL) {
27.314 - res = MP_MEM;
27.315 - goto CLEANUP;
27.316 - }
27.317 -#endif
27.318 -
27.319 - /* Compute 5NAF */
27.320 - ec_compute_wNAF(naf, orderBitSize, n, 5);
27.321 -
27.322 - /* wNAF method */
27.323 - for (i = orderBitSize; i >= 0; i--) {
27.324 - /* R = 2R */
27.325 - ec_GFp_pt_dbl_jm(rx, ry, &rz, &raz4, rx, ry, &rz,
27.326 - &raz4, scratch, group);
27.327 - if (naf[i] != 0) {
27.328 - ec_GFp_pt_add_jm_aff(rx, ry, &rz, &raz4,
27.329 - &precomp[(naf[i] + 15) / 2][0],
27.330 - &precomp[(naf[i] + 15) / 2][1], rx, ry,
27.331 - &rz, &raz4, scratch, group);
27.332 - }
27.333 - }
27.334 -
27.335 - /* convert result S to affine coordinates */
27.336 - MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
27.337 -
27.338 - CLEANUP:
27.339 - for (i = 0; i < MAX_SCRATCH; i++) {
27.340 - mp_clear(&scratch[i]);
27.341 - }
27.342 - for (i = 0; i < 16; i++) {
27.343 - mp_clear(&precomp[i][0]);
27.344 - mp_clear(&precomp[i][1]);
27.345 - }
27.346 - mp_clear(&tpx);
27.347 - mp_clear(&tpy);
27.348 - mp_clear(&rz);
27.349 - mp_clear(&raz4);
27.350 -#ifdef _KERNEL
27.351 - kmem_free(naf, (orderBitSize + 1));
27.352 -#else
27.353 - free(naf);
27.354 -#endif
27.355 - return res;
27.356 -}
28.1 --- a/src/share/native/sun/security/ec/ecp_mont.c Tue Oct 13 15:25:58 2009 -0700
28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
28.3 @@ -1,223 +0,0 @@
28.4 -/* *********************************************************************
28.5 - *
28.6 - * Sun elects to have this file available under and governed by the
28.7 - * Mozilla Public License Version 1.1 ("MPL") (see
28.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
28.9 - * of doubt and subject to the following, Sun also elects to allow
28.10 - * licensees to use this file under the MPL, the GNU General Public
28.11 - * License version 2 only or the Lesser General Public License version
28.12 - * 2.1 only. Any references to the "GNU General Public License version 2
28.13 - * or later" or "GPL" in the following shall be construed to mean the
28.14 - * GNU General Public License version 2 only. Any references to the "GNU
28.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
28.16 - * following shall be construed to mean the GNU Lesser General Public
28.17 - * License version 2.1 only. However, the following notice accompanied
28.18 - * the original version of this file:
28.19 - *
28.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
28.21 - *
28.22 - * The contents of this file are subject to the Mozilla Public License Version
28.23 - * 1.1 (the "License"); you may not use this file except in compliance with
28.24 - * the License. You may obtain a copy of the License at
28.25 - * http://www.mozilla.org/MPL/
28.26 - *
28.27 - * Software distributed under the License is distributed on an "AS IS" basis,
28.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
28.29 - * for the specific language governing rights and limitations under the
28.30 - * License.
28.31 - *
28.32 - * The Original Code is the elliptic curve math library.
28.33 - *
28.34 - * The Initial Developer of the Original Code is
28.35 - * Sun Microsystems, Inc.
28.36 - * Portions created by the Initial Developer are Copyright (C) 2003
28.37 - * the Initial Developer. All Rights Reserved.
28.38 - *
28.39 - * Contributor(s):
28.40 - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
28.41 - *
28.42 - * Alternatively, the contents of this file may be used under the terms of
28.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
28.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
28.46 - * of those above. If you wish to allow use of your version of this file only
28.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
28.48 - * use your version of this file under the terms of the MPL, indicate your
28.49 - * decision by deleting the provisions above and replace them with the notice
28.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
28.51 - * the provisions above, a recipient may use your version of this file under
28.52 - * the terms of any one of the MPL, the GPL or the LGPL.
28.53 - *
28.54 - *********************************************************************** */
28.55 -/*
28.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
28.57 - * Use is subject to license terms.
28.58 - */
28.59 -
28.60 -#pragma ident "%Z%%M% %I% %E% SMI"
28.61 -
28.62 -/* Uses Montgomery reduction for field arithmetic. See mpi/mpmontg.c for
28.63 - * code implementation. */
28.64 -
28.65 -#include "mpi.h"
28.66 -#include "mplogic.h"
28.67 -#include "mpi-priv.h"
28.68 -#include "ecl-priv.h"
28.69 -#include "ecp.h"
28.70 -#ifndef _KERNEL
28.71 -#include <stdlib.h>
28.72 -#include <stdio.h>
28.73 -#endif
28.74 -
28.75 -/* Construct a generic GFMethod for arithmetic over prime fields with
28.76 - * irreducible irr. */
28.77 -GFMethod *
28.78 -GFMethod_consGFp_mont(const mp_int *irr)
28.79 -{
28.80 - mp_err res = MP_OKAY;
28.81 - int i;
28.82 - GFMethod *meth = NULL;
28.83 - mp_mont_modulus *mmm;
28.84 -
28.85 - meth = GFMethod_consGFp(irr);
28.86 - if (meth == NULL)
28.87 - return NULL;
28.88 -
28.89 -#ifdef _KERNEL
28.90 - mmm = (mp_mont_modulus *) kmem_alloc(sizeof(mp_mont_modulus),
28.91 - FLAG(irr));
28.92 -#else
28.93 - mmm = (mp_mont_modulus *) malloc(sizeof(mp_mont_modulus));
28.94 -#endif
28.95 - if (mmm == NULL) {
28.96 - res = MP_MEM;
28.97 - goto CLEANUP;
28.98 - }
28.99 -
28.100 - meth->field_mul = &ec_GFp_mul_mont;
28.101 - meth->field_sqr = &ec_GFp_sqr_mont;
28.102 - meth->field_div = &ec_GFp_div_mont;
28.103 - meth->field_enc = &ec_GFp_enc_mont;
28.104 - meth->field_dec = &ec_GFp_dec_mont;
28.105 - meth->extra1 = mmm;
28.106 - meth->extra2 = NULL;
28.107 - meth->extra_free = &ec_GFp_extra_free_mont;
28.108 -
28.109 - mmm->N = meth->irr;
28.110 - i = mpl_significant_bits(&meth->irr);
28.111 - i += MP_DIGIT_BIT - 1;
28.112 - mmm->b = i - i % MP_DIGIT_BIT;
28.113 - mmm->n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(&meth->irr, 0));
28.114 -
28.115 - CLEANUP:
28.116 - if (res != MP_OKAY) {
28.117 - GFMethod_free(meth);
28.118 - return NULL;
28.119 - }
28.120 - return meth;
28.121 -}
28.122 -
28.123 -/* Wrapper functions for generic prime field arithmetic. */
28.124 -
28.125 -/* Field multiplication using Montgomery reduction. */
28.126 -mp_err
28.127 -ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
28.128 - const GFMethod *meth)
28.129 -{
28.130 - mp_err res = MP_OKAY;
28.131 -
28.132 -#ifdef MP_MONT_USE_MP_MUL
28.133 - /* if MP_MONT_USE_MP_MUL is defined, then the function s_mp_mul_mont
28.134 - * is not implemented and we have to use mp_mul and s_mp_redc directly
28.135 - */
28.136 - MP_CHECKOK(mp_mul(a, b, r));
28.137 - MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
28.138 -#else
28.139 - mp_int s;
28.140 -
28.141 - MP_DIGITS(&s) = 0;
28.142 - /* s_mp_mul_mont doesn't allow source and destination to be the same */
28.143 - if ((a == r) || (b == r)) {
28.144 - MP_CHECKOK(mp_init(&s, FLAG(a)));
28.145 - MP_CHECKOK(s_mp_mul_mont
28.146 - (a, b, &s, (mp_mont_modulus *) meth->extra1));
28.147 - MP_CHECKOK(mp_copy(&s, r));
28.148 - mp_clear(&s);
28.149 - } else {
28.150 - return s_mp_mul_mont(a, b, r, (mp_mont_modulus *) meth->extra1);
28.151 - }
28.152 -#endif
28.153 - CLEANUP:
28.154 - return res;
28.155 -}
28.156 -
28.157 -/* Field squaring using Montgomery reduction. */
28.158 -mp_err
28.159 -ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
28.160 -{
28.161 - return ec_GFp_mul_mont(a, a, r, meth);
28.162 -}
28.163 -
28.164 -/* Field division using Montgomery reduction. */
28.165 -mp_err
28.166 -ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
28.167 - const GFMethod *meth)
28.168 -{
28.169 - mp_err res = MP_OKAY;
28.170 -
28.171 - /* if A=aZ represents a encoded in montgomery coordinates with Z and #
28.172 - * and \ respectively represent multiplication and division in
28.173 - * montgomery coordinates, then A\B = (a/b)Z = (A/B)Z and Binv =
28.174 - * (1/b)Z = (1/B)(Z^2) where B # Binv = Z */
28.175 - MP_CHECKOK(ec_GFp_div(a, b, r, meth));
28.176 - MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
28.177 - if (a == NULL) {
28.178 - MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
28.179 - }
28.180 - CLEANUP:
28.181 - return res;
28.182 -}
28.183 -
28.184 -/* Encode a field element in Montgomery form. See s_mp_to_mont in
28.185 - * mpi/mpmontg.c */
28.186 -mp_err
28.187 -ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
28.188 -{
28.189 - mp_mont_modulus *mmm;
28.190 - mp_err res = MP_OKAY;
28.191 -
28.192 - mmm = (mp_mont_modulus *) meth->extra1;
28.193 - MP_CHECKOK(mpl_lsh(a, r, mmm->b));
28.194 - MP_CHECKOK(mp_mod(r, &mmm->N, r));
28.195 - CLEANUP:
28.196 - return res;
28.197 -}
28.198 -
28.199 -/* Decode a field element from Montgomery form. */
28.200 -mp_err
28.201 -ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
28.202 -{
28.203 - mp_err res = MP_OKAY;
28.204 -
28.205 - if (a != r) {
28.206 - MP_CHECKOK(mp_copy(a, r));
28.207 - }
28.208 - MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
28.209 - CLEANUP:
28.210 - return res;
28.211 -}
28.212 -
28.213 -/* Free the memory allocated to the extra fields of Montgomery GFMethod
28.214 - * object. */
28.215 -void
28.216 -ec_GFp_extra_free_mont(GFMethod *meth)
28.217 -{
28.218 - if (meth->extra1 != NULL) {
28.219 -#ifdef _KERNEL
28.220 - kmem_free(meth->extra1, sizeof(mp_mont_modulus));
28.221 -#else
28.222 - free(meth->extra1);
28.223 -#endif
28.224 - meth->extra1 = NULL;
28.225 - }
28.226 -}
29.1 --- a/src/share/native/sun/security/ec/logtab.h Tue Oct 13 15:25:58 2009 -0700
29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
29.3 @@ -1,82 +0,0 @@
29.4 -/* *********************************************************************
29.5 - *
29.6 - * Sun elects to have this file available under and governed by the
29.7 - * Mozilla Public License Version 1.1 ("MPL") (see
29.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
29.9 - * of doubt and subject to the following, Sun also elects to allow
29.10 - * licensees to use this file under the MPL, the GNU General Public
29.11 - * License version 2 only or the Lesser General Public License version
29.12 - * 2.1 only. Any references to the "GNU General Public License version 2
29.13 - * or later" or "GPL" in the following shall be construed to mean the
29.14 - * GNU General Public License version 2 only. Any references to the "GNU
29.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
29.16 - * following shall be construed to mean the GNU Lesser General Public
29.17 - * License version 2.1 only. However, the following notice accompanied
29.18 - * the original version of this file:
29.19 - *
29.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
29.21 - *
29.22 - * The contents of this file are subject to the Mozilla Public License Version
29.23 - * 1.1 (the "License"); you may not use this file except in compliance with
29.24 - * the License. You may obtain a copy of the License at
29.25 - * http://www.mozilla.org/MPL/
29.26 - *
29.27 - * Software distributed under the License is distributed on an "AS IS" basis,
29.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
29.29 - * for the specific language governing rights and limitations under the
29.30 - * License.
29.31 - *
29.32 - * The Original Code is the Netscape security libraries.
29.33 - *
29.34 - * The Initial Developer of the Original Code is
29.35 - * Netscape Communications Corporation.
29.36 - * Portions created by the Initial Developer are Copyright (C) 1994-2000
29.37 - * the Initial Developer. All Rights Reserved.
29.38 - *
29.39 - * Contributor(s):
29.40 - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
29.41 - *
29.42 - * Alternatively, the contents of this file may be used under the terms of
29.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
29.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
29.46 - * of those above. If you wish to allow use of your version of this file only
29.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
29.48 - * use your version of this file under the terms of the MPL, indicate your
29.49 - * decision by deleting the provisions above and replace them with the notice
29.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
29.51 - * the provisions above, a recipient may use your version of this file under
29.52 - * the terms of any one of the MPL, the GPL or the LGPL.
29.53 - *
29.54 - *********************************************************************** */
29.55 -/*
29.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
29.57 - * Use is subject to license terms.
29.58 - */
29.59 -
29.60 -#ifndef _LOGTAB_H
29.61 -#define _LOGTAB_H
29.62 -
29.63 -#pragma ident "%Z%%M% %I% %E% SMI"
29.64 -
29.65 -const float s_logv_2[] = {
29.66 - 0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */
29.67 - 0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */
29.68 - 0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f, /* 8 9 10 11 */
29.69 - 0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f, /* 12 13 14 15 */
29.70 - 0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f, /* 16 17 18 19 */
29.71 - 0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f, /* 20 21 22 23 */
29.72 - 0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f, /* 24 25 26 27 */
29.73 - 0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f, /* 28 29 30 31 */
29.74 - 0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f, /* 32 33 34 35 */
29.75 - 0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f, /* 36 37 38 39 */
29.76 - 0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f, /* 40 41 42 43 */
29.77 - 0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f, /* 44 45 46 47 */
29.78 - 0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f, /* 48 49 50 51 */
29.79 - 0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f, /* 52 53 54 55 */
29.80 - 0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f, /* 56 57 58 59 */
29.81 - 0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f, /* 60 61 62 63 */
29.82 - 0.166666667f
29.83 -};
29.84 -
29.85 -#endif /* _LOGTAB_H */
30.1 --- a/src/share/native/sun/security/ec/mp_gf2m-priv.h Tue Oct 13 15:25:58 2009 -0700
30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
30.3 @@ -1,122 +0,0 @@
30.4 -/* *********************************************************************
30.5 - *
30.6 - * Sun elects to have this file available under and governed by the
30.7 - * Mozilla Public License Version 1.1 ("MPL") (see
30.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
30.9 - * of doubt and subject to the following, Sun also elects to allow
30.10 - * licensees to use this file under the MPL, the GNU General Public
30.11 - * License version 2 only or the Lesser General Public License version
30.12 - * 2.1 only. Any references to the "GNU General Public License version 2
30.13 - * or later" or "GPL" in the following shall be construed to mean the
30.14 - * GNU General Public License version 2 only. Any references to the "GNU
30.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
30.16 - * following shall be construed to mean the GNU Lesser General Public
30.17 - * License version 2.1 only. However, the following notice accompanied
30.18 - * the original version of this file:
30.19 - *
30.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
30.21 - *
30.22 - * The contents of this file are subject to the Mozilla Public License Version
30.23 - * 1.1 (the "License"); you may not use this file except in compliance with
30.24 - * the License. You may obtain a copy of the License at
30.25 - * http://www.mozilla.org/MPL/
30.26 - *
30.27 - * Software distributed under the License is distributed on an "AS IS" basis,
30.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
30.29 - * for the specific language governing rights and limitations under the
30.30 - * License.
30.31 - *
30.32 - * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
30.33 - *
30.34 - * The Initial Developer of the Original Code is
30.35 - * Sun Microsystems, Inc.
30.36 - * Portions created by the Initial Developer are Copyright (C) 2003
30.37 - * the Initial Developer. All Rights Reserved.
30.38 - *
30.39 - * Contributor(s):
30.40 - * Sheueling Chang Shantz <sheueling.chang@sun.com> and
30.41 - * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
30.42 - *
30.43 - * Alternatively, the contents of this file may be used under the terms of
30.44 - * either the GNU General Public License Version 2 or later (the "GPL"), or
30.45 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30.46 - * in which case the provisions of the GPL or the LGPL are applicable instead
30.47 - * of those above. If you wish to allow use of your version of this file only
30.48 - * under the terms of either the GPL or the LGPL, and not to allow others to
30.49 - * use your version of this file under the terms of the MPL, indicate your
30.50 - * decision by deleting the provisions above and replace them with the notice
30.51 - * and other provisions required by the GPL or the LGPL. If you do not delete
30.52 - * the provisions above, a recipient may use your version of this file under
30.53 - * the terms of any one of the MPL, the GPL or the LGPL.
30.54 - *
30.55 - *********************************************************************** */
30.56 -/*
30.57 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
30.58 - * Use is subject to license terms.
30.59 - */
30.60 -
30.61 -#ifndef _MP_GF2M_PRIV_H_
30.62 -#define _MP_GF2M_PRIV_H_
30.63 -
30.64 -#pragma ident "%Z%%M% %I% %E% SMI"
30.65 -
30.66 -#include "mpi-priv.h"
30.67 -
30.68 -extern const mp_digit mp_gf2m_sqr_tb[16];
30.69 -
30.70 -#if defined(MP_USE_UINT_DIGIT)
30.71 -#define MP_DIGIT_BITS 32
30.72 -#else
30.73 -#define MP_DIGIT_BITS 64
30.74 -#endif
30.75 -
30.76 -/* Platform-specific macros for fast binary polynomial squaring. */
30.77 -#if MP_DIGIT_BITS == 32
30.78 -#define gf2m_SQR1(w) \
30.79 - mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 16 | \
30.80 - mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF]
30.81 -#define gf2m_SQR0(w) \
30.82 - mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \
30.83 - mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF]
30.84 -#else
30.85 -#define gf2m_SQR1(w) \
30.86 - mp_gf2m_sqr_tb[(w) >> 60 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 56 & 0xF] << 48 | \
30.87 - mp_gf2m_sqr_tb[(w) >> 52 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 48 & 0xF] << 32 | \
30.88 - mp_gf2m_sqr_tb[(w) >> 44 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 40 & 0xF] << 16 | \
30.89 - mp_gf2m_sqr_tb[(w) >> 36 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 32 & 0xF]
30.90 -#define gf2m_SQR0(w) \
30.91 - mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 48 | \
30.92 - mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] << 32 | \
30.93 - mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \
30.94 - mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF]
30.95 -#endif
30.96 -
30.97 -/* Multiply two binary polynomials mp_digits a, b.
30.98 - * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
30.99 - * Output in two mp_digits rh, rl.
30.100 - */
30.101 -void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b);
30.102 -
30.103 -/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0)
30.104 - * result is a binary polynomial in 4 mp_digits r[4].
30.105 - * The caller MUST ensure that r has the right amount of space allocated.
30.106 - */
30.107 -void s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
30.108 - const mp_digit b0);
30.109 -
30.110 -/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0)
30.111 - * result is a binary polynomial in 6 mp_digits r[6].
30.112 - * The caller MUST ensure that r has the right amount of space allocated.
30.113 - */
30.114 -void s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
30.115 - const mp_digit b2, const mp_digit b1, const mp_digit b0);
30.116 -
30.117 -/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0)
30.118 - * result is a binary polynomial in 8 mp_digits r[8].
30.119 - * The caller MUST ensure that r has the right amount of space allocated.
30.120 - */
30.121 -void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
30.122 - const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
30.123 - const mp_digit b0);
30.124 -
30.125 -#endif /* _MP_GF2M_PRIV_H_ */
31.1 --- a/src/share/native/sun/security/ec/mp_gf2m.c Tue Oct 13 15:25:58 2009 -0700
31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
31.3 @@ -1,624 +0,0 @@
31.4 -/* *********************************************************************
31.5 - *
31.6 - * Sun elects to have this file available under and governed by the
31.7 - * Mozilla Public License Version 1.1 ("MPL") (see
31.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
31.9 - * of doubt and subject to the following, Sun also elects to allow
31.10 - * licensees to use this file under the MPL, the GNU General Public
31.11 - * License version 2 only or the Lesser General Public License version
31.12 - * 2.1 only. Any references to the "GNU General Public License version 2
31.13 - * or later" or "GPL" in the following shall be construed to mean the
31.14 - * GNU General Public License version 2 only. Any references to the "GNU
31.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
31.16 - * following shall be construed to mean the GNU Lesser General Public
31.17 - * License version 2.1 only. However, the following notice accompanied
31.18 - * the original version of this file:
31.19 - *
31.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
31.21 - *
31.22 - * The contents of this file are subject to the Mozilla Public License Version
31.23 - * 1.1 (the "License"); you may not use this file except in compliance with
31.24 - * the License. You may obtain a copy of the License at
31.25 - * http://www.mozilla.org/MPL/
31.26 - *
31.27 - * Software distributed under the License is distributed on an "AS IS" basis,
31.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
31.29 - * for the specific language governing rights and limitations under the
31.30 - * License.
31.31 - *
31.32 - * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
31.33 - *
31.34 - * The Initial Developer of the Original Code is
31.35 - * Sun Microsystems, Inc.
31.36 - * Portions created by the Initial Developer are Copyright (C) 2003
31.37 - * the Initial Developer. All Rights Reserved.
31.38 - *
31.39 - * Contributor(s):
31.40 - * Sheueling Chang Shantz <sheueling.chang@sun.com> and
31.41 - * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
31.42 - *
31.43 - * Alternatively, the contents of this file may be used under the terms of
31.44 - * either the GNU General Public License Version 2 or later (the "GPL"), or
31.45 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31.46 - * in which case the provisions of the GPL or the LGPL are applicable instead
31.47 - * of those above. If you wish to allow use of your version of this file only
31.48 - * under the terms of either the GPL or the LGPL, and not to allow others to
31.49 - * use your version of this file under the terms of the MPL, indicate your
31.50 - * decision by deleting the provisions above and replace them with the notice
31.51 - * and other provisions required by the GPL or the LGPL. If you do not delete
31.52 - * the provisions above, a recipient may use your version of this file under
31.53 - * the terms of any one of the MPL, the GPL or the LGPL.
31.54 - *
31.55 - *********************************************************************** */
31.56 -/*
31.57 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
31.58 - * Use is subject to license terms.
31.59 - */
31.60 -
31.61 -#pragma ident "%Z%%M% %I% %E% SMI"
31.62 -
31.63 -#include "mp_gf2m.h"
31.64 -#include "mp_gf2m-priv.h"
31.65 -#include "mplogic.h"
31.66 -#include "mpi-priv.h"
31.67 -
31.68 -const mp_digit mp_gf2m_sqr_tb[16] =
31.69 -{
31.70 - 0, 1, 4, 5, 16, 17, 20, 21,
31.71 - 64, 65, 68, 69, 80, 81, 84, 85
31.72 -};
31.73 -
31.74 -/* Multiply two binary polynomials mp_digits a, b.
31.75 - * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
31.76 - * Output in two mp_digits rh, rl.
31.77 - */
31.78 -#if MP_DIGIT_BITS == 32
31.79 -void
31.80 -s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
31.81 -{
31.82 - register mp_digit h, l, s;
31.83 - mp_digit tab[8], top2b = a >> 30;
31.84 - register mp_digit a1, a2, a4;
31.85 -
31.86 - a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
31.87 -
31.88 - tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
31.89 - tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
31.90 -
31.91 - s = tab[b & 0x7]; l = s;
31.92 - s = tab[b >> 3 & 0x7]; l ^= s << 3; h = s >> 29;
31.93 - s = tab[b >> 6 & 0x7]; l ^= s << 6; h ^= s >> 26;
31.94 - s = tab[b >> 9 & 0x7]; l ^= s << 9; h ^= s >> 23;
31.95 - s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
31.96 - s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
31.97 - s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
31.98 - s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
31.99 - s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >> 8;
31.100 - s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >> 5;
31.101 - s = tab[b >> 30 ]; l ^= s << 30; h ^= s >> 2;
31.102 -
31.103 - /* compensate for the top two bits of a */
31.104 -
31.105 - if (top2b & 01) { l ^= b << 30; h ^= b >> 2; }
31.106 - if (top2b & 02) { l ^= b << 31; h ^= b >> 1; }
31.107 -
31.108 - *rh = h; *rl = l;
31.109 -}
31.110 -#else
31.111 -void
31.112 -s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
31.113 -{
31.114 - register mp_digit h, l, s;
31.115 - mp_digit tab[16], top3b = a >> 61;
31.116 - register mp_digit a1, a2, a4, a8;
31.117 -
31.118 - a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1;
31.119 - a4 = a2 << 1; a8 = a4 << 1;
31.120 - tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2;
31.121 - tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4;
31.122 - tab[ 8] = a8; tab[ 9] = a1^a8; tab[10] = a2^a8; tab[11] = a1^a2^a8;
31.123 - tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
31.124 -
31.125 - s = tab[b & 0xF]; l = s;
31.126 - s = tab[b >> 4 & 0xF]; l ^= s << 4; h = s >> 60;
31.127 - s = tab[b >> 8 & 0xF]; l ^= s << 8; h ^= s >> 56;
31.128 - s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
31.129 - s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
31.130 - s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
31.131 - s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
31.132 - s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
31.133 - s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
31.134 - s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
31.135 - s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
31.136 - s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
31.137 - s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
31.138 - s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
31.139 - s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >> 8;
31.140 - s = tab[b >> 60 ]; l ^= s << 60; h ^= s >> 4;
31.141 -
31.142 - /* compensate for the top three bits of a */
31.143 -
31.144 - if (top3b & 01) { l ^= b << 61; h ^= b >> 3; }
31.145 - if (top3b & 02) { l ^= b << 62; h ^= b >> 2; }
31.146 - if (top3b & 04) { l ^= b << 63; h ^= b >> 1; }
31.147 -
31.148 - *rh = h; *rl = l;
31.149 -}
31.150 -#endif
31.151 -
31.152 -/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0)
31.153 - * result is a binary polynomial in 4 mp_digits r[4].
31.154 - * The caller MUST ensure that r has the right amount of space allocated.
31.155 - */
31.156 -void
31.157 -s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
31.158 - const mp_digit b0)
31.159 -{
31.160 - mp_digit m1, m0;
31.161 - /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
31.162 - s_bmul_1x1(r+3, r+2, a1, b1);
31.163 - s_bmul_1x1(r+1, r, a0, b0);
31.164 - s_bmul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
31.165 - /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
31.166 - r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */
31.167 - r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
31.168 -}
31.169 -
31.170 -/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0)
31.171 - * result is a binary polynomial in 6 mp_digits r[6].
31.172 - * The caller MUST ensure that r has the right amount of space allocated.
31.173 - */
31.174 -void
31.175 -s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
31.176 - const mp_digit b2, const mp_digit b1, const mp_digit b0)
31.177 -{
31.178 - mp_digit zm[4];
31.179 -
31.180 - s_bmul_1x1(r+5, r+4, a2, b2); /* fill top 2 words */
31.181 - s_bmul_2x2(zm, a1, a2^a0, b1, b2^b0); /* fill middle 4 words */
31.182 - s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */
31.183 -
31.184 - zm[3] ^= r[3];
31.185 - zm[2] ^= r[2];
31.186 - zm[1] ^= r[1] ^ r[5];
31.187 - zm[0] ^= r[0] ^ r[4];
31.188 -
31.189 - r[5] ^= zm[3];
31.190 - r[4] ^= zm[2];
31.191 - r[3] ^= zm[1];
31.192 - r[2] ^= zm[0];
31.193 -}
31.194 -
31.195 -/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0)
31.196 - * result is a binary polynomial in 8 mp_digits r[8].
31.197 - * The caller MUST ensure that r has the right amount of space allocated.
31.198 - */
31.199 -void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
31.200 - const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
31.201 - const mp_digit b0)
31.202 -{
31.203 - mp_digit zm[4];
31.204 -
31.205 - s_bmul_2x2(r+4, a3, a2, b3, b2); /* fill top 4 words */
31.206 - s_bmul_2x2(zm, a3^a1, a2^a0, b3^b1, b2^b0); /* fill middle 4 words */
31.207 - s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */
31.208 -
31.209 - zm[3] ^= r[3] ^ r[7];
31.210 - zm[2] ^= r[2] ^ r[6];
31.211 - zm[1] ^= r[1] ^ r[5];
31.212 - zm[0] ^= r[0] ^ r[4];
31.213 -
31.214 - r[5] ^= zm[3];
31.215 - r[4] ^= zm[2];
31.216 - r[3] ^= zm[1];
31.217 - r[2] ^= zm[0];
31.218 -}
31.219 -
31.220 -/* Compute addition of two binary polynomials a and b,
31.221 - * store result in c; c could be a or b, a and b could be equal;
31.222 - * c is the bitwise XOR of a and b.
31.223 - */
31.224 -mp_err
31.225 -mp_badd(const mp_int *a, const mp_int *b, mp_int *c)
31.226 -{
31.227 - mp_digit *pa, *pb, *pc;
31.228 - mp_size ix;
31.229 - mp_size used_pa, used_pb;
31.230 - mp_err res = MP_OKAY;
31.231 -
31.232 - /* Add all digits up to the precision of b. If b had more
31.233 - * precision than a initially, swap a, b first
31.234 - */
31.235 - if (MP_USED(a) >= MP_USED(b)) {
31.236 - pa = MP_DIGITS(a);
31.237 - pb = MP_DIGITS(b);
31.238 - used_pa = MP_USED(a);
31.239 - used_pb = MP_USED(b);
31.240 - } else {
31.241 - pa = MP_DIGITS(b);
31.242 - pb = MP_DIGITS(a);
31.243 - used_pa = MP_USED(b);
31.244 - used_pb = MP_USED(a);
31.245 - }
31.246 -
31.247 - /* Make sure c has enough precision for the output value */
31.248 - MP_CHECKOK( s_mp_pad(c, used_pa) );
31.249 -
31.250 - /* Do word-by-word xor */
31.251 - pc = MP_DIGITS(c);
31.252 - for (ix = 0; ix < used_pb; ix++) {
31.253 - (*pc++) = (*pa++) ^ (*pb++);
31.254 - }
31.255 -
31.256 - /* Finish the rest of digits until we're actually done */
31.257 - for (; ix < used_pa; ++ix) {
31.258 - *pc++ = *pa++;
31.259 - }
31.260 -
31.261 - MP_USED(c) = used_pa;
31.262 - MP_SIGN(c) = ZPOS;
31.263 - s_mp_clamp(c);
31.264 -
31.265 -CLEANUP:
31.266 - return res;
31.267 -}
31.268 -
31.269 -#define s_mp_div2(a) MP_CHECKOK( mpl_rsh((a), (a), 1) );
31.270 -
31.271 -/* Compute binary polynomial multiply d = a * b */
31.272 -static void
31.273 -s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
31.274 -{
31.275 - mp_digit a_i, a0b0, a1b1, carry = 0;
31.276 - while (a_len--) {
31.277 - a_i = *a++;
31.278 - s_bmul_1x1(&a1b1, &a0b0, a_i, b);
31.279 - *d++ = a0b0 ^ carry;
31.280 - carry = a1b1;
31.281 - }
31.282 - *d = carry;
31.283 -}
31.284 -
31.285 -/* Compute binary polynomial xor multiply accumulate d ^= a * b */
31.286 -static void
31.287 -s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
31.288 -{
31.289 - mp_digit a_i, a0b0, a1b1, carry = 0;
31.290 - while (a_len--) {
31.291 - a_i = *a++;
31.292 - s_bmul_1x1(&a1b1, &a0b0, a_i, b);
31.293 - *d++ ^= a0b0 ^ carry;
31.294 - carry = a1b1;
31.295 - }
31.296 - *d ^= carry;
31.297 -}
31.298 -
31.299 -/* Compute binary polynomial xor multiply c = a * b.
31.300 - * All parameters may be identical.
31.301 - */
31.302 -mp_err
31.303 -mp_bmul(const mp_int *a, const mp_int *b, mp_int *c)
31.304 -{
31.305 - mp_digit *pb, b_i;
31.306 - mp_int tmp;
31.307 - mp_size ib, a_used, b_used;
31.308 - mp_err res = MP_OKAY;
31.309 -
31.310 - MP_DIGITS(&tmp) = 0;
31.311 -
31.312 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
31.313 -
31.314 - if (a == c) {
31.315 - MP_CHECKOK( mp_init_copy(&tmp, a) );
31.316 - if (a == b)
31.317 - b = &tmp;
31.318 - a = &tmp;
31.319 - } else if (b == c) {
31.320 - MP_CHECKOK( mp_init_copy(&tmp, b) );
31.321 - b = &tmp;
31.322 - }
31.323 -
31.324 - if (MP_USED(a) < MP_USED(b)) {
31.325 - const mp_int *xch = b; /* switch a and b if b longer */
31.326 - b = a;
31.327 - a = xch;
31.328 - }
31.329 -
31.330 - MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
31.331 - MP_CHECKOK( s_mp_pad(c, USED(a) + USED(b)) );
31.332 -
31.333 - pb = MP_DIGITS(b);
31.334 - s_bmul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
31.335 -
31.336 - /* Outer loop: Digits of b */
31.337 - a_used = MP_USED(a);
31.338 - b_used = MP_USED(b);
31.339 - MP_USED(c) = a_used + b_used;
31.340 - for (ib = 1; ib < b_used; ib++) {
31.341 - b_i = *pb++;
31.342 -
31.343 - /* Inner product: Digits of a */
31.344 - if (b_i)
31.345 - s_bmul_d_add(MP_DIGITS(a), a_used, b_i, MP_DIGITS(c) + ib);
31.346 - else
31.347 - MP_DIGIT(c, ib + a_used) = b_i;
31.348 - }
31.349 -
31.350 - s_mp_clamp(c);
31.351 -
31.352 - SIGN(c) = ZPOS;
31.353 -
31.354 -CLEANUP:
31.355 - mp_clear(&tmp);
31.356 - return res;
31.357 -}
31.358 -
31.359 -
31.360 -/* Compute modular reduction of a and store result in r.
31.361 - * r could be a.
31.362 - * For modular arithmetic, the irreducible polynomial f(t) is represented
31.363 - * as an array of int[], where f(t) is of the form:
31.364 - * f(t) = t^p[0] + t^p[1] + ... + t^p[k]
31.365 - * where m = p[0] > p[1] > ... > p[k] = 0.
31.366 - */
31.367 -mp_err
31.368 -mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
31.369 -{
31.370 - int j, k;
31.371 - int n, dN, d0, d1;
31.372 - mp_digit zz, *z, tmp;
31.373 - mp_size used;
31.374 - mp_err res = MP_OKAY;
31.375 -
31.376 - /* The algorithm does the reduction in place in r,
31.377 - * if a != r, copy a into r first so reduction can be done in r
31.378 - */
31.379 - if (a != r) {
31.380 - MP_CHECKOK( mp_copy(a, r) );
31.381 - }
31.382 - z = MP_DIGITS(r);
31.383 -
31.384 - /* start reduction */
31.385 - dN = p[0] / MP_DIGIT_BITS;
31.386 - used = MP_USED(r);
31.387 -
31.388 - for (j = used - 1; j > dN;) {
31.389 -
31.390 - zz = z[j];
31.391 - if (zz == 0) {
31.392 - j--; continue;
31.393 - }
31.394 - z[j] = 0;
31.395 -
31.396 - for (k = 1; p[k] > 0; k++) {
31.397 - /* reducing component t^p[k] */
31.398 - n = p[0] - p[k];
31.399 - d0 = n % MP_DIGIT_BITS;
31.400 - d1 = MP_DIGIT_BITS - d0;
31.401 - n /= MP_DIGIT_BITS;
31.402 - z[j-n] ^= (zz>>d0);
31.403 - if (d0)
31.404 - z[j-n-1] ^= (zz<<d1);
31.405 - }
31.406 -
31.407 - /* reducing component t^0 */
31.408 - n = dN;
31.409 - d0 = p[0] % MP_DIGIT_BITS;
31.410 - d1 = MP_DIGIT_BITS - d0;
31.411 - z[j-n] ^= (zz >> d0);
31.412 - if (d0)
31.413 - z[j-n-1] ^= (zz << d1);
31.414 -
31.415 - }
31.416 -
31.417 - /* final round of reduction */
31.418 - while (j == dN) {
31.419 -
31.420 - d0 = p[0] % MP_DIGIT_BITS;
31.421 - zz = z[dN] >> d0;
31.422 - if (zz == 0) break;
31.423 - d1 = MP_DIGIT_BITS - d0;
31.424 -
31.425 - /* clear up the top d1 bits */
31.426 - if (d0) z[dN] = (z[dN] << d1) >> d1;
31.427 - *z ^= zz; /* reduction t^0 component */
31.428 -
31.429 - for (k = 1; p[k] > 0; k++) {
31.430 - /* reducing component t^p[k]*/
31.431 - n = p[k] / MP_DIGIT_BITS;
31.432 - d0 = p[k] % MP_DIGIT_BITS;
31.433 - d1 = MP_DIGIT_BITS - d0;
31.434 - z[n] ^= (zz << d0);
31.435 - tmp = zz >> d1;
31.436 - if (d0 && tmp)
31.437 - z[n+1] ^= tmp;
31.438 - }
31.439 - }
31.440 -
31.441 - s_mp_clamp(r);
31.442 -CLEANUP:
31.443 - return res;
31.444 -}
31.445 -
31.446 -/* Compute the product of two polynomials a and b, reduce modulo p,
31.447 - * Store the result in r. r could be a or b; a could be b.
31.448 - */
31.449 -mp_err
31.450 -mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], mp_int *r)
31.451 -{
31.452 - mp_err res;
31.453 -
31.454 - if (a == b) return mp_bsqrmod(a, p, r);
31.455 - if ((res = mp_bmul(a, b, r) ) != MP_OKAY)
31.456 - return res;
31.457 - return mp_bmod(r, p, r);
31.458 -}
31.459 -
31.460 -/* Compute binary polynomial squaring c = a*a mod p .
31.461 - * Parameter r and a can be identical.
31.462 - */
31.463 -
31.464 -mp_err
31.465 -mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
31.466 -{
31.467 - mp_digit *pa, *pr, a_i;
31.468 - mp_int tmp;
31.469 - mp_size ia, a_used;
31.470 - mp_err res;
31.471 -
31.472 - ARGCHK(a != NULL && r != NULL, MP_BADARG);
31.473 - MP_DIGITS(&tmp) = 0;
31.474 -
31.475 - if (a == r) {
31.476 - MP_CHECKOK( mp_init_copy(&tmp, a) );
31.477 - a = &tmp;
31.478 - }
31.479 -
31.480 - MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
31.481 - MP_CHECKOK( s_mp_pad(r, 2*USED(a)) );
31.482 -
31.483 - pa = MP_DIGITS(a);
31.484 - pr = MP_DIGITS(r);
31.485 - a_used = MP_USED(a);
31.486 - MP_USED(r) = 2 * a_used;
31.487 -
31.488 - for (ia = 0; ia < a_used; ia++) {
31.489 - a_i = *pa++;
31.490 - *pr++ = gf2m_SQR0(a_i);
31.491 - *pr++ = gf2m_SQR1(a_i);
31.492 - }
31.493 -
31.494 - MP_CHECKOK( mp_bmod(r, p, r) );
31.495 - s_mp_clamp(r);
31.496 - SIGN(r) = ZPOS;
31.497 -
31.498 -CLEANUP:
31.499 - mp_clear(&tmp);
31.500 - return res;
31.501 -}
31.502 -
31.503 -/* Compute binary polynomial y/x mod p, y divided by x, reduce modulo p.
31.504 - * Store the result in r. r could be x or y, and x could equal y.
31.505 - * Uses algorithm Modular_Division_GF(2^m) from
31.506 - * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to
31.507 - * the Great Divide".
31.508 - */
31.509 -int
31.510 -mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
31.511 - const unsigned int p[], mp_int *r)
31.512 -{
31.513 - mp_int aa, bb, uu;
31.514 - mp_int *a, *b, *u, *v;
31.515 - mp_err res = MP_OKAY;
31.516 -
31.517 - MP_DIGITS(&aa) = 0;
31.518 - MP_DIGITS(&bb) = 0;
31.519 - MP_DIGITS(&uu) = 0;
31.520 -
31.521 - MP_CHECKOK( mp_init_copy(&aa, x) );
31.522 - MP_CHECKOK( mp_init_copy(&uu, y) );
31.523 - MP_CHECKOK( mp_init_copy(&bb, pp) );
31.524 - MP_CHECKOK( s_mp_pad(r, USED(pp)) );
31.525 - MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
31.526 -
31.527 - a = &aa; b= &bb; u=&uu; v=r;
31.528 - /* reduce x and y mod p */
31.529 - MP_CHECKOK( mp_bmod(a, p, a) );
31.530 - MP_CHECKOK( mp_bmod(u, p, u) );
31.531 -
31.532 - while (!mp_isodd(a)) {
31.533 - s_mp_div2(a);
31.534 - if (mp_isodd(u)) {
31.535 - MP_CHECKOK( mp_badd(u, pp, u) );
31.536 - }
31.537 - s_mp_div2(u);
31.538 - }
31.539 -
31.540 - do {
31.541 - if (mp_cmp_mag(b, a) > 0) {
31.542 - MP_CHECKOK( mp_badd(b, a, b) );
31.543 - MP_CHECKOK( mp_badd(v, u, v) );
31.544 - do {
31.545 - s_mp_div2(b);
31.546 - if (mp_isodd(v)) {
31.547 - MP_CHECKOK( mp_badd(v, pp, v) );
31.548 - }
31.549 - s_mp_div2(v);
31.550 - } while (!mp_isodd(b));
31.551 - }
31.552 - else if ((MP_DIGIT(a,0) == 1) && (MP_USED(a) == 1))
31.553 - break;
31.554 - else {
31.555 - MP_CHECKOK( mp_badd(a, b, a) );
31.556 - MP_CHECKOK( mp_badd(u, v, u) );
31.557 - do {
31.558 - s_mp_div2(a);
31.559 - if (mp_isodd(u)) {
31.560 - MP_CHECKOK( mp_badd(u, pp, u) );
31.561 - }
31.562 - s_mp_div2(u);
31.563 - } while (!mp_isodd(a));
31.564 - }
31.565 - } while (1);
31.566 -
31.567 - MP_CHECKOK( mp_copy(u, r) );
31.568 -
31.569 -CLEANUP:
31.570 - /* XXX this appears to be a memory leak in the NSS code */
31.571 - mp_clear(&aa);
31.572 - mp_clear(&bb);
31.573 - mp_clear(&uu);
31.574 - return res;
31.575 -
31.576 -}
31.577 -
31.578 -/* Convert the bit-string representation of a polynomial a into an array
31.579 - * of integers corresponding to the bits with non-zero coefficient.
31.580 - * Up to max elements of the array will be filled. Return value is total
31.581 - * number of coefficients that would be extracted if array was large enough.
31.582 - */
31.583 -int
31.584 -mp_bpoly2arr(const mp_int *a, unsigned int p[], int max)
31.585 -{
31.586 - int i, j, k;
31.587 - mp_digit top_bit, mask;
31.588 -
31.589 - top_bit = 1;
31.590 - top_bit <<= MP_DIGIT_BIT - 1;
31.591 -
31.592 - for (k = 0; k < max; k++) p[k] = 0;
31.593 - k = 0;
31.594 -
31.595 - for (i = MP_USED(a) - 1; i >= 0; i--) {
31.596 - mask = top_bit;
31.597 - for (j = MP_DIGIT_BIT - 1; j >= 0; j--) {
31.598 - if (MP_DIGITS(a)[i] & mask) {
31.599 - if (k < max) p[k] = MP_DIGIT_BIT * i + j;
31.600 - k++;
31.601 - }
31.602 - mask >>= 1;
31.603 - }
31.604 - }
31.605 -
31.606 - return k;
31.607 -}
31.608 -
31.609 -/* Convert the coefficient array representation of a polynomial to a
31.610 - * bit-string. The array must be terminated by 0.
31.611 - */
31.612 -mp_err
31.613 -mp_barr2poly(const unsigned int p[], mp_int *a)
31.614 -{
31.615 -
31.616 - mp_err res = MP_OKAY;
31.617 - int i;
31.618 -
31.619 - mp_zero(a);
31.620 - for (i = 0; p[i] > 0; i++) {
31.621 - MP_CHECKOK( mpl_set_bit(a, p[i], 1) );
31.622 - }
31.623 - MP_CHECKOK( mpl_set_bit(a, 0, 1) );
31.624 -
31.625 -CLEANUP:
31.626 - return res;
31.627 -}
32.1 --- a/src/share/native/sun/security/ec/mp_gf2m.h Tue Oct 13 15:25:58 2009 -0700
32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
32.3 @@ -1,83 +0,0 @@
32.4 -/* *********************************************************************
32.5 - *
32.6 - * Sun elects to have this file available under and governed by the
32.7 - * Mozilla Public License Version 1.1 ("MPL") (see
32.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
32.9 - * of doubt and subject to the following, Sun also elects to allow
32.10 - * licensees to use this file under the MPL, the GNU General Public
32.11 - * License version 2 only or the Lesser General Public License version
32.12 - * 2.1 only. Any references to the "GNU General Public License version 2
32.13 - * or later" or "GPL" in the following shall be construed to mean the
32.14 - * GNU General Public License version 2 only. Any references to the "GNU
32.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
32.16 - * following shall be construed to mean the GNU Lesser General Public
32.17 - * License version 2.1 only. However, the following notice accompanied
32.18 - * the original version of this file:
32.19 - *
32.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
32.21 - *
32.22 - * The contents of this file are subject to the Mozilla Public License Version
32.23 - * 1.1 (the "License"); you may not use this file except in compliance with
32.24 - * the License. You may obtain a copy of the License at
32.25 - * http://www.mozilla.org/MPL/
32.26 - *
32.27 - * Software distributed under the License is distributed on an "AS IS" basis,
32.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
32.29 - * for the specific language governing rights and limitations under the
32.30 - * License.
32.31 - *
32.32 - * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
32.33 - *
32.34 - * The Initial Developer of the Original Code is
32.35 - * Sun Microsystems, Inc.
32.36 - * Portions created by the Initial Developer are Copyright (C) 2003
32.37 - * the Initial Developer. All Rights Reserved.
32.38 - *
32.39 - * Contributor(s):
32.40 - * Sheueling Chang Shantz <sheueling.chang@sun.com> and
32.41 - * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
32.42 - *
32.43 - * Alternatively, the contents of this file may be used under the terms of
32.44 - * either the GNU General Public License Version 2 or later (the "GPL"), or
32.45 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32.46 - * in which case the provisions of the GPL or the LGPL are applicable instead
32.47 - * of those above. If you wish to allow use of your version of this file only
32.48 - * under the terms of either the GPL or the LGPL, and not to allow others to
32.49 - * use your version of this file under the terms of the MPL, indicate your
32.50 - * decision by deleting the provisions above and replace them with the notice
32.51 - * and other provisions required by the GPL or the LGPL. If you do not delete
32.52 - * the provisions above, a recipient may use your version of this file under
32.53 - * the terms of any one of the MPL, the GPL or the LGPL.
32.54 - *
32.55 - *********************************************************************** */
32.56 -/*
32.57 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
32.58 - * Use is subject to license terms.
32.59 - */
32.60 -
32.61 -#ifndef _MP_GF2M_H_
32.62 -#define _MP_GF2M_H_
32.63 -
32.64 -#pragma ident "%Z%%M% %I% %E% SMI"
32.65 -
32.66 -#include "mpi.h"
32.67 -
32.68 -mp_err mp_badd(const mp_int *a, const mp_int *b, mp_int *c);
32.69 -mp_err mp_bmul(const mp_int *a, const mp_int *b, mp_int *c);
32.70 -
32.71 -/* For modular arithmetic, the irreducible polynomial f(t) is represented
32.72 - * as an array of int[], where f(t) is of the form:
32.73 - * f(t) = t^p[0] + t^p[1] + ... + t^p[k]
32.74 - * where m = p[0] > p[1] > ... > p[k] = 0.
32.75 - */
32.76 -mp_err mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r);
32.77 -mp_err mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[],
32.78 - mp_int *r);
32.79 -mp_err mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r);
32.80 -mp_err mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
32.81 - const unsigned int p[], mp_int *r);
32.82 -
32.83 -int mp_bpoly2arr(const mp_int *a, unsigned int p[], int max);
32.84 -mp_err mp_barr2poly(const unsigned int p[], mp_int *a);
32.85 -
32.86 -#endif /* _MP_GF2M_H_ */
33.1 --- a/src/share/native/sun/security/ec/mpi-config.h Tue Oct 13 15:25:58 2009 -0700
33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
33.3 @@ -1,130 +0,0 @@
33.4 -/* *********************************************************************
33.5 - *
33.6 - * Sun elects to have this file available under and governed by the
33.7 - * Mozilla Public License Version 1.1 ("MPL") (see
33.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
33.9 - * of doubt and subject to the following, Sun also elects to allow
33.10 - * licensees to use this file under the MPL, the GNU General Public
33.11 - * License version 2 only or the Lesser General Public License version
33.12 - * 2.1 only. Any references to the "GNU General Public License version 2
33.13 - * or later" or "GPL" in the following shall be construed to mean the
33.14 - * GNU General Public License version 2 only. Any references to the "GNU
33.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
33.16 - * following shall be construed to mean the GNU Lesser General Public
33.17 - * License version 2.1 only. However, the following notice accompanied
33.18 - * the original version of this file:
33.19 - *
33.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
33.21 - *
33.22 - * The contents of this file are subject to the Mozilla Public License Version
33.23 - * 1.1 (the "License"); you may not use this file except in compliance with
33.24 - * the License. You may obtain a copy of the License at
33.25 - * http://www.mozilla.org/MPL/
33.26 - *
33.27 - * Software distributed under the License is distributed on an "AS IS" basis,
33.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
33.29 - * for the specific language governing rights and limitations under the
33.30 - * License.
33.31 - *
33.32 - * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
33.33 - *
33.34 - * The Initial Developer of the Original Code is
33.35 - * Michael J. Fromberger.
33.36 - * Portions created by the Initial Developer are Copyright (C) 1997
33.37 - * the Initial Developer. All Rights Reserved.
33.38 - *
33.39 - * Contributor(s):
33.40 - * Netscape Communications Corporation
33.41 - *
33.42 - * Alternatively, the contents of this file may be used under the terms of
33.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
33.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
33.46 - * of those above. If you wish to allow use of your version of this file only
33.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
33.48 - * use your version of this file under the terms of the MPL, indicate your
33.49 - * decision by deleting the provisions above and replace them with the notice
33.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
33.51 - * the provisions above, a recipient may use your version of this file under
33.52 - * the terms of any one of the MPL, the GPL or the LGPL.
33.53 - *
33.54 - *********************************************************************** */
33.55 -/*
33.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
33.57 - * Use is subject to license terms.
33.58 - */
33.59 -
33.60 -#ifndef _MPI_CONFIG_H
33.61 -#define _MPI_CONFIG_H
33.62 -
33.63 -#pragma ident "%Z%%M% %I% %E% SMI"
33.64 -
33.65 -/* $Id: mpi-config.h,v 1.5 2004/04/25 15:03:10 gerv%gerv.net Exp $ */
33.66 -
33.67 -/*
33.68 - For boolean options,
33.69 - 0 = no
33.70 - 1 = yes
33.71 -
33.72 - Other options are documented individually.
33.73 -
33.74 - */
33.75 -
33.76 -#ifndef MP_IOFUNC
33.77 -#define MP_IOFUNC 0 /* include mp_print() ? */
33.78 -#endif
33.79 -
33.80 -#ifndef MP_MODARITH
33.81 -#define MP_MODARITH 1 /* include modular arithmetic ? */
33.82 -#endif
33.83 -
33.84 -#ifndef MP_NUMTH
33.85 -#define MP_NUMTH 1 /* include number theoretic functions? */
33.86 -#endif
33.87 -
33.88 -#ifndef MP_LOGTAB
33.89 -#define MP_LOGTAB 1 /* use table of logs instead of log()? */
33.90 -#endif
33.91 -
33.92 -#ifndef MP_MEMSET
33.93 -#define MP_MEMSET 1 /* use memset() to zero buffers? */
33.94 -#endif
33.95 -
33.96 -#ifndef MP_MEMCPY
33.97 -#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */
33.98 -#endif
33.99 -
33.100 -#ifndef MP_CRYPTO
33.101 -#define MP_CRYPTO 1 /* erase memory on free? */
33.102 -#endif
33.103 -
33.104 -#ifndef MP_ARGCHK
33.105 -/*
33.106 - 0 = no parameter checks
33.107 - 1 = runtime checks, continue execution and return an error to caller
33.108 - 2 = assertions; dump core on parameter errors
33.109 - */
33.110 -#ifdef DEBUG
33.111 -#define MP_ARGCHK 2 /* how to check input arguments */
33.112 -#else
33.113 -#define MP_ARGCHK 1 /* how to check input arguments */
33.114 -#endif
33.115 -#endif
33.116 -
33.117 -#ifndef MP_DEBUG
33.118 -#define MP_DEBUG 0 /* print diagnostic output? */
33.119 -#endif
33.120 -
33.121 -#ifndef MP_DEFPREC
33.122 -#define MP_DEFPREC 64 /* default precision, in digits */
33.123 -#endif
33.124 -
33.125 -#ifndef MP_MACRO
33.126 -#define MP_MACRO 0 /* use macros for frequent calls? */
33.127 -#endif
33.128 -
33.129 -#ifndef MP_SQUARE
33.130 -#define MP_SQUARE 1 /* use separate squaring code? */
33.131 -#endif
33.132 -
33.133 -#endif /* _MPI_CONFIG_H */
34.1 --- a/src/share/native/sun/security/ec/mpi-priv.h Tue Oct 13 15:25:58 2009 -0700
34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
34.3 @@ -1,340 +0,0 @@
34.4 -/* *********************************************************************
34.5 - *
34.6 - * Sun elects to have this file available under and governed by the
34.7 - * Mozilla Public License Version 1.1 ("MPL") (see
34.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
34.9 - * of doubt and subject to the following, Sun also elects to allow
34.10 - * licensees to use this file under the MPL, the GNU General Public
34.11 - * License version 2 only or the Lesser General Public License version
34.12 - * 2.1 only. Any references to the "GNU General Public License version 2
34.13 - * or later" or "GPL" in the following shall be construed to mean the
34.14 - * GNU General Public License version 2 only. Any references to the "GNU
34.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
34.16 - * following shall be construed to mean the GNU Lesser General Public
34.17 - * License version 2.1 only. However, the following notice accompanied
34.18 - * the original version of this file:
34.19 - *
34.20 - * Arbitrary precision integer arithmetic library
34.21 - *
34.22 - * NOTE WELL: the content of this header file is NOT part of the "public"
34.23 - * API for the MPI library, and may change at any time.
34.24 - * Application programs that use libmpi should NOT include this header file.
34.25 - *
34.26 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
34.27 - *
34.28 - * The contents of this file are subject to the Mozilla Public License Version
34.29 - * 1.1 (the "License"); you may not use this file except in compliance with
34.30 - * the License. You may obtain a copy of the License at
34.31 - * http://www.mozilla.org/MPL/
34.32 - *
34.33 - * Software distributed under the License is distributed on an "AS IS" basis,
34.34 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
34.35 - * for the specific language governing rights and limitations under the
34.36 - * License.
34.37 - *
34.38 - * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
34.39 - *
34.40 - * The Initial Developer of the Original Code is
34.41 - * Michael J. Fromberger.
34.42 - * Portions created by the Initial Developer are Copyright (C) 1998
34.43 - * the Initial Developer. All Rights Reserved.
34.44 - *
34.45 - * Contributor(s):
34.46 - * Netscape Communications Corporation
34.47 - *
34.48 - * Alternatively, the contents of this file may be used under the terms of
34.49 - * either the GNU General Public License Version 2 or later (the "GPL"), or
34.50 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34.51 - * in which case the provisions of the GPL or the LGPL are applicable instead
34.52 - * of those above. If you wish to allow use of your version of this file only
34.53 - * under the terms of either the GPL or the LGPL, and not to allow others to
34.54 - * use your version of this file under the terms of the MPL, indicate your
34.55 - * decision by deleting the provisions above and replace them with the notice
34.56 - * and other provisions required by the GPL or the LGPL. If you do not delete
34.57 - * the provisions above, a recipient may use your version of this file under
34.58 - * the terms of any one of the MPL, the GPL or the LGPL.
34.59 - *
34.60 - *********************************************************************** */
34.61 -/*
34.62 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
34.63 - * Use is subject to license terms.
34.64 - */
34.65 -
34.66 -#ifndef _MPI_PRIV_H
34.67 -#define _MPI_PRIV_H
34.68 -
34.69 -#pragma ident "%Z%%M% %I% %E% SMI"
34.70 -
34.71 -/* $Id: mpi-priv.h,v 1.20 2005/11/22 07:16:43 relyea%netscape.com Exp $ */
34.72 -
34.73 -#include "mpi.h"
34.74 -#ifndef _KERNEL
34.75 -#include <stdlib.h>
34.76 -#include <string.h>
34.77 -#include <ctype.h>
34.78 -#endif /* _KERNEL */
34.79 -
34.80 -#if MP_DEBUG
34.81 -#include <stdio.h>
34.82 -
34.83 -#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
34.84 -#else
34.85 -#define DIAG(T,V)
34.86 -#endif
34.87 -
34.88 -/* If we aren't using a wired-in logarithm table, we need to include
34.89 - the math library to get the log() function
34.90 - */
34.91 -
34.92 -/* {{{ s_logv_2[] - log table for 2 in various bases */
34.93 -
34.94 -#if MP_LOGTAB
34.95 -/*
34.96 - A table of the logs of 2 for various bases (the 0 and 1 entries of
34.97 - this table are meaningless and should not be referenced).
34.98 -
34.99 - This table is used to compute output lengths for the mp_toradix()
34.100 - function. Since a number n in radix r takes up about log_r(n)
34.101 - digits, we estimate the output size by taking the least integer
34.102 - greater than log_r(n), where:
34.103 -
34.104 - log_r(n) = log_2(n) * log_r(2)
34.105 -
34.106 - This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
34.107 - which are the output bases supported.
34.108 - */
34.109 -
34.110 -extern const float s_logv_2[];
34.111 -#define LOG_V_2(R) s_logv_2[(R)]
34.112 -
34.113 -#else
34.114 -
34.115 -/*
34.116 - If MP_LOGTAB is not defined, use the math library to compute the
34.117 - logarithms on the fly. Otherwise, use the table.
34.118 - Pick which works best for your system.
34.119 - */
34.120 -
34.121 -#include <math.h>
34.122 -#define LOG_V_2(R) (log(2.0)/log(R))
34.123 -
34.124 -#endif /* if MP_LOGTAB */
34.125 -
34.126 -/* }}} */
34.127 -
34.128 -/* {{{ Digit arithmetic macros */
34.129 -
34.130 -/*
34.131 - When adding and multiplying digits, the results can be larger than
34.132 - can be contained in an mp_digit. Thus, an mp_word is used. These
34.133 - macros mask off the upper and lower digits of the mp_word (the
34.134 - mp_word may be more than 2 mp_digits wide, but we only concern
34.135 - ourselves with the low-order 2 mp_digits)
34.136 - */
34.137 -
34.138 -#define CARRYOUT(W) (mp_digit)((W)>>DIGIT_BIT)
34.139 -#define ACCUM(W) (mp_digit)(W)
34.140 -
34.141 -#define MP_MIN(a,b) (((a) < (b)) ? (a) : (b))
34.142 -#define MP_MAX(a,b) (((a) > (b)) ? (a) : (b))
34.143 -#define MP_HOWMANY(a,b) (((a) + (b) - 1)/(b))
34.144 -#define MP_ROUNDUP(a,b) (MP_HOWMANY(a,b) * (b))
34.145 -
34.146 -/* }}} */
34.147 -
34.148 -/* {{{ Comparison constants */
34.149 -
34.150 -#define MP_LT -1
34.151 -#define MP_EQ 0
34.152 -#define MP_GT 1
34.153 -
34.154 -/* }}} */
34.155 -
34.156 -/* {{{ private function declarations */
34.157 -
34.158 -/*
34.159 - If MP_MACRO is false, these will be defined as actual functions;
34.160 - otherwise, suitable macro definitions will be used. This works
34.161 - around the fact that ANSI C89 doesn't support an 'inline' keyword
34.162 - (although I hear C9x will ... about bloody time). At present, the
34.163 - macro definitions are identical to the function bodies, but they'll
34.164 - expand in place, instead of generating a function call.
34.165 -
34.166 - I chose these particular functions to be made into macros because
34.167 - some profiling showed they are called a lot on a typical workload,
34.168 - and yet they are primarily housekeeping.
34.169 - */
34.170 -#if MP_MACRO == 0
34.171 - void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */
34.172 - void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count); /* copy */
34.173 - void *s_mp_alloc(size_t nb, size_t ni, int flag); /* general allocator */
34.174 - void s_mp_free(void *ptr, mp_size); /* general free function */
34.175 -extern unsigned long mp_allocs;
34.176 -extern unsigned long mp_frees;
34.177 -extern unsigned long mp_copies;
34.178 -#else
34.179 -
34.180 - /* Even if these are defined as macros, we need to respect the settings
34.181 - of the MP_MEMSET and MP_MEMCPY configuration options...
34.182 - */
34.183 - #if MP_MEMSET == 0
34.184 - #define s_mp_setz(dp, count) \
34.185 - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
34.186 - #else
34.187 - #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
34.188 - #endif /* MP_MEMSET */
34.189 -
34.190 - #if MP_MEMCPY == 0
34.191 - #define s_mp_copy(sp, dp, count) \
34.192 - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
34.193 - #else
34.194 - #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
34.195 - #endif /* MP_MEMCPY */
34.196 -
34.197 - #define s_mp_alloc(nb, ni) calloc(nb, ni)
34.198 - #define s_mp_free(ptr) {if(ptr) free(ptr);}
34.199 -#endif /* MP_MACRO */
34.200 -
34.201 -mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */
34.202 -mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */
34.203 -
34.204 -#if MP_MACRO == 0
34.205 - void s_mp_clamp(mp_int *mp); /* clip leading zeroes */
34.206 -#else
34.207 - #define s_mp_clamp(mp)\
34.208 - { mp_size used = MP_USED(mp); \
34.209 - while (used > 1 && DIGIT(mp, used - 1) == 0) --used; \
34.210 - MP_USED(mp) = used; \
34.211 - }
34.212 -#endif /* MP_MACRO */
34.213 -
34.214 -void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */
34.215 -
34.216 -mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */
34.217 -void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */
34.218 -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place */
34.219 -void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */
34.220 -void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */
34.221 -void s_mp_div_2(mp_int *mp); /* divide by 2 in place */
34.222 -mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */
34.223 -mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd);
34.224 - /* normalize for division */
34.225 -mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */
34.226 -mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */
34.227 -mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */
34.228 -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
34.229 - /* unsigned digit divide */
34.230 -mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
34.231 - /* Barrett reduction */
34.232 -mp_err s_mp_add(mp_int *a, const mp_int *b); /* magnitude addition */
34.233 -mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c);
34.234 -mp_err s_mp_sub(mp_int *a, const mp_int *b); /* magnitude subtract */
34.235 -mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c);
34.236 -mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset);
34.237 - /* a += b * RADIX^offset */
34.238 -mp_err s_mp_mul(mp_int *a, const mp_int *b); /* magnitude multiply */
34.239 -#if MP_SQUARE
34.240 -mp_err s_mp_sqr(mp_int *a); /* magnitude square */
34.241 -#else
34.242 -#define s_mp_sqr(a) s_mp_mul(a, a)
34.243 -#endif
34.244 -mp_err s_mp_div(mp_int *rem, mp_int *div, mp_int *quot); /* magnitude div */
34.245 -mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
34.246 -mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */
34.247 -int s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */
34.248 -int s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */
34.249 -int s_mp_ispow2(const mp_int *v); /* is v a power of 2? */
34.250 -int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */
34.251 -
34.252 -int s_mp_tovalue(char ch, int r); /* convert ch to value */
34.253 -char s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */
34.254 -int s_mp_outlen(int bits, int r); /* output length in bytes */
34.255 -mp_digit s_mp_invmod_radix(mp_digit P); /* returns (P ** -1) mod RADIX */
34.256 -mp_err s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c);
34.257 -mp_err s_mp_invmod_2d( const mp_int *a, mp_size k, mp_int *c);
34.258 -mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
34.259 -
34.260 -#ifdef NSS_USE_COMBA
34.261 -
34.262 -#define IS_POWER_OF_2(a) ((a) && !((a) & ((a)-1)))
34.263 -
34.264 -void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C);
34.265 -void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C);
34.266 -void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C);
34.267 -void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C);
34.268 -
34.269 -void s_mp_sqr_comba_4(const mp_int *A, mp_int *B);
34.270 -void s_mp_sqr_comba_8(const mp_int *A, mp_int *B);
34.271 -void s_mp_sqr_comba_16(const mp_int *A, mp_int *B);
34.272 -void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
34.273 -
34.274 -#endif /* end NSS_USE_COMBA */
34.275 -
34.276 -/* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */
34.277 -#if defined (__OS2__) && defined (__IBMC__)
34.278 -#define MPI_ASM_DECL __cdecl
34.279 -#else
34.280 -#define MPI_ASM_DECL
34.281 -#endif
34.282 -
34.283 -#ifdef MPI_AMD64
34.284 -
34.285 -mp_digit MPI_ASM_DECL s_mpv_mul_set_vec64(mp_digit*, mp_digit *, mp_size, mp_digit);
34.286 -mp_digit MPI_ASM_DECL s_mpv_mul_add_vec64(mp_digit*, const mp_digit*, mp_size, mp_digit);
34.287 -
34.288 -/* c = a * b */
34.289 -#define s_mpv_mul_d(a, a_len, b, c) \
34.290 - ((unsigned long*)c)[a_len] = s_mpv_mul_set_vec64(c, a, a_len, b)
34.291 -
34.292 -/* c += a * b */
34.293 -#define s_mpv_mul_d_add(a, a_len, b, c) \
34.294 - ((unsigned long*)c)[a_len] = s_mpv_mul_add_vec64(c, a, a_len, b)
34.295 -
34.296 -#else
34.297 -
34.298 -void MPI_ASM_DECL s_mpv_mul_d(const mp_digit *a, mp_size a_len,
34.299 - mp_digit b, mp_digit *c);
34.300 -void MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len,
34.301 - mp_digit b, mp_digit *c);
34.302 -
34.303 -#endif
34.304 -
34.305 -void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a,
34.306 - mp_size a_len, mp_digit b,
34.307 - mp_digit *c);
34.308 -void MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a,
34.309 - mp_size a_len,
34.310 - mp_digit *sqrs);
34.311 -
34.312 -mp_err MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo,
34.313 - mp_digit divisor, mp_digit *quot, mp_digit *rem);
34.314 -
34.315 -/* c += a * b * (MP_RADIX ** offset); */
34.316 -#define s_mp_mul_d_add_offset(a, b, c, off) \
34.317 -(s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off), MP_OKAY)
34.318 -
34.319 -typedef struct {
34.320 - mp_int N; /* modulus N */
34.321 - mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */
34.322 - mp_size b; /* R == 2 ** b, also b = # significant bits in N */
34.323 -} mp_mont_modulus;
34.324 -
34.325 -mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
34.326 - mp_mont_modulus *mmm);
34.327 -mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm);
34.328 -
34.329 -/*
34.330 - * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
34.331 - * if a cache exists, or zero if there is no cache. If more than one
34.332 - * cache line exists, it should return the smallest line size (which is
34.333 - * usually the L1 cache).
34.334 - *
34.335 - * mp_modexp uses this information to make sure that private key information
34.336 - * isn't being leaked through the cache.
34.337 - *
34.338 - * see mpcpucache.c for the implementation.
34.339 - */
34.340 -unsigned long s_mpi_getProcessorLineSize();
34.341 -
34.342 -/* }}} */
34.343 -#endif /* _MPI_PRIV_H */
35.1 --- a/src/share/native/sun/security/ec/mpi.c Tue Oct 13 15:25:58 2009 -0700
35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3 @@ -1,4886 +0,0 @@
35.4 -/* *********************************************************************
35.5 - *
35.6 - * Sun elects to have this file available under and governed by the
35.7 - * Mozilla Public License Version 1.1 ("MPL") (see
35.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
35.9 - * of doubt and subject to the following, Sun also elects to allow
35.10 - * licensees to use this file under the MPL, the GNU General Public
35.11 - * License version 2 only or the Lesser General Public License version
35.12 - * 2.1 only. Any references to the "GNU General Public License version 2
35.13 - * or later" or "GPL" in the following shall be construed to mean the
35.14 - * GNU General Public License version 2 only. Any references to the "GNU
35.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
35.16 - * following shall be construed to mean the GNU Lesser General Public
35.17 - * License version 2.1 only. However, the following notice accompanied
35.18 - * the original version of this file:
35.19 - *
35.20 - *
35.21 - * Arbitrary precision integer arithmetic library
35.22 - *
35.23 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
35.24 - *
35.25 - * The contents of this file are subject to the Mozilla Public License Version
35.26 - * 1.1 (the "License"); you may not use this file except in compliance with
35.27 - * the License. You may obtain a copy of the License at
35.28 - * http://www.mozilla.org/MPL/
35.29 - *
35.30 - * Software distributed under the License is distributed on an "AS IS" basis,
35.31 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
35.32 - * for the specific language governing rights and limitations under the
35.33 - * License.
35.34 - *
35.35 - * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
35.36 - *
35.37 - * The Initial Developer of the Original Code is
35.38 - * Michael J. Fromberger.
35.39 - * Portions created by the Initial Developer are Copyright (C) 1998
35.40 - * the Initial Developer. All Rights Reserved.
35.41 - *
35.42 - * Contributor(s):
35.43 - * Netscape Communications Corporation
35.44 - * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
35.45 - *
35.46 - * Alternatively, the contents of this file may be used under the terms of
35.47 - * either the GNU General Public License Version 2 or later (the "GPL"), or
35.48 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
35.49 - * in which case the provisions of the GPL or the LGPL are applicable instead
35.50 - * of those above. If you wish to allow use of your version of this file only
35.51 - * under the terms of either the GPL or the LGPL, and not to allow others to
35.52 - * use your version of this file under the terms of the MPL, indicate your
35.53 - * decision by deleting the provisions above and replace them with the notice
35.54 - * and other provisions required by the GPL or the LGPL. If you do not delete
35.55 - * the provisions above, a recipient may use your version of this file under
35.56 - * the terms of any one of the MPL, the GPL or the LGPL.
35.57 - *
35.58 - *********************************************************************** */
35.59 -/*
35.60 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
35.61 - * Use is subject to license terms.
35.62 - */
35.63 -
35.64 -#pragma ident "%Z%%M% %I% %E% SMI"
35.65 -
35.66 -/* $Id: mpi.c,v 1.45 2006/09/29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */
35.67 -
35.68 -#include "mpi-priv.h"
35.69 -#if defined(OSF1)
35.70 -#include <c_asm.h>
35.71 -#endif
35.72 -
35.73 -#if MP_LOGTAB
35.74 -/*
35.75 - A table of the logs of 2 for various bases (the 0 and 1 entries of
35.76 - this table are meaningless and should not be referenced).
35.77 -
35.78 - This table is used to compute output lengths for the mp_toradix()
35.79 - function. Since a number n in radix r takes up about log_r(n)
35.80 - digits, we estimate the output size by taking the least integer
35.81 - greater than log_r(n), where:
35.82 -
35.83 - log_r(n) = log_2(n) * log_r(2)
35.84 -
35.85 - This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
35.86 - which are the output bases supported.
35.87 - */
35.88 -#include "logtab.h"
35.89 -#endif
35.90 -
35.91 -/* {{{ Constant strings */
35.92 -
35.93 -/* Constant strings returned by mp_strerror() */
35.94 -static const char *mp_err_string[] = {
35.95 - "unknown result code", /* say what? */
35.96 - "boolean true", /* MP_OKAY, MP_YES */
35.97 - "boolean false", /* MP_NO */
35.98 - "out of memory", /* MP_MEM */
35.99 - "argument out of range", /* MP_RANGE */
35.100 - "invalid input parameter", /* MP_BADARG */
35.101 - "result is undefined" /* MP_UNDEF */
35.102 -};
35.103 -
35.104 -/* Value to digit maps for radix conversion */
35.105 -
35.106 -/* s_dmap_1 - standard digits and letters */
35.107 -static const char *s_dmap_1 =
35.108 - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
35.109 -
35.110 -/* }}} */
35.111 -
35.112 -unsigned long mp_allocs;
35.113 -unsigned long mp_frees;
35.114 -unsigned long mp_copies;
35.115 -
35.116 -/* {{{ Default precision manipulation */
35.117 -
35.118 -/* Default precision for newly created mp_int's */
35.119 -static mp_size s_mp_defprec = MP_DEFPREC;
35.120 -
35.121 -mp_size mp_get_prec(void)
35.122 -{
35.123 - return s_mp_defprec;
35.124 -
35.125 -} /* end mp_get_prec() */
35.126 -
35.127 -void mp_set_prec(mp_size prec)
35.128 -{
35.129 - if(prec == 0)
35.130 - s_mp_defprec = MP_DEFPREC;
35.131 - else
35.132 - s_mp_defprec = prec;
35.133 -
35.134 -} /* end mp_set_prec() */
35.135 -
35.136 -/* }}} */
35.137 -
35.138 -/*------------------------------------------------------------------------*/
35.139 -/* {{{ mp_init(mp, kmflag) */
35.140 -
35.141 -/*
35.142 - mp_init(mp, kmflag)
35.143 -
35.144 - Initialize a new zero-valued mp_int. Returns MP_OKAY if successful,
35.145 - MP_MEM if memory could not be allocated for the structure.
35.146 - */
35.147 -
35.148 -mp_err mp_init(mp_int *mp, int kmflag)
35.149 -{
35.150 - return mp_init_size(mp, s_mp_defprec, kmflag);
35.151 -
35.152 -} /* end mp_init() */
35.153 -
35.154 -/* }}} */
35.155 -
35.156 -/* {{{ mp_init_size(mp, prec, kmflag) */
35.157 -
35.158 -/*
35.159 - mp_init_size(mp, prec, kmflag)
35.160 -
35.161 - Initialize a new zero-valued mp_int with at least the given
35.162 - precision; returns MP_OKAY if successful, or MP_MEM if memory could
35.163 - not be allocated for the structure.
35.164 - */
35.165 -
35.166 -mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag)
35.167 -{
35.168 - ARGCHK(mp != NULL && prec > 0, MP_BADARG);
35.169 -
35.170 - prec = MP_ROUNDUP(prec, s_mp_defprec);
35.171 - if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit), kmflag)) == NULL)
35.172 - return MP_MEM;
35.173 -
35.174 - SIGN(mp) = ZPOS;
35.175 - USED(mp) = 1;
35.176 - ALLOC(mp) = prec;
35.177 -
35.178 - return MP_OKAY;
35.179 -
35.180 -} /* end mp_init_size() */
35.181 -
35.182 -/* }}} */
35.183 -
35.184 -/* {{{ mp_init_copy(mp, from) */
35.185 -
35.186 -/*
35.187 - mp_init_copy(mp, from)
35.188 -
35.189 - Initialize mp as an exact copy of from. Returns MP_OKAY if
35.190 - successful, MP_MEM if memory could not be allocated for the new
35.191 - structure.
35.192 - */
35.193 -
35.194 -mp_err mp_init_copy(mp_int *mp, const mp_int *from)
35.195 -{
35.196 - ARGCHK(mp != NULL && from != NULL, MP_BADARG);
35.197 -
35.198 - if(mp == from)
35.199 - return MP_OKAY;
35.200 -
35.201 - if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
35.202 - return MP_MEM;
35.203 -
35.204 - s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
35.205 - USED(mp) = USED(from);
35.206 - ALLOC(mp) = ALLOC(from);
35.207 - SIGN(mp) = SIGN(from);
35.208 -
35.209 -#ifndef _WIN32
35.210 - FLAG(mp) = FLAG(from);
35.211 -#endif /* _WIN32 */
35.212 -
35.213 - return MP_OKAY;
35.214 -
35.215 -} /* end mp_init_copy() */
35.216 -
35.217 -/* }}} */
35.218 -
35.219 -/* {{{ mp_copy(from, to) */
35.220 -
35.221 -/*
35.222 - mp_copy(from, to)
35.223 -
35.224 - Copies the mp_int 'from' to the mp_int 'to'. It is presumed that
35.225 - 'to' has already been initialized (if not, use mp_init_copy()
35.226 - instead). If 'from' and 'to' are identical, nothing happens.
35.227 - */
35.228 -
35.229 -mp_err mp_copy(const mp_int *from, mp_int *to)
35.230 -{
35.231 - ARGCHK(from != NULL && to != NULL, MP_BADARG);
35.232 -
35.233 - if(from == to)
35.234 - return MP_OKAY;
35.235 -
35.236 - ++mp_copies;
35.237 - { /* copy */
35.238 - mp_digit *tmp;
35.239 -
35.240 - /*
35.241 - If the allocated buffer in 'to' already has enough space to hold
35.242 - all the used digits of 'from', we'll re-use it to avoid hitting
35.243 - the memory allocater more than necessary; otherwise, we'd have
35.244 - to grow anyway, so we just allocate a hunk and make the copy as
35.245 - usual
35.246 - */
35.247 - if(ALLOC(to) >= USED(from)) {
35.248 - s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
35.249 - s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
35.250 -
35.251 - } else {
35.252 - if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
35.253 - return MP_MEM;
35.254 -
35.255 - s_mp_copy(DIGITS(from), tmp, USED(from));
35.256 -
35.257 - if(DIGITS(to) != NULL) {
35.258 -#if MP_CRYPTO
35.259 - s_mp_setz(DIGITS(to), ALLOC(to));
35.260 -#endif
35.261 - s_mp_free(DIGITS(to), ALLOC(to));
35.262 - }
35.263 -
35.264 - DIGITS(to) = tmp;
35.265 - ALLOC(to) = ALLOC(from);
35.266 - }
35.267 -
35.268 - /* Copy the precision and sign from the original */
35.269 - USED(to) = USED(from);
35.270 - SIGN(to) = SIGN(from);
35.271 - } /* end copy */
35.272 -
35.273 - return MP_OKAY;
35.274 -
35.275 -} /* end mp_copy() */
35.276 -
35.277 -/* }}} */
35.278 -
35.279 -/* {{{ mp_exch(mp1, mp2) */
35.280 -
35.281 -/*
35.282 - mp_exch(mp1, mp2)
35.283 -
35.284 - Exchange mp1 and mp2 without allocating any intermediate memory
35.285 - (well, unless you count the stack space needed for this call and the
35.286 - locals it creates...). This cannot fail.
35.287 - */
35.288 -
35.289 -void mp_exch(mp_int *mp1, mp_int *mp2)
35.290 -{
35.291 -#if MP_ARGCHK == 2
35.292 - assert(mp1 != NULL && mp2 != NULL);
35.293 -#else
35.294 - if(mp1 == NULL || mp2 == NULL)
35.295 - return;
35.296 -#endif
35.297 -
35.298 - s_mp_exch(mp1, mp2);
35.299 -
35.300 -} /* end mp_exch() */
35.301 -
35.302 -/* }}} */
35.303 -
35.304 -/* {{{ mp_clear(mp) */
35.305 -
35.306 -/*
35.307 - mp_clear(mp)
35.308 -
35.309 - Release the storage used by an mp_int, and void its fields so that
35.310 - if someone calls mp_clear() again for the same int later, we won't
35.311 - get tollchocked.
35.312 - */
35.313 -
35.314 -void mp_clear(mp_int *mp)
35.315 -{
35.316 - if(mp == NULL)
35.317 - return;
35.318 -
35.319 - if(DIGITS(mp) != NULL) {
35.320 -#if MP_CRYPTO
35.321 - s_mp_setz(DIGITS(mp), ALLOC(mp));
35.322 -#endif
35.323 - s_mp_free(DIGITS(mp), ALLOC(mp));
35.324 - DIGITS(mp) = NULL;
35.325 - }
35.326 -
35.327 - USED(mp) = 0;
35.328 - ALLOC(mp) = 0;
35.329 -
35.330 -} /* end mp_clear() */
35.331 -
35.332 -/* }}} */
35.333 -
35.334 -/* {{{ mp_zero(mp) */
35.335 -
35.336 -/*
35.337 - mp_zero(mp)
35.338 -
35.339 - Set mp to zero. Does not change the allocated size of the structure,
35.340 - and therefore cannot fail (except on a bad argument, which we ignore)
35.341 - */
35.342 -void mp_zero(mp_int *mp)
35.343 -{
35.344 - if(mp == NULL)
35.345 - return;
35.346 -
35.347 - s_mp_setz(DIGITS(mp), ALLOC(mp));
35.348 - USED(mp) = 1;
35.349 - SIGN(mp) = ZPOS;
35.350 -
35.351 -} /* end mp_zero() */
35.352 -
35.353 -/* }}} */
35.354 -
35.355 -/* {{{ mp_set(mp, d) */
35.356 -
35.357 -void mp_set(mp_int *mp, mp_digit d)
35.358 -{
35.359 - if(mp == NULL)
35.360 - return;
35.361 -
35.362 - mp_zero(mp);
35.363 - DIGIT(mp, 0) = d;
35.364 -
35.365 -} /* end mp_set() */
35.366 -
35.367 -/* }}} */
35.368 -
35.369 -/* {{{ mp_set_int(mp, z) */
35.370 -
35.371 -mp_err mp_set_int(mp_int *mp, long z)
35.372 -{
35.373 - int ix;
35.374 - unsigned long v = labs(z);
35.375 - mp_err res;
35.376 -
35.377 - ARGCHK(mp != NULL, MP_BADARG);
35.378 -
35.379 - mp_zero(mp);
35.380 - if(z == 0)
35.381 - return MP_OKAY; /* shortcut for zero */
35.382 -
35.383 - if (sizeof v <= sizeof(mp_digit)) {
35.384 - DIGIT(mp,0) = v;
35.385 - } else {
35.386 - for (ix = sizeof(long) - 1; ix >= 0; ix--) {
35.387 - if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
35.388 - return res;
35.389 -
35.390 - res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
35.391 - if (res != MP_OKAY)
35.392 - return res;
35.393 - }
35.394 - }
35.395 - if(z < 0)
35.396 - SIGN(mp) = NEG;
35.397 -
35.398 - return MP_OKAY;
35.399 -
35.400 -} /* end mp_set_int() */
35.401 -
35.402 -/* }}} */
35.403 -
35.404 -/* {{{ mp_set_ulong(mp, z) */
35.405 -
35.406 -mp_err mp_set_ulong(mp_int *mp, unsigned long z)
35.407 -{
35.408 - int ix;
35.409 - mp_err res;
35.410 -
35.411 - ARGCHK(mp != NULL, MP_BADARG);
35.412 -
35.413 - mp_zero(mp);
35.414 - if(z == 0)
35.415 - return MP_OKAY; /* shortcut for zero */
35.416 -
35.417 - if (sizeof z <= sizeof(mp_digit)) {
35.418 - DIGIT(mp,0) = z;
35.419 - } else {
35.420 - for (ix = sizeof(long) - 1; ix >= 0; ix--) {
35.421 - if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
35.422 - return res;
35.423 -
35.424 - res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));
35.425 - if (res != MP_OKAY)
35.426 - return res;
35.427 - }
35.428 - }
35.429 - return MP_OKAY;
35.430 -} /* end mp_set_ulong() */
35.431 -
35.432 -/* }}} */
35.433 -
35.434 -/*------------------------------------------------------------------------*/
35.435 -/* {{{ Digit arithmetic */
35.436 -
35.437 -/* {{{ mp_add_d(a, d, b) */
35.438 -
35.439 -/*
35.440 - mp_add_d(a, d, b)
35.441 -
35.442 - Compute the sum b = a + d, for a single digit d. Respects the sign of
35.443 - its primary addend (single digits are unsigned anyway).
35.444 - */
35.445 -
35.446 -mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
35.447 -{
35.448 - mp_int tmp;
35.449 - mp_err res;
35.450 -
35.451 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
35.452 -
35.453 - if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
35.454 - return res;
35.455 -
35.456 - if(SIGN(&tmp) == ZPOS) {
35.457 - if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
35.458 - goto CLEANUP;
35.459 - } else if(s_mp_cmp_d(&tmp, d) >= 0) {
35.460 - if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
35.461 - goto CLEANUP;
35.462 - } else {
35.463 - mp_neg(&tmp, &tmp);
35.464 -
35.465 - DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
35.466 - }
35.467 -
35.468 - if(s_mp_cmp_d(&tmp, 0) == 0)
35.469 - SIGN(&tmp) = ZPOS;
35.470 -
35.471 - s_mp_exch(&tmp, b);
35.472 -
35.473 -CLEANUP:
35.474 - mp_clear(&tmp);
35.475 - return res;
35.476 -
35.477 -} /* end mp_add_d() */
35.478 -
35.479 -/* }}} */
35.480 -
35.481 -/* {{{ mp_sub_d(a, d, b) */
35.482 -
35.483 -/*
35.484 - mp_sub_d(a, d, b)
35.485 -
35.486 - Compute the difference b = a - d, for a single digit d. Respects the
35.487 - sign of its subtrahend (single digits are unsigned anyway).
35.488 - */
35.489 -
35.490 -mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)
35.491 -{
35.492 - mp_int tmp;
35.493 - mp_err res;
35.494 -
35.495 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
35.496 -
35.497 - if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
35.498 - return res;
35.499 -
35.500 - if(SIGN(&tmp) == NEG) {
35.501 - if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
35.502 - goto CLEANUP;
35.503 - } else if(s_mp_cmp_d(&tmp, d) >= 0) {
35.504 - if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
35.505 - goto CLEANUP;
35.506 - } else {
35.507 - mp_neg(&tmp, &tmp);
35.508 -
35.509 - DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
35.510 - SIGN(&tmp) = NEG;
35.511 - }
35.512 -
35.513 - if(s_mp_cmp_d(&tmp, 0) == 0)
35.514 - SIGN(&tmp) = ZPOS;
35.515 -
35.516 - s_mp_exch(&tmp, b);
35.517 -
35.518 -CLEANUP:
35.519 - mp_clear(&tmp);
35.520 - return res;
35.521 -
35.522 -} /* end mp_sub_d() */
35.523 -
35.524 -/* }}} */
35.525 -
35.526 -/* {{{ mp_mul_d(a, d, b) */
35.527 -
35.528 -/*
35.529 - mp_mul_d(a, d, b)
35.530 -
35.531 - Compute the product b = a * d, for a single digit d. Respects the sign
35.532 - of its multiplicand (single digits are unsigned anyway)
35.533 - */
35.534 -
35.535 -mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
35.536 -{
35.537 - mp_err res;
35.538 -
35.539 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
35.540 -
35.541 - if(d == 0) {
35.542 - mp_zero(b);
35.543 - return MP_OKAY;
35.544 - }
35.545 -
35.546 - if((res = mp_copy(a, b)) != MP_OKAY)
35.547 - return res;
35.548 -
35.549 - res = s_mp_mul_d(b, d);
35.550 -
35.551 - return res;
35.552 -
35.553 -} /* end mp_mul_d() */
35.554 -
35.555 -/* }}} */
35.556 -
35.557 -/* {{{ mp_mul_2(a, c) */
35.558 -
35.559 -mp_err mp_mul_2(const mp_int *a, mp_int *c)
35.560 -{
35.561 - mp_err res;
35.562 -
35.563 - ARGCHK(a != NULL && c != NULL, MP_BADARG);
35.564 -
35.565 - if((res = mp_copy(a, c)) != MP_OKAY)
35.566 - return res;
35.567 -
35.568 - return s_mp_mul_2(c);
35.569 -
35.570 -} /* end mp_mul_2() */
35.571 -
35.572 -/* }}} */
35.573 -
35.574 -/* {{{ mp_div_d(a, d, q, r) */
35.575 -
35.576 -/*
35.577 - mp_div_d(a, d, q, r)
35.578 -
35.579 - Compute the quotient q = a / d and remainder r = a mod d, for a
35.580 - single digit d. Respects the sign of its divisor (single digits are
35.581 - unsigned anyway).
35.582 - */
35.583 -
35.584 -mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
35.585 -{
35.586 - mp_err res;
35.587 - mp_int qp;
35.588 - mp_digit rem;
35.589 - int pow;
35.590 -
35.591 - ARGCHK(a != NULL, MP_BADARG);
35.592 -
35.593 - if(d == 0)
35.594 - return MP_RANGE;
35.595 -
35.596 - /* Shortcut for powers of two ... */
35.597 - if((pow = s_mp_ispow2d(d)) >= 0) {
35.598 - mp_digit mask;
35.599 -
35.600 - mask = ((mp_digit)1 << pow) - 1;
35.601 - rem = DIGIT(a, 0) & mask;
35.602 -
35.603 - if(q) {
35.604 - mp_copy(a, q);
35.605 - s_mp_div_2d(q, pow);
35.606 - }
35.607 -
35.608 - if(r)
35.609 - *r = rem;
35.610 -
35.611 - return MP_OKAY;
35.612 - }
35.613 -
35.614 - if((res = mp_init_copy(&qp, a)) != MP_OKAY)
35.615 - return res;
35.616 -
35.617 - res = s_mp_div_d(&qp, d, &rem);
35.618 -
35.619 - if(s_mp_cmp_d(&qp, 0) == 0)
35.620 - SIGN(q) = ZPOS;
35.621 -
35.622 - if(r)
35.623 - *r = rem;
35.624 -
35.625 - if(q)
35.626 - s_mp_exch(&qp, q);
35.627 -
35.628 - mp_clear(&qp);
35.629 - return res;
35.630 -
35.631 -} /* end mp_div_d() */
35.632 -
35.633 -/* }}} */
35.634 -
35.635 -/* {{{ mp_div_2(a, c) */
35.636 -
35.637 -/*
35.638 - mp_div_2(a, c)
35.639 -
35.640 - Compute c = a / 2, disregarding the remainder.
35.641 - */
35.642 -
35.643 -mp_err mp_div_2(const mp_int *a, mp_int *c)
35.644 -{
35.645 - mp_err res;
35.646 -
35.647 - ARGCHK(a != NULL && c != NULL, MP_BADARG);
35.648 -
35.649 - if((res = mp_copy(a, c)) != MP_OKAY)
35.650 - return res;
35.651 -
35.652 - s_mp_div_2(c);
35.653 -
35.654 - return MP_OKAY;
35.655 -
35.656 -} /* end mp_div_2() */
35.657 -
35.658 -/* }}} */
35.659 -
35.660 -/* {{{ mp_expt_d(a, d, b) */
35.661 -
35.662 -mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
35.663 -{
35.664 - mp_int s, x;
35.665 - mp_err res;
35.666 -
35.667 - ARGCHK(a != NULL && c != NULL, MP_BADARG);
35.668 -
35.669 - if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
35.670 - return res;
35.671 - if((res = mp_init_copy(&x, a)) != MP_OKAY)
35.672 - goto X;
35.673 -
35.674 - DIGIT(&s, 0) = 1;
35.675 -
35.676 - while(d != 0) {
35.677 - if(d & 1) {
35.678 - if((res = s_mp_mul(&s, &x)) != MP_OKAY)
35.679 - goto CLEANUP;
35.680 - }
35.681 -
35.682 - d /= 2;
35.683 -
35.684 - if((res = s_mp_sqr(&x)) != MP_OKAY)
35.685 - goto CLEANUP;
35.686 - }
35.687 -
35.688 - s_mp_exch(&s, c);
35.689 -
35.690 -CLEANUP:
35.691 - mp_clear(&x);
35.692 -X:
35.693 - mp_clear(&s);
35.694 -
35.695 - return res;
35.696 -
35.697 -} /* end mp_expt_d() */
35.698 -
35.699 -/* }}} */
35.700 -
35.701 -/* }}} */
35.702 -
35.703 -/*------------------------------------------------------------------------*/
35.704 -/* {{{ Full arithmetic */
35.705 -
35.706 -/* {{{ mp_abs(a, b) */
35.707 -
35.708 -/*
35.709 - mp_abs(a, b)
35.710 -
35.711 - Compute b = |a|. 'a' and 'b' may be identical.
35.712 - */
35.713 -
35.714 -mp_err mp_abs(const mp_int *a, mp_int *b)
35.715 -{
35.716 - mp_err res;
35.717 -
35.718 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
35.719 -
35.720 - if((res = mp_copy(a, b)) != MP_OKAY)
35.721 - return res;
35.722 -
35.723 - SIGN(b) = ZPOS;
35.724 -
35.725 - return MP_OKAY;
35.726 -
35.727 -} /* end mp_abs() */
35.728 -
35.729 -/* }}} */
35.730 -
35.731 -/* {{{ mp_neg(a, b) */
35.732 -
35.733 -/*
35.734 - mp_neg(a, b)
35.735 -
35.736 - Compute b = -a. 'a' and 'b' may be identical.
35.737 - */
35.738 -
35.739 -mp_err mp_neg(const mp_int *a, mp_int *b)
35.740 -{
35.741 - mp_err res;
35.742 -
35.743 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
35.744 -
35.745 - if((res = mp_copy(a, b)) != MP_OKAY)
35.746 - return res;
35.747 -
35.748 - if(s_mp_cmp_d(b, 0) == MP_EQ)
35.749 - SIGN(b) = ZPOS;
35.750 - else
35.751 - SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
35.752 -
35.753 - return MP_OKAY;
35.754 -
35.755 -} /* end mp_neg() */
35.756 -
35.757 -/* }}} */
35.758 -
35.759 -/* {{{ mp_add(a, b, c) */
35.760 -
35.761 -/*
35.762 - mp_add(a, b, c)
35.763 -
35.764 - Compute c = a + b. All parameters may be identical.
35.765 - */
35.766 -
35.767 -mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
35.768 -{
35.769 - mp_err res;
35.770 -
35.771 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
35.772 -
35.773 - if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */
35.774 - MP_CHECKOK( s_mp_add_3arg(a, b, c) );
35.775 - } else if(s_mp_cmp(a, b) >= 0) { /* different sign: |a| >= |b| */
35.776 - MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
35.777 - } else { /* different sign: |a| < |b| */
35.778 - MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
35.779 - }
35.780 -
35.781 - if (s_mp_cmp_d(c, 0) == MP_EQ)
35.782 - SIGN(c) = ZPOS;
35.783 -
35.784 -CLEANUP:
35.785 - return res;
35.786 -
35.787 -} /* end mp_add() */
35.788 -
35.789 -/* }}} */
35.790 -
35.791 -/* {{{ mp_sub(a, b, c) */
35.792 -
35.793 -/*
35.794 - mp_sub(a, b, c)
35.795 -
35.796 - Compute c = a - b. All parameters may be identical.
35.797 - */
35.798 -
35.799 -mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
35.800 -{
35.801 - mp_err res;
35.802 - int magDiff;
35.803 -
35.804 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
35.805 -
35.806 - if (a == b) {
35.807 - mp_zero(c);
35.808 - return MP_OKAY;
35.809 - }
35.810 -
35.811 - if (MP_SIGN(a) != MP_SIGN(b)) {
35.812 - MP_CHECKOK( s_mp_add_3arg(a, b, c) );
35.813 - } else if (!(magDiff = s_mp_cmp(a, b))) {
35.814 - mp_zero(c);
35.815 - res = MP_OKAY;
35.816 - } else if (magDiff > 0) {
35.817 - MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
35.818 - } else {
35.819 - MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
35.820 - MP_SIGN(c) = !MP_SIGN(a);
35.821 - }
35.822 -
35.823 - if (s_mp_cmp_d(c, 0) == MP_EQ)
35.824 - MP_SIGN(c) = MP_ZPOS;
35.825 -
35.826 -CLEANUP:
35.827 - return res;
35.828 -
35.829 -} /* end mp_sub() */
35.830 -
35.831 -/* }}} */
35.832 -
35.833 -/* {{{ mp_mul(a, b, c) */
35.834 -
35.835 -/*
35.836 - mp_mul(a, b, c)
35.837 -
35.838 - Compute c = a * b. All parameters may be identical.
35.839 - */
35.840 -mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
35.841 -{
35.842 - mp_digit *pb;
35.843 - mp_int tmp;
35.844 - mp_err res;
35.845 - mp_size ib;
35.846 - mp_size useda, usedb;
35.847 -
35.848 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
35.849 -
35.850 - if (a == c) {
35.851 - if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)
35.852 - return res;
35.853 - if (a == b)
35.854 - b = &tmp;
35.855 - a = &tmp;
35.856 - } else if (b == c) {
35.857 - if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)
35.858 - return res;
35.859 - b = &tmp;
35.860 - } else {
35.861 - MP_DIGITS(&tmp) = 0;
35.862 - }
35.863 -
35.864 - if (MP_USED(a) < MP_USED(b)) {
35.865 - const mp_int *xch = b; /* switch a and b, to do fewer outer loops */
35.866 - b = a;
35.867 - a = xch;
35.868 - }
35.869 -
35.870 - MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
35.871 - if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
35.872 - goto CLEANUP;
35.873 -
35.874 -#ifdef NSS_USE_COMBA
35.875 - if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
35.876 - if (MP_USED(a) == 4) {
35.877 - s_mp_mul_comba_4(a, b, c);
35.878 - goto CLEANUP;
35.879 - }
35.880 - if (MP_USED(a) == 8) {
35.881 - s_mp_mul_comba_8(a, b, c);
35.882 - goto CLEANUP;
35.883 - }
35.884 - if (MP_USED(a) == 16) {
35.885 - s_mp_mul_comba_16(a, b, c);
35.886 - goto CLEANUP;
35.887 - }
35.888 - if (MP_USED(a) == 32) {
35.889 - s_mp_mul_comba_32(a, b, c);
35.890 - goto CLEANUP;
35.891 - }
35.892 - }
35.893 -#endif
35.894 -
35.895 - pb = MP_DIGITS(b);
35.896 - s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
35.897 -
35.898 - /* Outer loop: Digits of b */
35.899 - useda = MP_USED(a);
35.900 - usedb = MP_USED(b);
35.901 - for (ib = 1; ib < usedb; ib++) {
35.902 - mp_digit b_i = *pb++;
35.903 -
35.904 - /* Inner product: Digits of a */
35.905 - if (b_i)
35.906 - s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
35.907 - else
35.908 - MP_DIGIT(c, ib + useda) = b_i;
35.909 - }
35.910 -
35.911 - s_mp_clamp(c);
35.912 -
35.913 - if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
35.914 - SIGN(c) = ZPOS;
35.915 - else
35.916 - SIGN(c) = NEG;
35.917 -
35.918 -CLEANUP:
35.919 - mp_clear(&tmp);
35.920 - return res;
35.921 -} /* end mp_mul() */
35.922 -
35.923 -/* }}} */
35.924 -
35.925 -/* {{{ mp_sqr(a, sqr) */
35.926 -
35.927 -#if MP_SQUARE
35.928 -/*
35.929 - Computes the square of a. This can be done more
35.930 - efficiently than a general multiplication, because many of the
35.931 - computation steps are redundant when squaring. The inner product
35.932 - step is a bit more complicated, but we save a fair number of
35.933 - iterations of the multiplication loop.
35.934 - */
35.935 -
35.936 -/* sqr = a^2; Caller provides both a and tmp; */
35.937 -mp_err mp_sqr(const mp_int *a, mp_int *sqr)
35.938 -{
35.939 - mp_digit *pa;
35.940 - mp_digit d;
35.941 - mp_err res;
35.942 - mp_size ix;
35.943 - mp_int tmp;
35.944 - int count;
35.945 -
35.946 - ARGCHK(a != NULL && sqr != NULL, MP_BADARG);
35.947 -
35.948 - if (a == sqr) {
35.949 - if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
35.950 - return res;
35.951 - a = &tmp;
35.952 - } else {
35.953 - DIGITS(&tmp) = 0;
35.954 - res = MP_OKAY;
35.955 - }
35.956 -
35.957 - ix = 2 * MP_USED(a);
35.958 - if (ix > MP_ALLOC(sqr)) {
35.959 - MP_USED(sqr) = 1;
35.960 - MP_CHECKOK( s_mp_grow(sqr, ix) );
35.961 - }
35.962 - MP_USED(sqr) = ix;
35.963 - MP_DIGIT(sqr, 0) = 0;
35.964 -
35.965 -#ifdef NSS_USE_COMBA
35.966 - if (IS_POWER_OF_2(MP_USED(a))) {
35.967 - if (MP_USED(a) == 4) {
35.968 - s_mp_sqr_comba_4(a, sqr);
35.969 - goto CLEANUP;
35.970 - }
35.971 - if (MP_USED(a) == 8) {
35.972 - s_mp_sqr_comba_8(a, sqr);
35.973 - goto CLEANUP;
35.974 - }
35.975 - if (MP_USED(a) == 16) {
35.976 - s_mp_sqr_comba_16(a, sqr);
35.977 - goto CLEANUP;
35.978 - }
35.979 - if (MP_USED(a) == 32) {
35.980 - s_mp_sqr_comba_32(a, sqr);
35.981 - goto CLEANUP;
35.982 - }
35.983 - }
35.984 -#endif
35.985 -
35.986 - pa = MP_DIGITS(a);
35.987 - count = MP_USED(a) - 1;
35.988 - if (count > 0) {
35.989 - d = *pa++;
35.990 - s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);
35.991 - for (ix = 3; --count > 0; ix += 2) {
35.992 - d = *pa++;
35.993 - s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);
35.994 - } /* for(ix ...) */
35.995 - MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */
35.996 -
35.997 - /* now sqr *= 2 */
35.998 - s_mp_mul_2(sqr);
35.999 - } else {
35.1000 - MP_DIGIT(sqr, 1) = 0;
35.1001 - }
35.1002 -
35.1003 - /* now add the squares of the digits of a to sqr. */
35.1004 - s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));
35.1005 -
35.1006 - SIGN(sqr) = ZPOS;
35.1007 - s_mp_clamp(sqr);
35.1008 -
35.1009 -CLEANUP:
35.1010 - mp_clear(&tmp);
35.1011 - return res;
35.1012 -
35.1013 -} /* end mp_sqr() */
35.1014 -#endif
35.1015 -
35.1016 -/* }}} */
35.1017 -
35.1018 -/* {{{ mp_div(a, b, q, r) */
35.1019 -
35.1020 -/*
35.1021 - mp_div(a, b, q, r)
35.1022 -
35.1023 - Compute q = a / b and r = a mod b. Input parameters may be re-used
35.1024 - as output parameters. If q or r is NULL, that portion of the
35.1025 - computation will be discarded (although it will still be computed)
35.1026 - */
35.1027 -mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
35.1028 -{
35.1029 - mp_err res;
35.1030 - mp_int *pQ, *pR;
35.1031 - mp_int qtmp, rtmp, btmp;
35.1032 - int cmp;
35.1033 - mp_sign signA;
35.1034 - mp_sign signB;
35.1035 -
35.1036 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
35.1037 -
35.1038 - signA = MP_SIGN(a);
35.1039 - signB = MP_SIGN(b);
35.1040 -
35.1041 - if(mp_cmp_z(b) == MP_EQ)
35.1042 - return MP_RANGE;
35.1043 -
35.1044 - DIGITS(&qtmp) = 0;
35.1045 - DIGITS(&rtmp) = 0;
35.1046 - DIGITS(&btmp) = 0;
35.1047 -
35.1048 - /* Set up some temporaries... */
35.1049 - if (!r || r == a || r == b) {
35.1050 - MP_CHECKOK( mp_init_copy(&rtmp, a) );
35.1051 - pR = &rtmp;
35.1052 - } else {
35.1053 - MP_CHECKOK( mp_copy(a, r) );
35.1054 - pR = r;
35.1055 - }
35.1056 -
35.1057 - if (!q || q == a || q == b) {
35.1058 - MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a), FLAG(a)) );
35.1059 - pQ = &qtmp;
35.1060 - } else {
35.1061 - MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );
35.1062 - pQ = q;
35.1063 - mp_zero(pQ);
35.1064 - }
35.1065 -
35.1066 - /*
35.1067 - If |a| <= |b|, we can compute the solution without division;
35.1068 - otherwise, we actually do the work required.
35.1069 - */
35.1070 - if ((cmp = s_mp_cmp(a, b)) <= 0) {
35.1071 - if (cmp) {
35.1072 - /* r was set to a above. */
35.1073 - mp_zero(pQ);
35.1074 - } else {
35.1075 - mp_set(pQ, 1);
35.1076 - mp_zero(pR);
35.1077 - }
35.1078 - } else {
35.1079 - MP_CHECKOK( mp_init_copy(&btmp, b) );
35.1080 - MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );
35.1081 - }
35.1082 -
35.1083 - /* Compute the signs for the output */
35.1084 - MP_SIGN(pR) = signA; /* Sr = Sa */
35.1085 - /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */
35.1086 - MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;
35.1087 -
35.1088 - if(s_mp_cmp_d(pQ, 0) == MP_EQ)
35.1089 - SIGN(pQ) = ZPOS;
35.1090 - if(s_mp_cmp_d(pR, 0) == MP_EQ)
35.1091 - SIGN(pR) = ZPOS;
35.1092 -
35.1093 - /* Copy output, if it is needed */
35.1094 - if(q && q != pQ)
35.1095 - s_mp_exch(pQ, q);
35.1096 -
35.1097 - if(r && r != pR)
35.1098 - s_mp_exch(pR, r);
35.1099 -
35.1100 -CLEANUP:
35.1101 - mp_clear(&btmp);
35.1102 - mp_clear(&rtmp);
35.1103 - mp_clear(&qtmp);
35.1104 -
35.1105 - return res;
35.1106 -
35.1107 -} /* end mp_div() */
35.1108 -
35.1109 -/* }}} */
35.1110 -
35.1111 -/* {{{ mp_div_2d(a, d, q, r) */
35.1112 -
35.1113 -mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
35.1114 -{
35.1115 - mp_err res;
35.1116 -
35.1117 - ARGCHK(a != NULL, MP_BADARG);
35.1118 -
35.1119 - if(q) {
35.1120 - if((res = mp_copy(a, q)) != MP_OKAY)
35.1121 - return res;
35.1122 - }
35.1123 - if(r) {
35.1124 - if((res = mp_copy(a, r)) != MP_OKAY)
35.1125 - return res;
35.1126 - }
35.1127 - if(q) {
35.1128 - s_mp_div_2d(q, d);
35.1129 - }
35.1130 - if(r) {
35.1131 - s_mp_mod_2d(r, d);
35.1132 - }
35.1133 -
35.1134 - return MP_OKAY;
35.1135 -
35.1136 -} /* end mp_div_2d() */
35.1137 -
35.1138 -/* }}} */
35.1139 -
35.1140 -/* {{{ mp_expt(a, b, c) */
35.1141 -
35.1142 -/*
35.1143 - mp_expt(a, b, c)
35.1144 -
35.1145 - Compute c = a ** b, that is, raise a to the b power. Uses a
35.1146 - standard iterative square-and-multiply technique.
35.1147 - */
35.1148 -
35.1149 -mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
35.1150 -{
35.1151 - mp_int s, x;
35.1152 - mp_err res;
35.1153 - mp_digit d;
35.1154 - int dig, bit;
35.1155 -
35.1156 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
35.1157 -
35.1158 - if(mp_cmp_z(b) < 0)
35.1159 - return MP_RANGE;
35.1160 -
35.1161 - if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
35.1162 - return res;
35.1163 -
35.1164 - mp_set(&s, 1);
35.1165 -
35.1166 - if((res = mp_init_copy(&x, a)) != MP_OKAY)
35.1167 - goto X;
35.1168 -
35.1169 - /* Loop over low-order digits in ascending order */
35.1170 - for(dig = 0; dig < (USED(b) - 1); dig++) {
35.1171 - d = DIGIT(b, dig);
35.1172 -
35.1173 - /* Loop over bits of each non-maximal digit */
35.1174 - for(bit = 0; bit < DIGIT_BIT; bit++) {
35.1175 - if(d & 1) {
35.1176 - if((res = s_mp_mul(&s, &x)) != MP_OKAY)
35.1177 - goto CLEANUP;
35.1178 - }
35.1179 -
35.1180 - d >>= 1;
35.1181 -
35.1182 - if((res = s_mp_sqr(&x)) != MP_OKAY)
35.1183 - goto CLEANUP;
35.1184 - }
35.1185 - }
35.1186 -
35.1187 - /* Consider now the last digit... */
35.1188 - d = DIGIT(b, dig);
35.1189 -
35.1190 - while(d) {
35.1191 - if(d & 1) {
35.1192 - if((res = s_mp_mul(&s, &x)) != MP_OKAY)
35.1193 - goto CLEANUP;
35.1194 - }
35.1195 -
35.1196 - d >>= 1;
35.1197 -
35.1198 - if((res = s_mp_sqr(&x)) != MP_OKAY)
35.1199 - goto CLEANUP;
35.1200 - }
35.1201 -
35.1202 - if(mp_iseven(b))
35.1203 - SIGN(&s) = SIGN(a);
35.1204 -
35.1205 - res = mp_copy(&s, c);
35.1206 -
35.1207 -CLEANUP:
35.1208 - mp_clear(&x);
35.1209 -X:
35.1210 - mp_clear(&s);
35.1211 -
35.1212 - return res;
35.1213 -
35.1214 -} /* end mp_expt() */
35.1215 -
35.1216 -/* }}} */
35.1217 -
35.1218 -/* {{{ mp_2expt(a, k) */
35.1219 -
35.1220 -/* Compute a = 2^k */
35.1221 -
35.1222 -mp_err mp_2expt(mp_int *a, mp_digit k)
35.1223 -{
35.1224 - ARGCHK(a != NULL, MP_BADARG);
35.1225 -
35.1226 - return s_mp_2expt(a, k);
35.1227 -
35.1228 -} /* end mp_2expt() */
35.1229 -
35.1230 -/* }}} */
35.1231 -
35.1232 -/* {{{ mp_mod(a, m, c) */
35.1233 -
35.1234 -/*
35.1235 - mp_mod(a, m, c)
35.1236 -
35.1237 - Compute c = a (mod m). Result will always be 0 <= c < m.
35.1238 - */
35.1239 -
35.1240 -mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
35.1241 -{
35.1242 - mp_err res;
35.1243 - int mag;
35.1244 -
35.1245 - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
35.1246 -
35.1247 - if(SIGN(m) == NEG)
35.1248 - return MP_RANGE;
35.1249 -
35.1250 - /*
35.1251 - If |a| > m, we need to divide to get the remainder and take the
35.1252 - absolute value.
35.1253 -
35.1254 - If |a| < m, we don't need to do any division, just copy and adjust
35.1255 - the sign (if a is negative).
35.1256 -
35.1257 - If |a| == m, we can simply set the result to zero.
35.1258 -
35.1259 - This order is intended to minimize the average path length of the
35.1260 - comparison chain on common workloads -- the most frequent cases are
35.1261 - that |a| != m, so we do those first.
35.1262 - */
35.1263 - if((mag = s_mp_cmp(a, m)) > 0) {
35.1264 - if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
35.1265 - return res;
35.1266 -
35.1267 - if(SIGN(c) == NEG) {
35.1268 - if((res = mp_add(c, m, c)) != MP_OKAY)
35.1269 - return res;
35.1270 - }
35.1271 -
35.1272 - } else if(mag < 0) {
35.1273 - if((res = mp_copy(a, c)) != MP_OKAY)
35.1274 - return res;
35.1275 -
35.1276 - if(mp_cmp_z(a) < 0) {
35.1277 - if((res = mp_add(c, m, c)) != MP_OKAY)
35.1278 - return res;
35.1279 -
35.1280 - }
35.1281 -
35.1282 - } else {
35.1283 - mp_zero(c);
35.1284 -
35.1285 - }
35.1286 -
35.1287 - return MP_OKAY;
35.1288 -
35.1289 -} /* end mp_mod() */
35.1290 -
35.1291 -/* }}} */
35.1292 -
35.1293 -/* {{{ mp_mod_d(a, d, c) */
35.1294 -
35.1295 -/*
35.1296 - mp_mod_d(a, d, c)
35.1297 -
35.1298 - Compute c = a (mod d). Result will always be 0 <= c < d
35.1299 - */
35.1300 -mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
35.1301 -{
35.1302 - mp_err res;
35.1303 - mp_digit rem;
35.1304 -
35.1305 - ARGCHK(a != NULL && c != NULL, MP_BADARG);
35.1306 -
35.1307 - if(s_mp_cmp_d(a, d) > 0) {
35.1308 - if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
35.1309 - return res;
35.1310 -
35.1311 - } else {
35.1312 - if(SIGN(a) == NEG)
35.1313 - rem = d - DIGIT(a, 0);
35.1314 - else
35.1315 - rem = DIGIT(a, 0);
35.1316 - }
35.1317 -
35.1318 - if(c)
35.1319 - *c = rem;
35.1320 -
35.1321 - return MP_OKAY;
35.1322 -
35.1323 -} /* end mp_mod_d() */
35.1324 -
35.1325 -/* }}} */
35.1326 -
35.1327 -/* {{{ mp_sqrt(a, b) */
35.1328 -
35.1329 -/*
35.1330 - mp_sqrt(a, b)
35.1331 -
35.1332 - Compute the integer square root of a, and store the result in b.
35.1333 - Uses an integer-arithmetic version of Newton's iterative linear
35.1334 - approximation technique to determine this value; the result has the
35.1335 - following two properties:
35.1336 -
35.1337 - b^2 <= a
35.1338 - (b+1)^2 >= a
35.1339 -
35.1340 - It is a range error to pass a negative value.
35.1341 - */
35.1342 -mp_err mp_sqrt(const mp_int *a, mp_int *b)
35.1343 -{
35.1344 - mp_int x, t;
35.1345 - mp_err res;
35.1346 - mp_size used;
35.1347 -
35.1348 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
35.1349 -
35.1350 - /* Cannot take square root of a negative value */
35.1351 - if(SIGN(a) == NEG)
35.1352 - return MP_RANGE;
35.1353 -
35.1354 - /* Special cases for zero and one, trivial */
35.1355 - if(mp_cmp_d(a, 1) <= 0)
35.1356 - return mp_copy(a, b);
35.1357 -
35.1358 - /* Initialize the temporaries we'll use below */
35.1359 - if((res = mp_init_size(&t, USED(a), FLAG(a))) != MP_OKAY)
35.1360 - return res;
35.1361 -
35.1362 - /* Compute an initial guess for the iteration as a itself */
35.1363 - if((res = mp_init_copy(&x, a)) != MP_OKAY)
35.1364 - goto X;
35.1365 -
35.1366 - used = MP_USED(&x);
35.1367 - if (used > 1) {
35.1368 - s_mp_rshd(&x, used / 2);
35.1369 - }
35.1370 -
35.1371 - for(;;) {
35.1372 - /* t = (x * x) - a */
35.1373 - mp_copy(&x, &t); /* can't fail, t is big enough for original x */
35.1374 - if((res = mp_sqr(&t, &t)) != MP_OKAY ||
35.1375 - (res = mp_sub(&t, a, &t)) != MP_OKAY)
35.1376 - goto CLEANUP;
35.1377 -
35.1378 - /* t = t / 2x */
35.1379 - s_mp_mul_2(&x);
35.1380 - if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
35.1381 - goto CLEANUP;
35.1382 - s_mp_div_2(&x);
35.1383 -
35.1384 - /* Terminate the loop, if the quotient is zero */
35.1385 - if(mp_cmp_z(&t) == MP_EQ)
35.1386 - break;
35.1387 -
35.1388 - /* x = x - t */
35.1389 - if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
35.1390 - goto CLEANUP;
35.1391 -
35.1392 - }
35.1393 -
35.1394 - /* Copy result to output parameter */
35.1395 - mp_sub_d(&x, 1, &x);
35.1396 - s_mp_exch(&x, b);
35.1397 -
35.1398 - CLEANUP:
35.1399 - mp_clear(&x);
35.1400 - X:
35.1401 - mp_clear(&t);
35.1402 -
35.1403 - return res;
35.1404 -
35.1405 -} /* end mp_sqrt() */
35.1406 -
35.1407 -/* }}} */
35.1408 -
35.1409 -/* }}} */
35.1410 -
35.1411 -/*------------------------------------------------------------------------*/
35.1412 -/* {{{ Modular arithmetic */
35.1413 -
35.1414 -#if MP_MODARITH
35.1415 -/* {{{ mp_addmod(a, b, m, c) */
35.1416 -
35.1417 -/*
35.1418 - mp_addmod(a, b, m, c)
35.1419 -
35.1420 - Compute c = (a + b) mod m
35.1421 - */
35.1422 -
35.1423 -mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
35.1424 -{
35.1425 - mp_err res;
35.1426 -
35.1427 - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
35.1428 -
35.1429 - if((res = mp_add(a, b, c)) != MP_OKAY)
35.1430 - return res;
35.1431 - if((res = mp_mod(c, m, c)) != MP_OKAY)
35.1432 - return res;
35.1433 -
35.1434 - return MP_OKAY;
35.1435 -
35.1436 -}
35.1437 -
35.1438 -/* }}} */
35.1439 -
35.1440 -/* {{{ mp_submod(a, b, m, c) */
35.1441 -
35.1442 -/*
35.1443 - mp_submod(a, b, m, c)
35.1444 -
35.1445 - Compute c = (a - b) mod m
35.1446 - */
35.1447 -
35.1448 -mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
35.1449 -{
35.1450 - mp_err res;
35.1451 -
35.1452 - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
35.1453 -
35.1454 - if((res = mp_sub(a, b, c)) != MP_OKAY)
35.1455 - return res;
35.1456 - if((res = mp_mod(c, m, c)) != MP_OKAY)
35.1457 - return res;
35.1458 -
35.1459 - return MP_OKAY;
35.1460 -
35.1461 -}
35.1462 -
35.1463 -/* }}} */
35.1464 -
35.1465 -/* {{{ mp_mulmod(a, b, m, c) */
35.1466 -
35.1467 -/*
35.1468 - mp_mulmod(a, b, m, c)
35.1469 -
35.1470 - Compute c = (a * b) mod m
35.1471 - */
35.1472 -
35.1473 -mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
35.1474 -{
35.1475 - mp_err res;
35.1476 -
35.1477 - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
35.1478 -
35.1479 - if((res = mp_mul(a, b, c)) != MP_OKAY)
35.1480 - return res;
35.1481 - if((res = mp_mod(c, m, c)) != MP_OKAY)
35.1482 - return res;
35.1483 -
35.1484 - return MP_OKAY;
35.1485 -
35.1486 -}
35.1487 -
35.1488 -/* }}} */
35.1489 -
35.1490 -/* {{{ mp_sqrmod(a, m, c) */
35.1491 -
35.1492 -#if MP_SQUARE
35.1493 -mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
35.1494 -{
35.1495 - mp_err res;
35.1496 -
35.1497 - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
35.1498 -
35.1499 - if((res = mp_sqr(a, c)) != MP_OKAY)
35.1500 - return res;
35.1501 - if((res = mp_mod(c, m, c)) != MP_OKAY)
35.1502 - return res;
35.1503 -
35.1504 - return MP_OKAY;
35.1505 -
35.1506 -} /* end mp_sqrmod() */
35.1507 -#endif
35.1508 -
35.1509 -/* }}} */
35.1510 -
35.1511 -/* {{{ s_mp_exptmod(a, b, m, c) */
35.1512 -
35.1513 -/*
35.1514 - s_mp_exptmod(a, b, m, c)
35.1515 -
35.1516 - Compute c = (a ** b) mod m. Uses a standard square-and-multiply
35.1517 - method with modular reductions at each step. (This is basically the
35.1518 - same code as mp_expt(), except for the addition of the reductions)
35.1519 -
35.1520 - The modular reductions are done using Barrett's algorithm (see
35.1521 - s_mp_reduce() below for details)
35.1522 - */
35.1523 -
35.1524 -mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
35.1525 -{
35.1526 - mp_int s, x, mu;
35.1527 - mp_err res;
35.1528 - mp_digit d;
35.1529 - int dig, bit;
35.1530 -
35.1531 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
35.1532 -
35.1533 - if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
35.1534 - return MP_RANGE;
35.1535 -
35.1536 - if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
35.1537 - return res;
35.1538 - if((res = mp_init_copy(&x, a)) != MP_OKAY ||
35.1539 - (res = mp_mod(&x, m, &x)) != MP_OKAY)
35.1540 - goto X;
35.1541 - if((res = mp_init(&mu, FLAG(a))) != MP_OKAY)
35.1542 - goto MU;
35.1543 -
35.1544 - mp_set(&s, 1);
35.1545 -
35.1546 - /* mu = b^2k / m */
35.1547 - s_mp_add_d(&mu, 1);
35.1548 - s_mp_lshd(&mu, 2 * USED(m));
35.1549 - if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
35.1550 - goto CLEANUP;
35.1551 -
35.1552 - /* Loop over digits of b in ascending order, except highest order */
35.1553 - for(dig = 0; dig < (USED(b) - 1); dig++) {
35.1554 - d = DIGIT(b, dig);
35.1555 -
35.1556 - /* Loop over the bits of the lower-order digits */
35.1557 - for(bit = 0; bit < DIGIT_BIT; bit++) {
35.1558 - if(d & 1) {
35.1559 - if((res = s_mp_mul(&s, &x)) != MP_OKAY)
35.1560 - goto CLEANUP;
35.1561 - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
35.1562 - goto CLEANUP;
35.1563 - }
35.1564 -
35.1565 - d >>= 1;
35.1566 -
35.1567 - if((res = s_mp_sqr(&x)) != MP_OKAY)
35.1568 - goto CLEANUP;
35.1569 - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
35.1570 - goto CLEANUP;
35.1571 - }
35.1572 - }
35.1573 -
35.1574 - /* Now do the last digit... */
35.1575 - d = DIGIT(b, dig);
35.1576 -
35.1577 - while(d) {
35.1578 - if(d & 1) {
35.1579 - if((res = s_mp_mul(&s, &x)) != MP_OKAY)
35.1580 - goto CLEANUP;
35.1581 - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
35.1582 - goto CLEANUP;
35.1583 - }
35.1584 -
35.1585 - d >>= 1;
35.1586 -
35.1587 - if((res = s_mp_sqr(&x)) != MP_OKAY)
35.1588 - goto CLEANUP;
35.1589 - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
35.1590 - goto CLEANUP;
35.1591 - }
35.1592 -
35.1593 - s_mp_exch(&s, c);
35.1594 -
35.1595 - CLEANUP:
35.1596 - mp_clear(&mu);
35.1597 - MU:
35.1598 - mp_clear(&x);
35.1599 - X:
35.1600 - mp_clear(&s);
35.1601 -
35.1602 - return res;
35.1603 -
35.1604 -} /* end s_mp_exptmod() */
35.1605 -
35.1606 -/* }}} */
35.1607 -
35.1608 -/* {{{ mp_exptmod_d(a, d, m, c) */
35.1609 -
35.1610 -mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
35.1611 -{
35.1612 - mp_int s, x;
35.1613 - mp_err res;
35.1614 -
35.1615 - ARGCHK(a != NULL && c != NULL, MP_BADARG);
35.1616 -
35.1617 - if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
35.1618 - return res;
35.1619 - if((res = mp_init_copy(&x, a)) != MP_OKAY)
35.1620 - goto X;
35.1621 -
35.1622 - mp_set(&s, 1);
35.1623 -
35.1624 - while(d != 0) {
35.1625 - if(d & 1) {
35.1626 - if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
35.1627 - (res = mp_mod(&s, m, &s)) != MP_OKAY)
35.1628 - goto CLEANUP;
35.1629 - }
35.1630 -
35.1631 - d /= 2;
35.1632 -
35.1633 - if((res = s_mp_sqr(&x)) != MP_OKAY ||
35.1634 - (res = mp_mod(&x, m, &x)) != MP_OKAY)
35.1635 - goto CLEANUP;
35.1636 - }
35.1637 -
35.1638 - s_mp_exch(&s, c);
35.1639 -
35.1640 -CLEANUP:
35.1641 - mp_clear(&x);
35.1642 -X:
35.1643 - mp_clear(&s);
35.1644 -
35.1645 - return res;
35.1646 -
35.1647 -} /* end mp_exptmod_d() */
35.1648 -
35.1649 -/* }}} */
35.1650 -#endif /* if MP_MODARITH */
35.1651 -
35.1652 -/* }}} */
35.1653 -
35.1654 -/*------------------------------------------------------------------------*/
35.1655 -/* {{{ Comparison functions */
35.1656 -
35.1657 -/* {{{ mp_cmp_z(a) */
35.1658 -
35.1659 -/*
35.1660 - mp_cmp_z(a)
35.1661 -
35.1662 - Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0.
35.1663 - */
35.1664 -
35.1665 -int mp_cmp_z(const mp_int *a)
35.1666 -{
35.1667 - if(SIGN(a) == NEG)
35.1668 - return MP_LT;
35.1669 - else if(USED(a) == 1 && DIGIT(a, 0) == 0)
35.1670 - return MP_EQ;
35.1671 - else
35.1672 - return MP_GT;
35.1673 -
35.1674 -} /* end mp_cmp_z() */
35.1675 -
35.1676 -/* }}} */
35.1677 -
35.1678 -/* {{{ mp_cmp_d(a, d) */
35.1679 -
35.1680 -/*
35.1681 - mp_cmp_d(a, d)
35.1682 -
35.1683 - Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d
35.1684 - */
35.1685 -
35.1686 -int mp_cmp_d(const mp_int *a, mp_digit d)
35.1687 -{
35.1688 - ARGCHK(a != NULL, MP_EQ);
35.1689 -
35.1690 - if(SIGN(a) == NEG)
35.1691 - return MP_LT;
35.1692 -
35.1693 - return s_mp_cmp_d(a, d);
35.1694 -
35.1695 -} /* end mp_cmp_d() */
35.1696 -
35.1697 -/* }}} */
35.1698 -
35.1699 -/* {{{ mp_cmp(a, b) */
35.1700 -
35.1701 -int mp_cmp(const mp_int *a, const mp_int *b)
35.1702 -{
35.1703 - ARGCHK(a != NULL && b != NULL, MP_EQ);
35.1704 -
35.1705 - if(SIGN(a) == SIGN(b)) {
35.1706 - int mag;
35.1707 -
35.1708 - if((mag = s_mp_cmp(a, b)) == MP_EQ)
35.1709 - return MP_EQ;
35.1710 -
35.1711 - if(SIGN(a) == ZPOS)
35.1712 - return mag;
35.1713 - else
35.1714 - return -mag;
35.1715 -
35.1716 - } else if(SIGN(a) == ZPOS) {
35.1717 - return MP_GT;
35.1718 - } else {
35.1719 - return MP_LT;
35.1720 - }
35.1721 -
35.1722 -} /* end mp_cmp() */
35.1723 -
35.1724 -/* }}} */
35.1725 -
35.1726 -/* {{{ mp_cmp_mag(a, b) */
35.1727 -
35.1728 -/*
35.1729 - mp_cmp_mag(a, b)
35.1730 -
35.1731 - Compares |a| <=> |b|, and returns an appropriate comparison result
35.1732 - */
35.1733 -
35.1734 -int mp_cmp_mag(mp_int *a, mp_int *b)
35.1735 -{
35.1736 - ARGCHK(a != NULL && b != NULL, MP_EQ);
35.1737 -
35.1738 - return s_mp_cmp(a, b);
35.1739 -
35.1740 -} /* end mp_cmp_mag() */
35.1741 -
35.1742 -/* }}} */
35.1743 -
35.1744 -/* {{{ mp_cmp_int(a, z, kmflag) */
35.1745 -
35.1746 -/*
35.1747 - This just converts z to an mp_int, and uses the existing comparison
35.1748 - routines. This is sort of inefficient, but it's not clear to me how
35.1749 - frequently this wil get used anyway. For small positive constants,
35.1750 - you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
35.1751 - */
35.1752 -int mp_cmp_int(const mp_int *a, long z, int kmflag)
35.1753 -{
35.1754 - mp_int tmp;
35.1755 - int out;
35.1756 -
35.1757 - ARGCHK(a != NULL, MP_EQ);
35.1758 -
35.1759 - mp_init(&tmp, kmflag); mp_set_int(&tmp, z);
35.1760 - out = mp_cmp(a, &tmp);
35.1761 - mp_clear(&tmp);
35.1762 -
35.1763 - return out;
35.1764 -
35.1765 -} /* end mp_cmp_int() */
35.1766 -
35.1767 -/* }}} */
35.1768 -
35.1769 -/* {{{ mp_isodd(a) */
35.1770 -
35.1771 -/*
35.1772 - mp_isodd(a)
35.1773 -
35.1774 - Returns a true (non-zero) value if a is odd, false (zero) otherwise.
35.1775 - */
35.1776 -int mp_isodd(const mp_int *a)
35.1777 -{
35.1778 - ARGCHK(a != NULL, 0);
35.1779 -
35.1780 - return (int)(DIGIT(a, 0) & 1);
35.1781 -
35.1782 -} /* end mp_isodd() */
35.1783 -
35.1784 -/* }}} */
35.1785 -
35.1786 -/* {{{ mp_iseven(a) */
35.1787 -
35.1788 -int mp_iseven(const mp_int *a)
35.1789 -{
35.1790 - return !mp_isodd(a);
35.1791 -
35.1792 -} /* end mp_iseven() */
35.1793 -
35.1794 -/* }}} */
35.1795 -
35.1796 -/* }}} */
35.1797 -
35.1798 -/*------------------------------------------------------------------------*/
35.1799 -/* {{{ Number theoretic functions */
35.1800 -
35.1801 -#if MP_NUMTH
35.1802 -/* {{{ mp_gcd(a, b, c) */
35.1803 -
35.1804 -/*
35.1805 - Like the old mp_gcd() function, except computes the GCD using the
35.1806 - binary algorithm due to Josef Stein in 1961 (via Knuth).
35.1807 - */
35.1808 -mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
35.1809 -{
35.1810 - mp_err res;
35.1811 - mp_int u, v, t;
35.1812 - mp_size k = 0;
35.1813 -
35.1814 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
35.1815 -
35.1816 - if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
35.1817 - return MP_RANGE;
35.1818 - if(mp_cmp_z(a) == MP_EQ) {
35.1819 - return mp_copy(b, c);
35.1820 - } else if(mp_cmp_z(b) == MP_EQ) {
35.1821 - return mp_copy(a, c);
35.1822 - }
35.1823 -
35.1824 - if((res = mp_init(&t, FLAG(a))) != MP_OKAY)
35.1825 - return res;
35.1826 - if((res = mp_init_copy(&u, a)) != MP_OKAY)
35.1827 - goto U;
35.1828 - if((res = mp_init_copy(&v, b)) != MP_OKAY)
35.1829 - goto V;
35.1830 -
35.1831 - SIGN(&u) = ZPOS;
35.1832 - SIGN(&v) = ZPOS;
35.1833 -
35.1834 - /* Divide out common factors of 2 until at least 1 of a, b is even */
35.1835 - while(mp_iseven(&u) && mp_iseven(&v)) {
35.1836 - s_mp_div_2(&u);
35.1837 - s_mp_div_2(&v);
35.1838 - ++k;
35.1839 - }
35.1840 -
35.1841 - /* Initialize t */
35.1842 - if(mp_isodd(&u)) {
35.1843 - if((res = mp_copy(&v, &t)) != MP_OKAY)
35.1844 - goto CLEANUP;
35.1845 -
35.1846 - /* t = -v */
35.1847 - if(SIGN(&v) == ZPOS)
35.1848 - SIGN(&t) = NEG;
35.1849 - else
35.1850 - SIGN(&t) = ZPOS;
35.1851 -
35.1852 - } else {
35.1853 - if((res = mp_copy(&u, &t)) != MP_OKAY)
35.1854 - goto CLEANUP;
35.1855 -
35.1856 - }
35.1857 -
35.1858 - for(;;) {
35.1859 - while(mp_iseven(&t)) {
35.1860 - s_mp_div_2(&t);
35.1861 - }
35.1862 -
35.1863 - if(mp_cmp_z(&t) == MP_GT) {
35.1864 - if((res = mp_copy(&t, &u)) != MP_OKAY)
35.1865 - goto CLEANUP;
35.1866 -
35.1867 - } else {
35.1868 - if((res = mp_copy(&t, &v)) != MP_OKAY)
35.1869 - goto CLEANUP;
35.1870 -
35.1871 - /* v = -t */
35.1872 - if(SIGN(&t) == ZPOS)
35.1873 - SIGN(&v) = NEG;
35.1874 - else
35.1875 - SIGN(&v) = ZPOS;
35.1876 - }
35.1877 -
35.1878 - if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
35.1879 - goto CLEANUP;
35.1880 -
35.1881 - if(s_mp_cmp_d(&t, 0) == MP_EQ)
35.1882 - break;
35.1883 - }
35.1884 -
35.1885 - s_mp_2expt(&v, k); /* v = 2^k */
35.1886 - res = mp_mul(&u, &v, c); /* c = u * v */
35.1887 -
35.1888 - CLEANUP:
35.1889 - mp_clear(&v);
35.1890 - V:
35.1891 - mp_clear(&u);
35.1892 - U:
35.1893 - mp_clear(&t);
35.1894 -
35.1895 - return res;
35.1896 -
35.1897 -} /* end mp_gcd() */
35.1898 -
35.1899 -/* }}} */
35.1900 -
35.1901 -/* {{{ mp_lcm(a, b, c) */
35.1902 -
35.1903 -/* We compute the least common multiple using the rule:
35.1904 -
35.1905 - ab = [a, b](a, b)
35.1906 -
35.1907 - ... by computing the product, and dividing out the gcd.
35.1908 - */
35.1909 -
35.1910 -mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
35.1911 -{
35.1912 - mp_int gcd, prod;
35.1913 - mp_err res;
35.1914 -
35.1915 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
35.1916 -
35.1917 - /* Set up temporaries */
35.1918 - if((res = mp_init(&gcd, FLAG(a))) != MP_OKAY)
35.1919 - return res;
35.1920 - if((res = mp_init(&prod, FLAG(a))) != MP_OKAY)
35.1921 - goto GCD;
35.1922 -
35.1923 - if((res = mp_mul(a, b, &prod)) != MP_OKAY)
35.1924 - goto CLEANUP;
35.1925 - if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
35.1926 - goto CLEANUP;
35.1927 -
35.1928 - res = mp_div(&prod, &gcd, c, NULL);
35.1929 -
35.1930 - CLEANUP:
35.1931 - mp_clear(&prod);
35.1932 - GCD:
35.1933 - mp_clear(&gcd);
35.1934 -
35.1935 - return res;
35.1936 -
35.1937 -} /* end mp_lcm() */
35.1938 -
35.1939 -/* }}} */
35.1940 -
35.1941 -/* {{{ mp_xgcd(a, b, g, x, y) */
35.1942 -
35.1943 -/*
35.1944 - mp_xgcd(a, b, g, x, y)
35.1945 -
35.1946 - Compute g = (a, b) and values x and y satisfying Bezout's identity
35.1947 - (that is, ax + by = g). This uses the binary extended GCD algorithm
35.1948 - based on the Stein algorithm used for mp_gcd()
35.1949 - See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
35.1950 - */
35.1951 -
35.1952 -mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)
35.1953 -{
35.1954 - mp_int gx, xc, yc, u, v, A, B, C, D;
35.1955 - mp_int *clean[9];
35.1956 - mp_err res;
35.1957 - int last = -1;
35.1958 -
35.1959 - if(mp_cmp_z(b) == 0)
35.1960 - return MP_RANGE;
35.1961 -
35.1962 - /* Initialize all these variables we need */
35.1963 - MP_CHECKOK( mp_init(&u, FLAG(a)) );
35.1964 - clean[++last] = &u;
35.1965 - MP_CHECKOK( mp_init(&v, FLAG(a)) );
35.1966 - clean[++last] = &v;
35.1967 - MP_CHECKOK( mp_init(&gx, FLAG(a)) );
35.1968 - clean[++last] = &gx;
35.1969 - MP_CHECKOK( mp_init(&A, FLAG(a)) );
35.1970 - clean[++last] = &A;
35.1971 - MP_CHECKOK( mp_init(&B, FLAG(a)) );
35.1972 - clean[++last] = &B;
35.1973 - MP_CHECKOK( mp_init(&C, FLAG(a)) );
35.1974 - clean[++last] = &C;
35.1975 - MP_CHECKOK( mp_init(&D, FLAG(a)) );
35.1976 - clean[++last] = &D;
35.1977 - MP_CHECKOK( mp_init_copy(&xc, a) );
35.1978 - clean[++last] = &xc;
35.1979 - mp_abs(&xc, &xc);
35.1980 - MP_CHECKOK( mp_init_copy(&yc, b) );
35.1981 - clean[++last] = &yc;
35.1982 - mp_abs(&yc, &yc);
35.1983 -
35.1984 - mp_set(&gx, 1);
35.1985 -
35.1986 - /* Divide by two until at least one of them is odd */
35.1987 - while(mp_iseven(&xc) && mp_iseven(&yc)) {
35.1988 - mp_size nx = mp_trailing_zeros(&xc);
35.1989 - mp_size ny = mp_trailing_zeros(&yc);
35.1990 - mp_size n = MP_MIN(nx, ny);
35.1991 - s_mp_div_2d(&xc,n);
35.1992 - s_mp_div_2d(&yc,n);
35.1993 - MP_CHECKOK( s_mp_mul_2d(&gx,n) );
35.1994 - }
35.1995 -
35.1996 - mp_copy(&xc, &u);
35.1997 - mp_copy(&yc, &v);
35.1998 - mp_set(&A, 1); mp_set(&D, 1);
35.1999 -
35.2000 - /* Loop through binary GCD algorithm */
35.2001 - do {
35.2002 - while(mp_iseven(&u)) {
35.2003 - s_mp_div_2(&u);
35.2004 -
35.2005 - if(mp_iseven(&A) && mp_iseven(&B)) {
35.2006 - s_mp_div_2(&A); s_mp_div_2(&B);
35.2007 - } else {
35.2008 - MP_CHECKOK( mp_add(&A, &yc, &A) );
35.2009 - s_mp_div_2(&A);
35.2010 - MP_CHECKOK( mp_sub(&B, &xc, &B) );
35.2011 - s_mp_div_2(&B);
35.2012 - }
35.2013 - }
35.2014 -
35.2015 - while(mp_iseven(&v)) {
35.2016 - s_mp_div_2(&v);
35.2017 -
35.2018 - if(mp_iseven(&C) && mp_iseven(&D)) {
35.2019 - s_mp_div_2(&C); s_mp_div_2(&D);
35.2020 - } else {
35.2021 - MP_CHECKOK( mp_add(&C, &yc, &C) );
35.2022 - s_mp_div_2(&C);
35.2023 - MP_CHECKOK( mp_sub(&D, &xc, &D) );
35.2024 - s_mp_div_2(&D);
35.2025 - }
35.2026 - }
35.2027 -
35.2028 - if(mp_cmp(&u, &v) >= 0) {
35.2029 - MP_CHECKOK( mp_sub(&u, &v, &u) );
35.2030 - MP_CHECKOK( mp_sub(&A, &C, &A) );
35.2031 - MP_CHECKOK( mp_sub(&B, &D, &B) );
35.2032 - } else {
35.2033 - MP_CHECKOK( mp_sub(&v, &u, &v) );
35.2034 - MP_CHECKOK( mp_sub(&C, &A, &C) );
35.2035 - MP_CHECKOK( mp_sub(&D, &B, &D) );
35.2036 - }
35.2037 - } while (mp_cmp_z(&u) != 0);
35.2038 -
35.2039 - /* copy results to output */
35.2040 - if(x)
35.2041 - MP_CHECKOK( mp_copy(&C, x) );
35.2042 -
35.2043 - if(y)
35.2044 - MP_CHECKOK( mp_copy(&D, y) );
35.2045 -
35.2046 - if(g)
35.2047 - MP_CHECKOK( mp_mul(&gx, &v, g) );
35.2048 -
35.2049 - CLEANUP:
35.2050 - while(last >= 0)
35.2051 - mp_clear(clean[last--]);
35.2052 -
35.2053 - return res;
35.2054 -
35.2055 -} /* end mp_xgcd() */
35.2056 -
35.2057 -/* }}} */
35.2058 -
35.2059 -mp_size mp_trailing_zeros(const mp_int *mp)
35.2060 -{
35.2061 - mp_digit d;
35.2062 - mp_size n = 0;
35.2063 - int ix;
35.2064 -
35.2065 - if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
35.2066 - return n;
35.2067 -
35.2068 - for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
35.2069 - n += MP_DIGIT_BIT;
35.2070 - if (!d)
35.2071 - return 0; /* shouldn't happen, but ... */
35.2072 -#if !defined(MP_USE_UINT_DIGIT)
35.2073 - if (!(d & 0xffffffffU)) {
35.2074 - d >>= 32;
35.2075 - n += 32;
35.2076 - }
35.2077 -#endif
35.2078 - if (!(d & 0xffffU)) {
35.2079 - d >>= 16;
35.2080 - n += 16;
35.2081 - }
35.2082 - if (!(d & 0xffU)) {
35.2083 - d >>= 8;
35.2084 - n += 8;
35.2085 - }
35.2086 - if (!(d & 0xfU)) {
35.2087 - d >>= 4;
35.2088 - n += 4;
35.2089 - }
35.2090 - if (!(d & 0x3U)) {
35.2091 - d >>= 2;
35.2092 - n += 2;
35.2093 - }
35.2094 - if (!(d & 0x1U)) {
35.2095 - d >>= 1;
35.2096 - n += 1;
35.2097 - }
35.2098 -#if MP_ARGCHK == 2
35.2099 - assert(0 != (d & 1));
35.2100 -#endif
35.2101 - return n;
35.2102 -}
35.2103 -
35.2104 -/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
35.2105 -** Returns k (positive) or error (negative).
35.2106 -** This technique from the paper "Fast Modular Reciprocals" (unpublished)
35.2107 -** by Richard Schroeppel (a.k.a. Captain Nemo).
35.2108 -*/
35.2109 -mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
35.2110 -{
35.2111 - mp_err res;
35.2112 - mp_err k = 0;
35.2113 - mp_int d, f, g;
35.2114 -
35.2115 - ARGCHK(a && p && c, MP_BADARG);
35.2116 -
35.2117 - MP_DIGITS(&d) = 0;
35.2118 - MP_DIGITS(&f) = 0;
35.2119 - MP_DIGITS(&g) = 0;
35.2120 - MP_CHECKOK( mp_init(&d, FLAG(a)) );
35.2121 - MP_CHECKOK( mp_init_copy(&f, a) ); /* f = a */
35.2122 - MP_CHECKOK( mp_init_copy(&g, p) ); /* g = p */
35.2123 -
35.2124 - mp_set(c, 1);
35.2125 - mp_zero(&d);
35.2126 -
35.2127 - if (mp_cmp_z(&f) == 0) {
35.2128 - res = MP_UNDEF;
35.2129 - } else
35.2130 - for (;;) {
35.2131 - int diff_sign;
35.2132 - while (mp_iseven(&f)) {
35.2133 - mp_size n = mp_trailing_zeros(&f);
35.2134 - if (!n) {
35.2135 - res = MP_UNDEF;
35.2136 - goto CLEANUP;
35.2137 - }
35.2138 - s_mp_div_2d(&f, n);
35.2139 - MP_CHECKOK( s_mp_mul_2d(&d, n) );
35.2140 - k += n;
35.2141 - }
35.2142 - if (mp_cmp_d(&f, 1) == MP_EQ) { /* f == 1 */
35.2143 - res = k;
35.2144 - break;
35.2145 - }
35.2146 - diff_sign = mp_cmp(&f, &g);
35.2147 - if (diff_sign < 0) { /* f < g */
35.2148 - s_mp_exch(&f, &g);
35.2149 - s_mp_exch(c, &d);
35.2150 - } else if (diff_sign == 0) { /* f == g */
35.2151 - res = MP_UNDEF; /* a and p are not relatively prime */
35.2152 - break;
35.2153 - }
35.2154 - if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {
35.2155 - MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */
35.2156 - MP_CHECKOK( mp_sub(c, &d, c) ); /* c = c - d */
35.2157 - } else {
35.2158 - MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */
35.2159 - MP_CHECKOK( mp_add(c, &d, c) ); /* c = c + d */
35.2160 - }
35.2161 - }
35.2162 - if (res >= 0) {
35.2163 - while (MP_SIGN(c) != MP_ZPOS) {
35.2164 - MP_CHECKOK( mp_add(c, p, c) );
35.2165 - }
35.2166 - res = k;
35.2167 - }
35.2168 -
35.2169 -CLEANUP:
35.2170 - mp_clear(&d);
35.2171 - mp_clear(&f);
35.2172 - mp_clear(&g);
35.2173 - return res;
35.2174 -}
35.2175 -
35.2176 -/* Compute T = (P ** -1) mod MP_RADIX. Also works for 16-bit mp_digits.
35.2177 -** This technique from the paper "Fast Modular Reciprocals" (unpublished)
35.2178 -** by Richard Schroeppel (a.k.a. Captain Nemo).
35.2179 -*/
35.2180 -mp_digit s_mp_invmod_radix(mp_digit P)
35.2181 -{
35.2182 - mp_digit T = P;
35.2183 - T *= 2 - (P * T);
35.2184 - T *= 2 - (P * T);
35.2185 - T *= 2 - (P * T);
35.2186 - T *= 2 - (P * T);
35.2187 -#if !defined(MP_USE_UINT_DIGIT)
35.2188 - T *= 2 - (P * T);
35.2189 - T *= 2 - (P * T);
35.2190 -#endif
35.2191 - return T;
35.2192 -}
35.2193 -
35.2194 -/* Given c, k, and prime p, where a*c == 2**k (mod p),
35.2195 -** Compute x = (a ** -1) mod p. This is similar to Montgomery reduction.
35.2196 -** This technique from the paper "Fast Modular Reciprocals" (unpublished)
35.2197 -** by Richard Schroeppel (a.k.a. Captain Nemo).
35.2198 -*/
35.2199 -mp_err s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x)
35.2200 -{
35.2201 - int k_orig = k;
35.2202 - mp_digit r;
35.2203 - mp_size ix;
35.2204 - mp_err res;
35.2205 -
35.2206 - if (mp_cmp_z(c) < 0) { /* c < 0 */
35.2207 - MP_CHECKOK( mp_add(c, p, x) ); /* x = c + p */
35.2208 - } else {
35.2209 - MP_CHECKOK( mp_copy(c, x) ); /* x = c */
35.2210 - }
35.2211 -
35.2212 - /* make sure x is large enough */
35.2213 - ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;
35.2214 - ix = MP_MAX(ix, MP_USED(x));
35.2215 - MP_CHECKOK( s_mp_pad(x, ix) );
35.2216 -
35.2217 - r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));
35.2218 -
35.2219 - for (ix = 0; k > 0; ix++) {
35.2220 - int j = MP_MIN(k, MP_DIGIT_BIT);
35.2221 - mp_digit v = r * MP_DIGIT(x, ix);
35.2222 - if (j < MP_DIGIT_BIT) {
35.2223 - v &= ((mp_digit)1 << j) - 1; /* v = v mod (2 ** j) */
35.2224 - }
35.2225 - s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */
35.2226 - k -= j;
35.2227 - }
35.2228 - s_mp_clamp(x);
35.2229 - s_mp_div_2d(x, k_orig);
35.2230 - res = MP_OKAY;
35.2231 -
35.2232 -CLEANUP:
35.2233 - return res;
35.2234 -}
35.2235 -
35.2236 -/* compute mod inverse using Schroeppel's method, only if m is odd */
35.2237 -mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
35.2238 -{
35.2239 - int k;
35.2240 - mp_err res;
35.2241 - mp_int x;
35.2242 -
35.2243 - ARGCHK(a && m && c, MP_BADARG);
35.2244 -
35.2245 - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
35.2246 - return MP_RANGE;
35.2247 - if (mp_iseven(m))
35.2248 - return MP_UNDEF;
35.2249 -
35.2250 - MP_DIGITS(&x) = 0;
35.2251 -
35.2252 - if (a == c) {
35.2253 - if ((res = mp_init_copy(&x, a)) != MP_OKAY)
35.2254 - return res;
35.2255 - if (a == m)
35.2256 - m = &x;
35.2257 - a = &x;
35.2258 - } else if (m == c) {
35.2259 - if ((res = mp_init_copy(&x, m)) != MP_OKAY)
35.2260 - return res;
35.2261 - m = &x;
35.2262 - } else {
35.2263 - MP_DIGITS(&x) = 0;
35.2264 - }
35.2265 -
35.2266 - MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
35.2267 - k = res;
35.2268 - MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
35.2269 -CLEANUP:
35.2270 - mp_clear(&x);
35.2271 - return res;
35.2272 -}
35.2273 -
35.2274 -/* Known good algorithm for computing modular inverse. But slow. */
35.2275 -mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
35.2276 -{
35.2277 - mp_int g, x;
35.2278 - mp_err res;
35.2279 -
35.2280 - ARGCHK(a && m && c, MP_BADARG);
35.2281 -
35.2282 - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
35.2283 - return MP_RANGE;
35.2284 -
35.2285 - MP_DIGITS(&g) = 0;
35.2286 - MP_DIGITS(&x) = 0;
35.2287 - MP_CHECKOK( mp_init(&x, FLAG(a)) );
35.2288 - MP_CHECKOK( mp_init(&g, FLAG(a)) );
35.2289 -
35.2290 - MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
35.2291 -
35.2292 - if (mp_cmp_d(&g, 1) != MP_EQ) {
35.2293 - res = MP_UNDEF;
35.2294 - goto CLEANUP;
35.2295 - }
35.2296 -
35.2297 - res = mp_mod(&x, m, c);
35.2298 - SIGN(c) = SIGN(a);
35.2299 -
35.2300 -CLEANUP:
35.2301 - mp_clear(&x);
35.2302 - mp_clear(&g);
35.2303 -
35.2304 - return res;
35.2305 -}
35.2306 -
35.2307 -/* modular inverse where modulus is 2**k. */
35.2308 -/* c = a**-1 mod 2**k */
35.2309 -mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
35.2310 -{
35.2311 - mp_err res;
35.2312 - mp_size ix = k + 4;
35.2313 - mp_int t0, t1, val, tmp, two2k;
35.2314 -
35.2315 - static const mp_digit d2 = 2;
35.2316 - static const mp_int two = { 0, MP_ZPOS, 1, 1, (mp_digit *)&d2 };
35.2317 -
35.2318 - if (mp_iseven(a))
35.2319 - return MP_UNDEF;
35.2320 - if (k <= MP_DIGIT_BIT) {
35.2321 - mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
35.2322 - if (k < MP_DIGIT_BIT)
35.2323 - i &= ((mp_digit)1 << k) - (mp_digit)1;
35.2324 - mp_set(c, i);
35.2325 - return MP_OKAY;
35.2326 - }
35.2327 - MP_DIGITS(&t0) = 0;
35.2328 - MP_DIGITS(&t1) = 0;
35.2329 - MP_DIGITS(&val) = 0;
35.2330 - MP_DIGITS(&tmp) = 0;
35.2331 - MP_DIGITS(&two2k) = 0;
35.2332 - MP_CHECKOK( mp_init_copy(&val, a) );
35.2333 - s_mp_mod_2d(&val, k);
35.2334 - MP_CHECKOK( mp_init_copy(&t0, &val) );
35.2335 - MP_CHECKOK( mp_init_copy(&t1, &t0) );
35.2336 - MP_CHECKOK( mp_init(&tmp, FLAG(a)) );
35.2337 - MP_CHECKOK( mp_init(&two2k, FLAG(a)) );
35.2338 - MP_CHECKOK( s_mp_2expt(&two2k, k) );
35.2339 - do {
35.2340 - MP_CHECKOK( mp_mul(&val, &t1, &tmp) );
35.2341 - MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
35.2342 - MP_CHECKOK( mp_mul(&t1, &tmp, &t1) );
35.2343 - s_mp_mod_2d(&t1, k);
35.2344 - while (MP_SIGN(&t1) != MP_ZPOS) {
35.2345 - MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
35.2346 - }
35.2347 - if (mp_cmp(&t1, &t0) == MP_EQ)
35.2348 - break;
35.2349 - MP_CHECKOK( mp_copy(&t1, &t0) );
35.2350 - } while (--ix > 0);
35.2351 - if (!ix) {
35.2352 - res = MP_UNDEF;
35.2353 - } else {
35.2354 - mp_exch(c, &t1);
35.2355 - }
35.2356 -
35.2357 -CLEANUP:
35.2358 - mp_clear(&t0);
35.2359 - mp_clear(&t1);
35.2360 - mp_clear(&val);
35.2361 - mp_clear(&tmp);
35.2362 - mp_clear(&two2k);
35.2363 - return res;
35.2364 -}
35.2365 -
35.2366 -mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
35.2367 -{
35.2368 - mp_err res;
35.2369 - mp_size k;
35.2370 - mp_int oddFactor, evenFactor; /* factors of the modulus */
35.2371 - mp_int oddPart, evenPart; /* parts to combine via CRT. */
35.2372 - mp_int C2, tmp1, tmp2;
35.2373 -
35.2374 - /*static const mp_digit d1 = 1; */
35.2375 - /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
35.2376 -
35.2377 - if ((res = s_mp_ispow2(m)) >= 0) {
35.2378 - k = res;
35.2379 - return s_mp_invmod_2d(a, k, c);
35.2380 - }
35.2381 - MP_DIGITS(&oddFactor) = 0;
35.2382 - MP_DIGITS(&evenFactor) = 0;
35.2383 - MP_DIGITS(&oddPart) = 0;
35.2384 - MP_DIGITS(&evenPart) = 0;
35.2385 - MP_DIGITS(&C2) = 0;
35.2386 - MP_DIGITS(&tmp1) = 0;
35.2387 - MP_DIGITS(&tmp2) = 0;
35.2388 -
35.2389 - MP_CHECKOK( mp_init_copy(&oddFactor, m) ); /* oddFactor = m */
35.2390 - MP_CHECKOK( mp_init(&evenFactor, FLAG(m)) );
35.2391 - MP_CHECKOK( mp_init(&oddPart, FLAG(m)) );
35.2392 - MP_CHECKOK( mp_init(&evenPart, FLAG(m)) );
35.2393 - MP_CHECKOK( mp_init(&C2, FLAG(m)) );
35.2394 - MP_CHECKOK( mp_init(&tmp1, FLAG(m)) );
35.2395 - MP_CHECKOK( mp_init(&tmp2, FLAG(m)) );
35.2396 -
35.2397 - k = mp_trailing_zeros(m);
35.2398 - s_mp_div_2d(&oddFactor, k);
35.2399 - MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
35.2400 -
35.2401 - /* compute a**-1 mod oddFactor. */
35.2402 - MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
35.2403 - /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
35.2404 - MP_CHECKOK( s_mp_invmod_2d( a, k, &evenPart) );
35.2405 -
35.2406 - /* Use Chinese Remainer theorem to compute a**-1 mod m. */
35.2407 - /* let m1 = oddFactor, v1 = oddPart,
35.2408 - * let m2 = evenFactor, v2 = evenPart.
35.2409 - */
35.2410 -
35.2411 - /* Compute C2 = m1**-1 mod m2. */
35.2412 - MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k, &C2) );
35.2413 -
35.2414 - /* compute u = (v2 - v1)*C2 mod m2 */
35.2415 - MP_CHECKOK( mp_sub(&evenPart, &oddPart, &tmp1) );
35.2416 - MP_CHECKOK( mp_mul(&tmp1, &C2, &tmp2) );
35.2417 - s_mp_mod_2d(&tmp2, k);
35.2418 - while (MP_SIGN(&tmp2) != MP_ZPOS) {
35.2419 - MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
35.2420 - }
35.2421 -
35.2422 - /* compute answer = v1 + u*m1 */
35.2423 - MP_CHECKOK( mp_mul(&tmp2, &oddFactor, c) );
35.2424 - MP_CHECKOK( mp_add(&oddPart, c, c) );
35.2425 - /* not sure this is necessary, but it's low cost if not. */
35.2426 - MP_CHECKOK( mp_mod(c, m, c) );
35.2427 -
35.2428 -CLEANUP:
35.2429 - mp_clear(&oddFactor);
35.2430 - mp_clear(&evenFactor);
35.2431 - mp_clear(&oddPart);
35.2432 - mp_clear(&evenPart);
35.2433 - mp_clear(&C2);
35.2434 - mp_clear(&tmp1);
35.2435 - mp_clear(&tmp2);
35.2436 - return res;
35.2437 -}
35.2438 -
35.2439 -
35.2440 -/* {{{ mp_invmod(a, m, c) */
35.2441 -
35.2442 -/*
35.2443 - mp_invmod(a, m, c)
35.2444 -
35.2445 - Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
35.2446 - This is equivalent to the question of whether (a, m) = 1. If not,
35.2447 - MP_UNDEF is returned, and there is no inverse.
35.2448 - */
35.2449 -
35.2450 -mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
35.2451 -{
35.2452 -
35.2453 - ARGCHK(a && m && c, MP_BADARG);
35.2454 -
35.2455 - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
35.2456 - return MP_RANGE;
35.2457 -
35.2458 - if (mp_isodd(m)) {
35.2459 - return s_mp_invmod_odd_m(a, m, c);
35.2460 - }
35.2461 - if (mp_iseven(a))
35.2462 - return MP_UNDEF; /* not invertable */
35.2463 -
35.2464 - return s_mp_invmod_even_m(a, m, c);
35.2465 -
35.2466 -} /* end mp_invmod() */
35.2467 -
35.2468 -/* }}} */
35.2469 -#endif /* if MP_NUMTH */
35.2470 -
35.2471 -/* }}} */
35.2472 -
35.2473 -/*------------------------------------------------------------------------*/
35.2474 -/* {{{ mp_print(mp, ofp) */
35.2475 -
35.2476 -#if MP_IOFUNC
35.2477 -/*
35.2478 - mp_print(mp, ofp)
35.2479 -
35.2480 - Print a textual representation of the given mp_int on the output
35.2481 - stream 'ofp'. Output is generated using the internal radix.
35.2482 - */
35.2483 -
35.2484 -void mp_print(mp_int *mp, FILE *ofp)
35.2485 -{
35.2486 - int ix;
35.2487 -
35.2488 - if(mp == NULL || ofp == NULL)
35.2489 - return;
35.2490 -
35.2491 - fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
35.2492 -
35.2493 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.2494 - fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
35.2495 - }
35.2496 -
35.2497 -} /* end mp_print() */
35.2498 -
35.2499 -#endif /* if MP_IOFUNC */
35.2500 -
35.2501 -/* }}} */
35.2502 -
35.2503 -/*------------------------------------------------------------------------*/
35.2504 -/* {{{ More I/O Functions */
35.2505 -
35.2506 -/* {{{ mp_read_raw(mp, str, len) */
35.2507 -
35.2508 -/*
35.2509 - mp_read_raw(mp, str, len)
35.2510 -
35.2511 - Read in a raw value (base 256) into the given mp_int
35.2512 - */
35.2513 -
35.2514 -mp_err mp_read_raw(mp_int *mp, char *str, int len)
35.2515 -{
35.2516 - int ix;
35.2517 - mp_err res;
35.2518 - unsigned char *ustr = (unsigned char *)str;
35.2519 -
35.2520 - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
35.2521 -
35.2522 - mp_zero(mp);
35.2523 -
35.2524 - /* Get sign from first byte */
35.2525 - if(ustr[0])
35.2526 - SIGN(mp) = NEG;
35.2527 - else
35.2528 - SIGN(mp) = ZPOS;
35.2529 -
35.2530 - /* Read the rest of the digits */
35.2531 - for(ix = 1; ix < len; ix++) {
35.2532 - if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
35.2533 - return res;
35.2534 - if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)
35.2535 - return res;
35.2536 - }
35.2537 -
35.2538 - return MP_OKAY;
35.2539 -
35.2540 -} /* end mp_read_raw() */
35.2541 -
35.2542 -/* }}} */
35.2543 -
35.2544 -/* {{{ mp_raw_size(mp) */
35.2545 -
35.2546 -int mp_raw_size(mp_int *mp)
35.2547 -{
35.2548 - ARGCHK(mp != NULL, 0);
35.2549 -
35.2550 - return (USED(mp) * sizeof(mp_digit)) + 1;
35.2551 -
35.2552 -} /* end mp_raw_size() */
35.2553 -
35.2554 -/* }}} */
35.2555 -
35.2556 -/* {{{ mp_toraw(mp, str) */
35.2557 -
35.2558 -mp_err mp_toraw(mp_int *mp, char *str)
35.2559 -{
35.2560 - int ix, jx, pos = 1;
35.2561 -
35.2562 - ARGCHK(mp != NULL && str != NULL, MP_BADARG);
35.2563 -
35.2564 - str[0] = (char)SIGN(mp);
35.2565 -
35.2566 - /* Iterate over each digit... */
35.2567 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.2568 - mp_digit d = DIGIT(mp, ix);
35.2569 -
35.2570 - /* Unpack digit bytes, high order first */
35.2571 - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
35.2572 - str[pos++] = (char)(d >> (jx * CHAR_BIT));
35.2573 - }
35.2574 - }
35.2575 -
35.2576 - return MP_OKAY;
35.2577 -
35.2578 -} /* end mp_toraw() */
35.2579 -
35.2580 -/* }}} */
35.2581 -
35.2582 -/* {{{ mp_read_radix(mp, str, radix) */
35.2583 -
35.2584 -/*
35.2585 - mp_read_radix(mp, str, radix)
35.2586 -
35.2587 - Read an integer from the given string, and set mp to the resulting
35.2588 - value. The input is presumed to be in base 10. Leading non-digit
35.2589 - characters are ignored, and the function reads until a non-digit
35.2590 - character or the end of the string.
35.2591 - */
35.2592 -
35.2593 -mp_err mp_read_radix(mp_int *mp, const char *str, int radix)
35.2594 -{
35.2595 - int ix = 0, val = 0;
35.2596 - mp_err res;
35.2597 - mp_sign sig = ZPOS;
35.2598 -
35.2599 - ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
35.2600 - MP_BADARG);
35.2601 -
35.2602 - mp_zero(mp);
35.2603 -
35.2604 - /* Skip leading non-digit characters until a digit or '-' or '+' */
35.2605 - while(str[ix] &&
35.2606 - (s_mp_tovalue(str[ix], radix) < 0) &&
35.2607 - str[ix] != '-' &&
35.2608 - str[ix] != '+') {
35.2609 - ++ix;
35.2610 - }
35.2611 -
35.2612 - if(str[ix] == '-') {
35.2613 - sig = NEG;
35.2614 - ++ix;
35.2615 - } else if(str[ix] == '+') {
35.2616 - sig = ZPOS; /* this is the default anyway... */
35.2617 - ++ix;
35.2618 - }
35.2619 -
35.2620 - while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
35.2621 - if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
35.2622 - return res;
35.2623 - if((res = s_mp_add_d(mp, val)) != MP_OKAY)
35.2624 - return res;
35.2625 - ++ix;
35.2626 - }
35.2627 -
35.2628 - if(s_mp_cmp_d(mp, 0) == MP_EQ)
35.2629 - SIGN(mp) = ZPOS;
35.2630 - else
35.2631 - SIGN(mp) = sig;
35.2632 -
35.2633 - return MP_OKAY;
35.2634 -
35.2635 -} /* end mp_read_radix() */
35.2636 -
35.2637 -mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)
35.2638 -{
35.2639 - int radix = default_radix;
35.2640 - int cx;
35.2641 - mp_sign sig = ZPOS;
35.2642 - mp_err res;
35.2643 -
35.2644 - /* Skip leading non-digit characters until a digit or '-' or '+' */
35.2645 - while ((cx = *str) != 0 &&
35.2646 - (s_mp_tovalue(cx, radix) < 0) &&
35.2647 - cx != '-' &&
35.2648 - cx != '+') {
35.2649 - ++str;
35.2650 - }
35.2651 -
35.2652 - if (cx == '-') {
35.2653 - sig = NEG;
35.2654 - ++str;
35.2655 - } else if (cx == '+') {
35.2656 - sig = ZPOS; /* this is the default anyway... */
35.2657 - ++str;
35.2658 - }
35.2659 -
35.2660 - if (str[0] == '0') {
35.2661 - if ((str[1] | 0x20) == 'x') {
35.2662 - radix = 16;
35.2663 - str += 2;
35.2664 - } else {
35.2665 - radix = 8;
35.2666 - str++;
35.2667 - }
35.2668 - }
35.2669 - res = mp_read_radix(a, str, radix);
35.2670 - if (res == MP_OKAY) {
35.2671 - MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;
35.2672 - }
35.2673 - return res;
35.2674 -}
35.2675 -
35.2676 -/* }}} */
35.2677 -
35.2678 -/* {{{ mp_radix_size(mp, radix) */
35.2679 -
35.2680 -int mp_radix_size(mp_int *mp, int radix)
35.2681 -{
35.2682 - int bits;
35.2683 -
35.2684 - if(!mp || radix < 2 || radix > MAX_RADIX)
35.2685 - return 0;
35.2686 -
35.2687 - bits = USED(mp) * DIGIT_BIT - 1;
35.2688 -
35.2689 - return s_mp_outlen(bits, radix);
35.2690 -
35.2691 -} /* end mp_radix_size() */
35.2692 -
35.2693 -/* }}} */
35.2694 -
35.2695 -/* {{{ mp_toradix(mp, str, radix) */
35.2696 -
35.2697 -mp_err mp_toradix(mp_int *mp, char *str, int radix)
35.2698 -{
35.2699 - int ix, pos = 0;
35.2700 -
35.2701 - ARGCHK(mp != NULL && str != NULL, MP_BADARG);
35.2702 - ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
35.2703 -
35.2704 - if(mp_cmp_z(mp) == MP_EQ) {
35.2705 - str[0] = '0';
35.2706 - str[1] = '\0';
35.2707 - } else {
35.2708 - mp_err res;
35.2709 - mp_int tmp;
35.2710 - mp_sign sgn;
35.2711 - mp_digit rem, rdx = (mp_digit)radix;
35.2712 - char ch;
35.2713 -
35.2714 - if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
35.2715 - return res;
35.2716 -
35.2717 - /* Save sign for later, and take absolute value */
35.2718 - sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;
35.2719 -
35.2720 - /* Generate output digits in reverse order */
35.2721 - while(mp_cmp_z(&tmp) != 0) {
35.2722 - if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {
35.2723 - mp_clear(&tmp);
35.2724 - return res;
35.2725 - }
35.2726 -
35.2727 - /* Generate digits, use capital letters */
35.2728 - ch = s_mp_todigit(rem, radix, 0);
35.2729 -
35.2730 - str[pos++] = ch;
35.2731 - }
35.2732 -
35.2733 - /* Add - sign if original value was negative */
35.2734 - if(sgn == NEG)
35.2735 - str[pos++] = '-';
35.2736 -
35.2737 - /* Add trailing NUL to end the string */
35.2738 - str[pos--] = '\0';
35.2739 -
35.2740 - /* Reverse the digits and sign indicator */
35.2741 - ix = 0;
35.2742 - while(ix < pos) {
35.2743 - char tmp = str[ix];
35.2744 -
35.2745 - str[ix] = str[pos];
35.2746 - str[pos] = tmp;
35.2747 - ++ix;
35.2748 - --pos;
35.2749 - }
35.2750 -
35.2751 - mp_clear(&tmp);
35.2752 - }
35.2753 -
35.2754 - return MP_OKAY;
35.2755 -
35.2756 -} /* end mp_toradix() */
35.2757 -
35.2758 -/* }}} */
35.2759 -
35.2760 -/* {{{ mp_tovalue(ch, r) */
35.2761 -
35.2762 -int mp_tovalue(char ch, int r)
35.2763 -{
35.2764 - return s_mp_tovalue(ch, r);
35.2765 -
35.2766 -} /* end mp_tovalue() */
35.2767 -
35.2768 -/* }}} */
35.2769 -
35.2770 -/* }}} */
35.2771 -
35.2772 -/* {{{ mp_strerror(ec) */
35.2773 -
35.2774 -/*
35.2775 - mp_strerror(ec)
35.2776 -
35.2777 - Return a string describing the meaning of error code 'ec'. The
35.2778 - string returned is allocated in static memory, so the caller should
35.2779 - not attempt to modify or free the memory associated with this
35.2780 - string.
35.2781 - */
35.2782 -const char *mp_strerror(mp_err ec)
35.2783 -{
35.2784 - int aec = (ec < 0) ? -ec : ec;
35.2785 -
35.2786 - /* Code values are negative, so the senses of these comparisons
35.2787 - are accurate */
35.2788 - if(ec < MP_LAST_CODE || ec > MP_OKAY) {
35.2789 - return mp_err_string[0]; /* unknown error code */
35.2790 - } else {
35.2791 - return mp_err_string[aec + 1];
35.2792 - }
35.2793 -
35.2794 -} /* end mp_strerror() */
35.2795 -
35.2796 -/* }}} */
35.2797 -
35.2798 -/*========================================================================*/
35.2799 -/*------------------------------------------------------------------------*/
35.2800 -/* Static function definitions (internal use only) */
35.2801 -
35.2802 -/* {{{ Memory management */
35.2803 -
35.2804 -/* {{{ s_mp_grow(mp, min) */
35.2805 -
35.2806 -/* Make sure there are at least 'min' digits allocated to mp */
35.2807 -mp_err s_mp_grow(mp_int *mp, mp_size min)
35.2808 -{
35.2809 - if(min > ALLOC(mp)) {
35.2810 - mp_digit *tmp;
35.2811 -
35.2812 - /* Set min to next nearest default precision block size */
35.2813 - min = MP_ROUNDUP(min, s_mp_defprec);
35.2814 -
35.2815 - if((tmp = s_mp_alloc(min, sizeof(mp_digit), FLAG(mp))) == NULL)
35.2816 - return MP_MEM;
35.2817 -
35.2818 - s_mp_copy(DIGITS(mp), tmp, USED(mp));
35.2819 -
35.2820 -#if MP_CRYPTO
35.2821 - s_mp_setz(DIGITS(mp), ALLOC(mp));
35.2822 -#endif
35.2823 - s_mp_free(DIGITS(mp), ALLOC(mp));
35.2824 - DIGITS(mp) = tmp;
35.2825 - ALLOC(mp) = min;
35.2826 - }
35.2827 -
35.2828 - return MP_OKAY;
35.2829 -
35.2830 -} /* end s_mp_grow() */
35.2831 -
35.2832 -/* }}} */
35.2833 -
35.2834 -/* {{{ s_mp_pad(mp, min) */
35.2835 -
35.2836 -/* Make sure the used size of mp is at least 'min', growing if needed */
35.2837 -mp_err s_mp_pad(mp_int *mp, mp_size min)
35.2838 -{
35.2839 - if(min > USED(mp)) {
35.2840 - mp_err res;
35.2841 -
35.2842 - /* Make sure there is room to increase precision */
35.2843 - if (min > ALLOC(mp)) {
35.2844 - if ((res = s_mp_grow(mp, min)) != MP_OKAY)
35.2845 - return res;
35.2846 - } else {
35.2847 - s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));
35.2848 - }
35.2849 -
35.2850 - /* Increase precision; should already be 0-filled */
35.2851 - USED(mp) = min;
35.2852 - }
35.2853 -
35.2854 - return MP_OKAY;
35.2855 -
35.2856 -} /* end s_mp_pad() */
35.2857 -
35.2858 -/* }}} */
35.2859 -
35.2860 -/* {{{ s_mp_setz(dp, count) */
35.2861 -
35.2862 -#if MP_MACRO == 0
35.2863 -/* Set 'count' digits pointed to by dp to be zeroes */
35.2864 -void s_mp_setz(mp_digit *dp, mp_size count)
35.2865 -{
35.2866 -#if MP_MEMSET == 0
35.2867 - int ix;
35.2868 -
35.2869 - for(ix = 0; ix < count; ix++)
35.2870 - dp[ix] = 0;
35.2871 -#else
35.2872 - memset(dp, 0, count * sizeof(mp_digit));
35.2873 -#endif
35.2874 -
35.2875 -} /* end s_mp_setz() */
35.2876 -#endif
35.2877 -
35.2878 -/* }}} */
35.2879 -
35.2880 -/* {{{ s_mp_copy(sp, dp, count) */
35.2881 -
35.2882 -#if MP_MACRO == 0
35.2883 -/* Copy 'count' digits from sp to dp */
35.2884 -void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
35.2885 -{
35.2886 -#if MP_MEMCPY == 0
35.2887 - int ix;
35.2888 -
35.2889 - for(ix = 0; ix < count; ix++)
35.2890 - dp[ix] = sp[ix];
35.2891 -#else
35.2892 - memcpy(dp, sp, count * sizeof(mp_digit));
35.2893 -#endif
35.2894 -
35.2895 -} /* end s_mp_copy() */
35.2896 -#endif
35.2897 -
35.2898 -/* }}} */
35.2899 -
35.2900 -/* {{{ s_mp_alloc(nb, ni, kmflag) */
35.2901 -
35.2902 -#if MP_MACRO == 0
35.2903 -/* Allocate ni records of nb bytes each, and return a pointer to that */
35.2904 -void *s_mp_alloc(size_t nb, size_t ni, int kmflag)
35.2905 -{
35.2906 - mp_int *mp;
35.2907 - ++mp_allocs;
35.2908 -#ifdef _KERNEL
35.2909 - mp = kmem_zalloc(nb * ni, kmflag);
35.2910 - if (mp != NULL)
35.2911 - FLAG(mp) = kmflag;
35.2912 - return (mp);
35.2913 -#else
35.2914 - return calloc(nb, ni);
35.2915 -#endif
35.2916 -
35.2917 -} /* end s_mp_alloc() */
35.2918 -#endif
35.2919 -
35.2920 -/* }}} */
35.2921 -
35.2922 -/* {{{ s_mp_free(ptr) */
35.2923 -
35.2924 -#if MP_MACRO == 0
35.2925 -/* Free the memory pointed to by ptr */
35.2926 -void s_mp_free(void *ptr, mp_size alloc)
35.2927 -{
35.2928 - if(ptr) {
35.2929 - ++mp_frees;
35.2930 -#ifdef _KERNEL
35.2931 - kmem_free(ptr, alloc * sizeof (mp_digit));
35.2932 -#else
35.2933 - free(ptr);
35.2934 -#endif
35.2935 - }
35.2936 -} /* end s_mp_free() */
35.2937 -#endif
35.2938 -
35.2939 -/* }}} */
35.2940 -
35.2941 -/* {{{ s_mp_clamp(mp) */
35.2942 -
35.2943 -#if MP_MACRO == 0
35.2944 -/* Remove leading zeroes from the given value */
35.2945 -void s_mp_clamp(mp_int *mp)
35.2946 -{
35.2947 - mp_size used = MP_USED(mp);
35.2948 - while (used > 1 && DIGIT(mp, used - 1) == 0)
35.2949 - --used;
35.2950 - MP_USED(mp) = used;
35.2951 -} /* end s_mp_clamp() */
35.2952 -#endif
35.2953 -
35.2954 -/* }}} */
35.2955 -
35.2956 -/* {{{ s_mp_exch(a, b) */
35.2957 -
35.2958 -/* Exchange the data for a and b; (b, a) = (a, b) */
35.2959 -void s_mp_exch(mp_int *a, mp_int *b)
35.2960 -{
35.2961 - mp_int tmp;
35.2962 -
35.2963 - tmp = *a;
35.2964 - *a = *b;
35.2965 - *b = tmp;
35.2966 -
35.2967 -} /* end s_mp_exch() */
35.2968 -
35.2969 -/* }}} */
35.2970 -
35.2971 -/* }}} */
35.2972 -
35.2973 -/* {{{ Arithmetic helpers */
35.2974 -
35.2975 -/* {{{ s_mp_lshd(mp, p) */
35.2976 -
35.2977 -/*
35.2978 - Shift mp leftward by p digits, growing if needed, and zero-filling
35.2979 - the in-shifted digits at the right end. This is a convenient
35.2980 - alternative to multiplication by powers of the radix
35.2981 - The value of USED(mp) must already have been set to the value for
35.2982 - the shifted result.
35.2983 - */
35.2984 -
35.2985 -mp_err s_mp_lshd(mp_int *mp, mp_size p)
35.2986 -{
35.2987 - mp_err res;
35.2988 - mp_size pos;
35.2989 - int ix;
35.2990 -
35.2991 - if(p == 0)
35.2992 - return MP_OKAY;
35.2993 -
35.2994 - if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
35.2995 - return MP_OKAY;
35.2996 -
35.2997 - if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
35.2998 - return res;
35.2999 -
35.3000 - pos = USED(mp) - 1;
35.3001 -
35.3002 - /* Shift all the significant figures over as needed */
35.3003 - for(ix = pos - p; ix >= 0; ix--)
35.3004 - DIGIT(mp, ix + p) = DIGIT(mp, ix);
35.3005 -
35.3006 - /* Fill the bottom digits with zeroes */
35.3007 - for(ix = 0; ix < p; ix++)
35.3008 - DIGIT(mp, ix) = 0;
35.3009 -
35.3010 - return MP_OKAY;
35.3011 -
35.3012 -} /* end s_mp_lshd() */
35.3013 -
35.3014 -/* }}} */
35.3015 -
35.3016 -/* {{{ s_mp_mul_2d(mp, d) */
35.3017 -
35.3018 -/*
35.3019 - Multiply the integer by 2^d, where d is a number of bits. This
35.3020 - amounts to a bitwise shift of the value.
35.3021 - */
35.3022 -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d)
35.3023 -{
35.3024 - mp_err res;
35.3025 - mp_digit dshift, bshift;
35.3026 - mp_digit mask;
35.3027 -
35.3028 - ARGCHK(mp != NULL, MP_BADARG);
35.3029 -
35.3030 - dshift = d / MP_DIGIT_BIT;
35.3031 - bshift = d % MP_DIGIT_BIT;
35.3032 - /* bits to be shifted out of the top word */
35.3033 - mask = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));
35.3034 - mask &= MP_DIGIT(mp, MP_USED(mp) - 1);
35.3035 -
35.3036 - if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
35.3037 - return res;
35.3038 -
35.3039 - if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))
35.3040 - return res;
35.3041 -
35.3042 - if (bshift) {
35.3043 - mp_digit *pa = MP_DIGITS(mp);
35.3044 - mp_digit *alim = pa + MP_USED(mp);
35.3045 - mp_digit prev = 0;
35.3046 -
35.3047 - for (pa += dshift; pa < alim; ) {
35.3048 - mp_digit x = *pa;
35.3049 - *pa++ = (x << bshift) | prev;
35.3050 - prev = x >> (DIGIT_BIT - bshift);
35.3051 - }
35.3052 - }
35.3053 -
35.3054 - s_mp_clamp(mp);
35.3055 - return MP_OKAY;
35.3056 -} /* end s_mp_mul_2d() */
35.3057 -
35.3058 -/* {{{ s_mp_rshd(mp, p) */
35.3059 -
35.3060 -/*
35.3061 - Shift mp rightward by p digits. Maintains the invariant that
35.3062 - digits above the precision are all zero. Digits shifted off the
35.3063 - end are lost. Cannot fail.
35.3064 - */
35.3065 -
35.3066 -void s_mp_rshd(mp_int *mp, mp_size p)
35.3067 -{
35.3068 - mp_size ix;
35.3069 - mp_digit *src, *dst;
35.3070 -
35.3071 - if(p == 0)
35.3072 - return;
35.3073 -
35.3074 - /* Shortcut when all digits are to be shifted off */
35.3075 - if(p >= USED(mp)) {
35.3076 - s_mp_setz(DIGITS(mp), ALLOC(mp));
35.3077 - USED(mp) = 1;
35.3078 - SIGN(mp) = ZPOS;
35.3079 - return;
35.3080 - }
35.3081 -
35.3082 - /* Shift all the significant figures over as needed */
35.3083 - dst = MP_DIGITS(mp);
35.3084 - src = dst + p;
35.3085 - for (ix = USED(mp) - p; ix > 0; ix--)
35.3086 - *dst++ = *src++;
35.3087 -
35.3088 - MP_USED(mp) -= p;
35.3089 - /* Fill the top digits with zeroes */
35.3090 - while (p-- > 0)
35.3091 - *dst++ = 0;
35.3092 -
35.3093 -#if 0
35.3094 - /* Strip off any leading zeroes */
35.3095 - s_mp_clamp(mp);
35.3096 -#endif
35.3097 -
35.3098 -} /* end s_mp_rshd() */
35.3099 -
35.3100 -/* }}} */
35.3101 -
35.3102 -/* {{{ s_mp_div_2(mp) */
35.3103 -
35.3104 -/* Divide by two -- take advantage of radix properties to do it fast */
35.3105 -void s_mp_div_2(mp_int *mp)
35.3106 -{
35.3107 - s_mp_div_2d(mp, 1);
35.3108 -
35.3109 -} /* end s_mp_div_2() */
35.3110 -
35.3111 -/* }}} */
35.3112 -
35.3113 -/* {{{ s_mp_mul_2(mp) */
35.3114 -
35.3115 -mp_err s_mp_mul_2(mp_int *mp)
35.3116 -{
35.3117 - mp_digit *pd;
35.3118 - int ix, used;
35.3119 - mp_digit kin = 0;
35.3120 -
35.3121 - /* Shift digits leftward by 1 bit */
35.3122 - used = MP_USED(mp);
35.3123 - pd = MP_DIGITS(mp);
35.3124 - for (ix = 0; ix < used; ix++) {
35.3125 - mp_digit d = *pd;
35.3126 - *pd++ = (d << 1) | kin;
35.3127 - kin = (d >> (DIGIT_BIT - 1));
35.3128 - }
35.3129 -
35.3130 - /* Deal with rollover from last digit */
35.3131 - if (kin) {
35.3132 - if (ix >= ALLOC(mp)) {
35.3133 - mp_err res;
35.3134 - if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
35.3135 - return res;
35.3136 - }
35.3137 -
35.3138 - DIGIT(mp, ix) = kin;
35.3139 - USED(mp) += 1;
35.3140 - }
35.3141 -
35.3142 - return MP_OKAY;
35.3143 -
35.3144 -} /* end s_mp_mul_2() */
35.3145 -
35.3146 -/* }}} */
35.3147 -
35.3148 -/* {{{ s_mp_mod_2d(mp, d) */
35.3149 -
35.3150 -/*
35.3151 - Remainder the integer by 2^d, where d is a number of bits. This
35.3152 - amounts to a bitwise AND of the value, and does not require the full
35.3153 - division code
35.3154 - */
35.3155 -void s_mp_mod_2d(mp_int *mp, mp_digit d)
35.3156 -{
35.3157 - mp_size ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
35.3158 - mp_size ix;
35.3159 - mp_digit dmask;
35.3160 -
35.3161 - if(ndig >= USED(mp))
35.3162 - return;
35.3163 -
35.3164 - /* Flush all the bits above 2^d in its digit */
35.3165 - dmask = ((mp_digit)1 << nbit) - 1;
35.3166 - DIGIT(mp, ndig) &= dmask;
35.3167 -
35.3168 - /* Flush all digits above the one with 2^d in it */
35.3169 - for(ix = ndig + 1; ix < USED(mp); ix++)
35.3170 - DIGIT(mp, ix) = 0;
35.3171 -
35.3172 - s_mp_clamp(mp);
35.3173 -
35.3174 -} /* end s_mp_mod_2d() */
35.3175 -
35.3176 -/* }}} */
35.3177 -
35.3178 -/* {{{ s_mp_div_2d(mp, d) */
35.3179 -
35.3180 -/*
35.3181 - Divide the integer by 2^d, where d is a number of bits. This
35.3182 - amounts to a bitwise shift of the value, and does not require the
35.3183 - full division code (used in Barrett reduction, see below)
35.3184 - */
35.3185 -void s_mp_div_2d(mp_int *mp, mp_digit d)
35.3186 -{
35.3187 - int ix;
35.3188 - mp_digit save, next, mask;
35.3189 -
35.3190 - s_mp_rshd(mp, d / DIGIT_BIT);
35.3191 - d %= DIGIT_BIT;
35.3192 - if (d) {
35.3193 - mask = ((mp_digit)1 << d) - 1;
35.3194 - save = 0;
35.3195 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.3196 - next = DIGIT(mp, ix) & mask;
35.3197 - DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));
35.3198 - save = next;
35.3199 - }
35.3200 - }
35.3201 - s_mp_clamp(mp);
35.3202 -
35.3203 -} /* end s_mp_div_2d() */
35.3204 -
35.3205 -/* }}} */
35.3206 -
35.3207 -/* {{{ s_mp_norm(a, b, *d) */
35.3208 -
35.3209 -/*
35.3210 - s_mp_norm(a, b, *d)
35.3211 -
35.3212 - Normalize a and b for division, where b is the divisor. In order
35.3213 - that we might make good guesses for quotient digits, we want the
35.3214 - leading digit of b to be at least half the radix, which we
35.3215 - accomplish by multiplying a and b by a power of 2. The exponent
35.3216 - (shift count) is placed in *pd, so that the remainder can be shifted
35.3217 - back at the end of the division process.
35.3218 - */
35.3219 -
35.3220 -mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
35.3221 -{
35.3222 - mp_digit d;
35.3223 - mp_digit mask;
35.3224 - mp_digit b_msd;
35.3225 - mp_err res = MP_OKAY;
35.3226 -
35.3227 - d = 0;
35.3228 - mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */
35.3229 - b_msd = DIGIT(b, USED(b) - 1);
35.3230 - while (!(b_msd & mask)) {
35.3231 - b_msd <<= 1;
35.3232 - ++d;
35.3233 - }
35.3234 -
35.3235 - if (d) {
35.3236 - MP_CHECKOK( s_mp_mul_2d(a, d) );
35.3237 - MP_CHECKOK( s_mp_mul_2d(b, d) );
35.3238 - }
35.3239 -
35.3240 - *pd = d;
35.3241 -CLEANUP:
35.3242 - return res;
35.3243 -
35.3244 -} /* end s_mp_norm() */
35.3245 -
35.3246 -/* }}} */
35.3247 -
35.3248 -/* }}} */
35.3249 -
35.3250 -/* {{{ Primitive digit arithmetic */
35.3251 -
35.3252 -/* {{{ s_mp_add_d(mp, d) */
35.3253 -
35.3254 -/* Add d to |mp| in place */
35.3255 -mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */
35.3256 -{
35.3257 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3258 - mp_word w, k = 0;
35.3259 - mp_size ix = 1;
35.3260 -
35.3261 - w = (mp_word)DIGIT(mp, 0) + d;
35.3262 - DIGIT(mp, 0) = ACCUM(w);
35.3263 - k = CARRYOUT(w);
35.3264 -
35.3265 - while(ix < USED(mp) && k) {
35.3266 - w = (mp_word)DIGIT(mp, ix) + k;
35.3267 - DIGIT(mp, ix) = ACCUM(w);
35.3268 - k = CARRYOUT(w);
35.3269 - ++ix;
35.3270 - }
35.3271 -
35.3272 - if(k != 0) {
35.3273 - mp_err res;
35.3274 -
35.3275 - if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
35.3276 - return res;
35.3277 -
35.3278 - DIGIT(mp, ix) = (mp_digit)k;
35.3279 - }
35.3280 -
35.3281 - return MP_OKAY;
35.3282 -#else
35.3283 - mp_digit * pmp = MP_DIGITS(mp);
35.3284 - mp_digit sum, mp_i, carry = 0;
35.3285 - mp_err res = MP_OKAY;
35.3286 - int used = (int)MP_USED(mp);
35.3287 -
35.3288 - mp_i = *pmp;
35.3289 - *pmp++ = sum = d + mp_i;
35.3290 - carry = (sum < d);
35.3291 - while (carry && --used > 0) {
35.3292 - mp_i = *pmp;
35.3293 - *pmp++ = sum = carry + mp_i;
35.3294 - carry = !sum;
35.3295 - }
35.3296 - if (carry && !used) {
35.3297 - /* mp is growing */
35.3298 - used = MP_USED(mp);
35.3299 - MP_CHECKOK( s_mp_pad(mp, used + 1) );
35.3300 - MP_DIGIT(mp, used) = carry;
35.3301 - }
35.3302 -CLEANUP:
35.3303 - return res;
35.3304 -#endif
35.3305 -} /* end s_mp_add_d() */
35.3306 -
35.3307 -/* }}} */
35.3308 -
35.3309 -/* {{{ s_mp_sub_d(mp, d) */
35.3310 -
35.3311 -/* Subtract d from |mp| in place, assumes |mp| > d */
35.3312 -mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
35.3313 -{
35.3314 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3315 - mp_word w, b = 0;
35.3316 - mp_size ix = 1;
35.3317 -
35.3318 - /* Compute initial subtraction */
35.3319 - w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
35.3320 - b = CARRYOUT(w) ? 0 : 1;
35.3321 - DIGIT(mp, 0) = ACCUM(w);
35.3322 -
35.3323 - /* Propagate borrows leftward */
35.3324 - while(b && ix < USED(mp)) {
35.3325 - w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
35.3326 - b = CARRYOUT(w) ? 0 : 1;
35.3327 - DIGIT(mp, ix) = ACCUM(w);
35.3328 - ++ix;
35.3329 - }
35.3330 -
35.3331 - /* Remove leading zeroes */
35.3332 - s_mp_clamp(mp);
35.3333 -
35.3334 - /* If we have a borrow out, it's a violation of the input invariant */
35.3335 - if(b)
35.3336 - return MP_RANGE;
35.3337 - else
35.3338 - return MP_OKAY;
35.3339 -#else
35.3340 - mp_digit *pmp = MP_DIGITS(mp);
35.3341 - mp_digit mp_i, diff, borrow;
35.3342 - mp_size used = MP_USED(mp);
35.3343 -
35.3344 - mp_i = *pmp;
35.3345 - *pmp++ = diff = mp_i - d;
35.3346 - borrow = (diff > mp_i);
35.3347 - while (borrow && --used) {
35.3348 - mp_i = *pmp;
35.3349 - *pmp++ = diff = mp_i - borrow;
35.3350 - borrow = (diff > mp_i);
35.3351 - }
35.3352 - s_mp_clamp(mp);
35.3353 - return (borrow && !used) ? MP_RANGE : MP_OKAY;
35.3354 -#endif
35.3355 -} /* end s_mp_sub_d() */
35.3356 -
35.3357 -/* }}} */
35.3358 -
35.3359 -/* {{{ s_mp_mul_d(a, d) */
35.3360 -
35.3361 -/* Compute a = a * d, single digit multiplication */
35.3362 -mp_err s_mp_mul_d(mp_int *a, mp_digit d)
35.3363 -{
35.3364 - mp_err res;
35.3365 - mp_size used;
35.3366 - int pow;
35.3367 -
35.3368 - if (!d) {
35.3369 - mp_zero(a);
35.3370 - return MP_OKAY;
35.3371 - }
35.3372 - if (d == 1)
35.3373 - return MP_OKAY;
35.3374 - if (0 <= (pow = s_mp_ispow2d(d))) {
35.3375 - return s_mp_mul_2d(a, (mp_digit)pow);
35.3376 - }
35.3377 -
35.3378 - used = MP_USED(a);
35.3379 - MP_CHECKOK( s_mp_pad(a, used + 1) );
35.3380 -
35.3381 - s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
35.3382 -
35.3383 - s_mp_clamp(a);
35.3384 -
35.3385 -CLEANUP:
35.3386 - return res;
35.3387 -
35.3388 -} /* end s_mp_mul_d() */
35.3389 -
35.3390 -/* }}} */
35.3391 -
35.3392 -/* {{{ s_mp_div_d(mp, d, r) */
35.3393 -
35.3394 -/*
35.3395 - s_mp_div_d(mp, d, r)
35.3396 -
35.3397 - Compute the quotient mp = mp / d and remainder r = mp mod d, for a
35.3398 - single digit d. If r is null, the remainder will be discarded.
35.3399 - */
35.3400 -
35.3401 -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
35.3402 -{
35.3403 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
35.3404 - mp_word w = 0, q;
35.3405 -#else
35.3406 - mp_digit w, q;
35.3407 -#endif
35.3408 - int ix;
35.3409 - mp_err res;
35.3410 - mp_int quot;
35.3411 - mp_int rem;
35.3412 -
35.3413 - if(d == 0)
35.3414 - return MP_RANGE;
35.3415 - if (d == 1) {
35.3416 - if (r)
35.3417 - *r = 0;
35.3418 - return MP_OKAY;
35.3419 - }
35.3420 - /* could check for power of 2 here, but mp_div_d does that. */
35.3421 - if (MP_USED(mp) == 1) {
35.3422 - mp_digit n = MP_DIGIT(mp,0);
35.3423 - mp_digit rem;
35.3424 -
35.3425 - q = n / d;
35.3426 - rem = n % d;
35.3427 - MP_DIGIT(mp,0) = q;
35.3428 - if (r)
35.3429 - *r = rem;
35.3430 - return MP_OKAY;
35.3431 - }
35.3432 -
35.3433 - MP_DIGITS(&rem) = 0;
35.3434 - MP_DIGITS(") = 0;
35.3435 - /* Make room for the quotient */
35.3436 - MP_CHECKOK( mp_init_size(", USED(mp), FLAG(mp)) );
35.3437 -
35.3438 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
35.3439 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.3440 - w = (w << DIGIT_BIT) | DIGIT(mp, ix);
35.3441 -
35.3442 - if(w >= d) {
35.3443 - q = w / d;
35.3444 - w = w % d;
35.3445 - } else {
35.3446 - q = 0;
35.3447 - }
35.3448 -
35.3449 - s_mp_lshd(", 1);
35.3450 - DIGIT(", 0) = (mp_digit)q;
35.3451 - }
35.3452 -#else
35.3453 - {
35.3454 - mp_digit p;
35.3455 -#if !defined(MP_ASSEMBLY_DIV_2DX1D)
35.3456 - mp_digit norm;
35.3457 -#endif
35.3458 -
35.3459 - MP_CHECKOK( mp_init_copy(&rem, mp) );
35.3460 -
35.3461 -#if !defined(MP_ASSEMBLY_DIV_2DX1D)
35.3462 - MP_DIGIT(", 0) = d;
35.3463 - MP_CHECKOK( s_mp_norm(&rem, ", &norm) );
35.3464 - if (norm)
35.3465 - d <<= norm;
35.3466 - MP_DIGIT(", 0) = 0;
35.3467 -#endif
35.3468 -
35.3469 - p = 0;
35.3470 - for (ix = USED(&rem) - 1; ix >= 0; ix--) {
35.3471 - w = DIGIT(&rem, ix);
35.3472 -
35.3473 - if (p) {
35.3474 - MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );
35.3475 - } else if (w >= d) {
35.3476 - q = w / d;
35.3477 - w = w % d;
35.3478 - } else {
35.3479 - q = 0;
35.3480 - }
35.3481 -
35.3482 - MP_CHECKOK( s_mp_lshd(", 1) );
35.3483 - DIGIT(", 0) = q;
35.3484 - p = w;
35.3485 - }
35.3486 -#if !defined(MP_ASSEMBLY_DIV_2DX1D)
35.3487 - if (norm)
35.3488 - w >>= norm;
35.3489 -#endif
35.3490 - }
35.3491 -#endif
35.3492 -
35.3493 - /* Deliver the remainder, if desired */
35.3494 - if(r)
35.3495 - *r = (mp_digit)w;
35.3496 -
35.3497 - s_mp_clamp(");
35.3498 - mp_exch(", mp);
35.3499 -CLEANUP:
35.3500 - mp_clear(");
35.3501 - mp_clear(&rem);
35.3502 -
35.3503 - return res;
35.3504 -} /* end s_mp_div_d() */
35.3505 -
35.3506 -/* }}} */
35.3507 -
35.3508 -
35.3509 -/* }}} */
35.3510 -
35.3511 -/* {{{ Primitive full arithmetic */
35.3512 -
35.3513 -/* {{{ s_mp_add(a, b) */
35.3514 -
35.3515 -/* Compute a = |a| + |b| */
35.3516 -mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */
35.3517 -{
35.3518 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3519 - mp_word w = 0;
35.3520 -#else
35.3521 - mp_digit d, sum, carry = 0;
35.3522 -#endif
35.3523 - mp_digit *pa, *pb;
35.3524 - mp_size ix;
35.3525 - mp_size used;
35.3526 - mp_err res;
35.3527 -
35.3528 - /* Make sure a has enough precision for the output value */
35.3529 - if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)
35.3530 - return res;
35.3531 -
35.3532 - /*
35.3533 - Add up all digits up to the precision of b. If b had initially
35.3534 - the same precision as a, or greater, we took care of it by the
35.3535 - padding step above, so there is no problem. If b had initially
35.3536 - less precision, we'll have to make sure the carry out is duly
35.3537 - propagated upward among the higher-order digits of the sum.
35.3538 - */
35.3539 - pa = MP_DIGITS(a);
35.3540 - pb = MP_DIGITS(b);
35.3541 - used = MP_USED(b);
35.3542 - for(ix = 0; ix < used; ix++) {
35.3543 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3544 - w = w + *pa + *pb++;
35.3545 - *pa++ = ACCUM(w);
35.3546 - w = CARRYOUT(w);
35.3547 -#else
35.3548 - d = *pa;
35.3549 - sum = d + *pb++;
35.3550 - d = (sum < d); /* detect overflow */
35.3551 - *pa++ = sum += carry;
35.3552 - carry = d + (sum < carry); /* detect overflow */
35.3553 -#endif
35.3554 - }
35.3555 -
35.3556 - /* If we run out of 'b' digits before we're actually done, make
35.3557 - sure the carries get propagated upward...
35.3558 - */
35.3559 - used = MP_USED(a);
35.3560 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3561 - while (w && ix < used) {
35.3562 - w = w + *pa;
35.3563 - *pa++ = ACCUM(w);
35.3564 - w = CARRYOUT(w);
35.3565 - ++ix;
35.3566 - }
35.3567 -#else
35.3568 - while (carry && ix < used) {
35.3569 - sum = carry + *pa;
35.3570 - *pa++ = sum;
35.3571 - carry = !sum;
35.3572 - ++ix;
35.3573 - }
35.3574 -#endif
35.3575 -
35.3576 - /* If there's an overall carry out, increase precision and include
35.3577 - it. We could have done this initially, but why touch the memory
35.3578 - allocator unless we're sure we have to?
35.3579 - */
35.3580 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3581 - if (w) {
35.3582 - if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
35.3583 - return res;
35.3584 -
35.3585 - DIGIT(a, ix) = (mp_digit)w;
35.3586 - }
35.3587 -#else
35.3588 - if (carry) {
35.3589 - if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
35.3590 - return res;
35.3591 -
35.3592 - DIGIT(a, used) = carry;
35.3593 - }
35.3594 -#endif
35.3595 -
35.3596 - return MP_OKAY;
35.3597 -} /* end s_mp_add() */
35.3598 -
35.3599 -/* }}} */
35.3600 -
35.3601 -/* Compute c = |a| + |b| */ /* magnitude addition */
35.3602 -mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
35.3603 -{
35.3604 - mp_digit *pa, *pb, *pc;
35.3605 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3606 - mp_word w = 0;
35.3607 -#else
35.3608 - mp_digit sum, carry = 0, d;
35.3609 -#endif
35.3610 - mp_size ix;
35.3611 - mp_size used;
35.3612 - mp_err res;
35.3613 -
35.3614 - MP_SIGN(c) = MP_SIGN(a);
35.3615 - if (MP_USED(a) < MP_USED(b)) {
35.3616 - const mp_int *xch = a;
35.3617 - a = b;
35.3618 - b = xch;
35.3619 - }
35.3620 -
35.3621 - /* Make sure a has enough precision for the output value */
35.3622 - if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
35.3623 - return res;
35.3624 -
35.3625 - /*
35.3626 - Add up all digits up to the precision of b. If b had initially
35.3627 - the same precision as a, or greater, we took care of it by the
35.3628 - exchange step above, so there is no problem. If b had initially
35.3629 - less precision, we'll have to make sure the carry out is duly
35.3630 - propagated upward among the higher-order digits of the sum.
35.3631 - */
35.3632 - pa = MP_DIGITS(a);
35.3633 - pb = MP_DIGITS(b);
35.3634 - pc = MP_DIGITS(c);
35.3635 - used = MP_USED(b);
35.3636 - for (ix = 0; ix < used; ix++) {
35.3637 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3638 - w = w + *pa++ + *pb++;
35.3639 - *pc++ = ACCUM(w);
35.3640 - w = CARRYOUT(w);
35.3641 -#else
35.3642 - d = *pa++;
35.3643 - sum = d + *pb++;
35.3644 - d = (sum < d); /* detect overflow */
35.3645 - *pc++ = sum += carry;
35.3646 - carry = d + (sum < carry); /* detect overflow */
35.3647 -#endif
35.3648 - }
35.3649 -
35.3650 - /* If we run out of 'b' digits before we're actually done, make
35.3651 - sure the carries get propagated upward...
35.3652 - */
35.3653 - for (used = MP_USED(a); ix < used; ++ix) {
35.3654 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3655 - w = w + *pa++;
35.3656 - *pc++ = ACCUM(w);
35.3657 - w = CARRYOUT(w);
35.3658 -#else
35.3659 - *pc++ = sum = carry + *pa++;
35.3660 - carry = (sum < carry);
35.3661 -#endif
35.3662 - }
35.3663 -
35.3664 - /* If there's an overall carry out, increase precision and include
35.3665 - it. We could have done this initially, but why touch the memory
35.3666 - allocator unless we're sure we have to?
35.3667 - */
35.3668 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3669 - if (w) {
35.3670 - if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
35.3671 - return res;
35.3672 -
35.3673 - DIGIT(c, used) = (mp_digit)w;
35.3674 - ++used;
35.3675 - }
35.3676 -#else
35.3677 - if (carry) {
35.3678 - if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
35.3679 - return res;
35.3680 -
35.3681 - DIGIT(c, used) = carry;
35.3682 - ++used;
35.3683 - }
35.3684 -#endif
35.3685 - MP_USED(c) = used;
35.3686 - return MP_OKAY;
35.3687 -}
35.3688 -/* {{{ s_mp_add_offset(a, b, offset) */
35.3689 -
35.3690 -/* Compute a = |a| + ( |b| * (RADIX ** offset) ) */
35.3691 -mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
35.3692 -{
35.3693 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3694 - mp_word w, k = 0;
35.3695 -#else
35.3696 - mp_digit d, sum, carry = 0;
35.3697 -#endif
35.3698 - mp_size ib;
35.3699 - mp_size ia;
35.3700 - mp_size lim;
35.3701 - mp_err res;
35.3702 -
35.3703 - /* Make sure a has enough precision for the output value */
35.3704 - lim = MP_USED(b) + offset;
35.3705 - if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)
35.3706 - return res;
35.3707 -
35.3708 - /*
35.3709 - Add up all digits up to the precision of b. If b had initially
35.3710 - the same precision as a, or greater, we took care of it by the
35.3711 - padding step above, so there is no problem. If b had initially
35.3712 - less precision, we'll have to make sure the carry out is duly
35.3713 - propagated upward among the higher-order digits of the sum.
35.3714 - */
35.3715 - lim = USED(b);
35.3716 - for(ib = 0, ia = offset; ib < lim; ib++, ia++) {
35.3717 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3718 - w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;
35.3719 - DIGIT(a, ia) = ACCUM(w);
35.3720 - k = CARRYOUT(w);
35.3721 -#else
35.3722 - d = MP_DIGIT(a, ia);
35.3723 - sum = d + MP_DIGIT(b, ib);
35.3724 - d = (sum < d);
35.3725 - MP_DIGIT(a,ia) = sum += carry;
35.3726 - carry = d + (sum < carry);
35.3727 -#endif
35.3728 - }
35.3729 -
35.3730 - /* If we run out of 'b' digits before we're actually done, make
35.3731 - sure the carries get propagated upward...
35.3732 - */
35.3733 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3734 - for (lim = MP_USED(a); k && (ia < lim); ++ia) {
35.3735 - w = (mp_word)DIGIT(a, ia) + k;
35.3736 - DIGIT(a, ia) = ACCUM(w);
35.3737 - k = CARRYOUT(w);
35.3738 - }
35.3739 -#else
35.3740 - for (lim = MP_USED(a); carry && (ia < lim); ++ia) {
35.3741 - d = MP_DIGIT(a, ia);
35.3742 - MP_DIGIT(a,ia) = sum = d + carry;
35.3743 - carry = (sum < d);
35.3744 - }
35.3745 -#endif
35.3746 -
35.3747 - /* If there's an overall carry out, increase precision and include
35.3748 - it. We could have done this initially, but why touch the memory
35.3749 - allocator unless we're sure we have to?
35.3750 - */
35.3751 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
35.3752 - if(k) {
35.3753 - if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
35.3754 - return res;
35.3755 -
35.3756 - DIGIT(a, ia) = (mp_digit)k;
35.3757 - }
35.3758 -#else
35.3759 - if (carry) {
35.3760 - if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
35.3761 - return res;
35.3762 -
35.3763 - DIGIT(a, lim) = carry;
35.3764 - }
35.3765 -#endif
35.3766 - s_mp_clamp(a);
35.3767 -
35.3768 - return MP_OKAY;
35.3769 -
35.3770 -} /* end s_mp_add_offset() */
35.3771 -
35.3772 -/* }}} */
35.3773 -
35.3774 -/* {{{ s_mp_sub(a, b) */
35.3775 -
35.3776 -/* Compute a = |a| - |b|, assumes |a| >= |b| */
35.3777 -mp_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */
35.3778 -{
35.3779 - mp_digit *pa, *pb, *limit;
35.3780 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3781 - mp_sword w = 0;
35.3782 -#else
35.3783 - mp_digit d, diff, borrow = 0;
35.3784 -#endif
35.3785 -
35.3786 - /*
35.3787 - Subtract and propagate borrow. Up to the precision of b, this
35.3788 - accounts for the digits of b; after that, we just make sure the
35.3789 - carries get to the right place. This saves having to pad b out to
35.3790 - the precision of a just to make the loops work right...
35.3791 - */
35.3792 - pa = MP_DIGITS(a);
35.3793 - pb = MP_DIGITS(b);
35.3794 - limit = pb + MP_USED(b);
35.3795 - while (pb < limit) {
35.3796 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3797 - w = w + *pa - *pb++;
35.3798 - *pa++ = ACCUM(w);
35.3799 - w >>= MP_DIGIT_BIT;
35.3800 -#else
35.3801 - d = *pa;
35.3802 - diff = d - *pb++;
35.3803 - d = (diff > d); /* detect borrow */
35.3804 - if (borrow && --diff == MP_DIGIT_MAX)
35.3805 - ++d;
35.3806 - *pa++ = diff;
35.3807 - borrow = d;
35.3808 -#endif
35.3809 - }
35.3810 - limit = MP_DIGITS(a) + MP_USED(a);
35.3811 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3812 - while (w && pa < limit) {
35.3813 - w = w + *pa;
35.3814 - *pa++ = ACCUM(w);
35.3815 - w >>= MP_DIGIT_BIT;
35.3816 - }
35.3817 -#else
35.3818 - while (borrow && pa < limit) {
35.3819 - d = *pa;
35.3820 - *pa++ = diff = d - borrow;
35.3821 - borrow = (diff > d);
35.3822 - }
35.3823 -#endif
35.3824 -
35.3825 - /* Clobber any leading zeroes we created */
35.3826 - s_mp_clamp(a);
35.3827 -
35.3828 - /*
35.3829 - If there was a borrow out, then |b| > |a| in violation
35.3830 - of our input invariant. We've already done the work,
35.3831 - but we'll at least complain about it...
35.3832 - */
35.3833 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3834 - return w ? MP_RANGE : MP_OKAY;
35.3835 -#else
35.3836 - return borrow ? MP_RANGE : MP_OKAY;
35.3837 -#endif
35.3838 -} /* end s_mp_sub() */
35.3839 -
35.3840 -/* }}} */
35.3841 -
35.3842 -/* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract */
35.3843 -mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
35.3844 -{
35.3845 - mp_digit *pa, *pb, *pc;
35.3846 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3847 - mp_sword w = 0;
35.3848 -#else
35.3849 - mp_digit d, diff, borrow = 0;
35.3850 -#endif
35.3851 - int ix, limit;
35.3852 - mp_err res;
35.3853 -
35.3854 - MP_SIGN(c) = MP_SIGN(a);
35.3855 -
35.3856 - /* Make sure a has enough precision for the output value */
35.3857 - if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
35.3858 - return res;
35.3859 -
35.3860 - /*
35.3861 - Subtract and propagate borrow. Up to the precision of b, this
35.3862 - accounts for the digits of b; after that, we just make sure the
35.3863 - carries get to the right place. This saves having to pad b out to
35.3864 - the precision of a just to make the loops work right...
35.3865 - */
35.3866 - pa = MP_DIGITS(a);
35.3867 - pb = MP_DIGITS(b);
35.3868 - pc = MP_DIGITS(c);
35.3869 - limit = MP_USED(b);
35.3870 - for (ix = 0; ix < limit; ++ix) {
35.3871 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3872 - w = w + *pa++ - *pb++;
35.3873 - *pc++ = ACCUM(w);
35.3874 - w >>= MP_DIGIT_BIT;
35.3875 -#else
35.3876 - d = *pa++;
35.3877 - diff = d - *pb++;
35.3878 - d = (diff > d);
35.3879 - if (borrow && --diff == MP_DIGIT_MAX)
35.3880 - ++d;
35.3881 - *pc++ = diff;
35.3882 - borrow = d;
35.3883 -#endif
35.3884 - }
35.3885 - for (limit = MP_USED(a); ix < limit; ++ix) {
35.3886 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3887 - w = w + *pa++;
35.3888 - *pc++ = ACCUM(w);
35.3889 - w >>= MP_DIGIT_BIT;
35.3890 -#else
35.3891 - d = *pa++;
35.3892 - *pc++ = diff = d - borrow;
35.3893 - borrow = (diff > d);
35.3894 -#endif
35.3895 - }
35.3896 -
35.3897 - /* Clobber any leading zeroes we created */
35.3898 - MP_USED(c) = ix;
35.3899 - s_mp_clamp(c);
35.3900 -
35.3901 - /*
35.3902 - If there was a borrow out, then |b| > |a| in violation
35.3903 - of our input invariant. We've already done the work,
35.3904 - but we'll at least complain about it...
35.3905 - */
35.3906 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
35.3907 - return w ? MP_RANGE : MP_OKAY;
35.3908 -#else
35.3909 - return borrow ? MP_RANGE : MP_OKAY;
35.3910 -#endif
35.3911 -}
35.3912 -/* {{{ s_mp_mul(a, b) */
35.3913 -
35.3914 -/* Compute a = |a| * |b| */
35.3915 -mp_err s_mp_mul(mp_int *a, const mp_int *b)
35.3916 -{
35.3917 - return mp_mul(a, b, a);
35.3918 -} /* end s_mp_mul() */
35.3919 -
35.3920 -/* }}} */
35.3921 -
35.3922 -#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
35.3923 -/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
35.3924 -#define MP_MUL_DxD(a, b, Phi, Plo) \
35.3925 - { unsigned long long product = (unsigned long long)a * b; \
35.3926 - Plo = (mp_digit)product; \
35.3927 - Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
35.3928 -#elif defined(OSF1)
35.3929 -#define MP_MUL_DxD(a, b, Phi, Plo) \
35.3930 - { Plo = asm ("mulq %a0, %a1, %v0", a, b);\
35.3931 - Phi = asm ("umulh %a0, %a1, %v0", a, b); }
35.3932 -#else
35.3933 -#define MP_MUL_DxD(a, b, Phi, Plo) \
35.3934 - { mp_digit a0b1, a1b0; \
35.3935 - Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \
35.3936 - Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \
35.3937 - a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \
35.3938 - a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
35.3939 - a1b0 += a0b1; \
35.3940 - Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
35.3941 - if (a1b0 < a0b1) \
35.3942 - Phi += MP_HALF_RADIX; \
35.3943 - a1b0 <<= MP_HALF_DIGIT_BIT; \
35.3944 - Plo += a1b0; \
35.3945 - if (Plo < a1b0) \
35.3946 - ++Phi; \
35.3947 - }
35.3948 -#endif
35.3949 -
35.3950 -#if !defined(MP_ASSEMBLY_MULTIPLY)
35.3951 -/* c = a * b */
35.3952 -void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
35.3953 -{
35.3954 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
35.3955 - mp_digit d = 0;
35.3956 -
35.3957 - /* Inner product: Digits of a */
35.3958 - while (a_len--) {
35.3959 - mp_word w = ((mp_word)b * *a++) + d;
35.3960 - *c++ = ACCUM(w);
35.3961 - d = CARRYOUT(w);
35.3962 - }
35.3963 - *c = d;
35.3964 -#else
35.3965 - mp_digit carry = 0;
35.3966 - while (a_len--) {
35.3967 - mp_digit a_i = *a++;
35.3968 - mp_digit a0b0, a1b1;
35.3969 -
35.3970 - MP_MUL_DxD(a_i, b, a1b1, a0b0);
35.3971 -
35.3972 - a0b0 += carry;
35.3973 - if (a0b0 < carry)
35.3974 - ++a1b1;
35.3975 - *c++ = a0b0;
35.3976 - carry = a1b1;
35.3977 - }
35.3978 - *c = carry;
35.3979 -#endif
35.3980 -}
35.3981 -
35.3982 -/* c += a * b */
35.3983 -void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
35.3984 - mp_digit *c)
35.3985 -{
35.3986 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
35.3987 - mp_digit d = 0;
35.3988 -
35.3989 - /* Inner product: Digits of a */
35.3990 - while (a_len--) {
35.3991 - mp_word w = ((mp_word)b * *a++) + *c + d;
35.3992 - *c++ = ACCUM(w);
35.3993 - d = CARRYOUT(w);
35.3994 - }
35.3995 - *c = d;
35.3996 -#else
35.3997 - mp_digit carry = 0;
35.3998 - while (a_len--) {
35.3999 - mp_digit a_i = *a++;
35.4000 - mp_digit a0b0, a1b1;
35.4001 -
35.4002 - MP_MUL_DxD(a_i, b, a1b1, a0b0);
35.4003 -
35.4004 - a0b0 += carry;
35.4005 - if (a0b0 < carry)
35.4006 - ++a1b1;
35.4007 - a0b0 += a_i = *c;
35.4008 - if (a0b0 < a_i)
35.4009 - ++a1b1;
35.4010 - *c++ = a0b0;
35.4011 - carry = a1b1;
35.4012 - }
35.4013 - *c = carry;
35.4014 -#endif
35.4015 -}
35.4016 -
35.4017 -/* Presently, this is only used by the Montgomery arithmetic code. */
35.4018 -/* c += a * b */
35.4019 -void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
35.4020 -{
35.4021 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
35.4022 - mp_digit d = 0;
35.4023 -
35.4024 - /* Inner product: Digits of a */
35.4025 - while (a_len--) {
35.4026 - mp_word w = ((mp_word)b * *a++) + *c + d;
35.4027 - *c++ = ACCUM(w);
35.4028 - d = CARRYOUT(w);
35.4029 - }
35.4030 -
35.4031 - while (d) {
35.4032 - mp_word w = (mp_word)*c + d;
35.4033 - *c++ = ACCUM(w);
35.4034 - d = CARRYOUT(w);
35.4035 - }
35.4036 -#else
35.4037 - mp_digit carry = 0;
35.4038 - while (a_len--) {
35.4039 - mp_digit a_i = *a++;
35.4040 - mp_digit a0b0, a1b1;
35.4041 -
35.4042 - MP_MUL_DxD(a_i, b, a1b1, a0b0);
35.4043 -
35.4044 - a0b0 += carry;
35.4045 - if (a0b0 < carry)
35.4046 - ++a1b1;
35.4047 -
35.4048 - a0b0 += a_i = *c;
35.4049 - if (a0b0 < a_i)
35.4050 - ++a1b1;
35.4051 -
35.4052 - *c++ = a0b0;
35.4053 - carry = a1b1;
35.4054 - }
35.4055 - while (carry) {
35.4056 - mp_digit c_i = *c;
35.4057 - carry += c_i;
35.4058 - *c++ = carry;
35.4059 - carry = carry < c_i;
35.4060 - }
35.4061 -#endif
35.4062 -}
35.4063 -#endif
35.4064 -
35.4065 -#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
35.4066 -/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
35.4067 -#define MP_SQR_D(a, Phi, Plo) \
35.4068 - { unsigned long long square = (unsigned long long)a * a; \
35.4069 - Plo = (mp_digit)square; \
35.4070 - Phi = (mp_digit)(square >> MP_DIGIT_BIT); }
35.4071 -#elif defined(OSF1)
35.4072 -#define MP_SQR_D(a, Phi, Plo) \
35.4073 - { Plo = asm ("mulq %a0, %a0, %v0", a);\
35.4074 - Phi = asm ("umulh %a0, %a0, %v0", a); }
35.4075 -#else
35.4076 -#define MP_SQR_D(a, Phi, Plo) \
35.4077 - { mp_digit Pmid; \
35.4078 - Plo = (a & MP_HALF_DIGIT_MAX) * (a & MP_HALF_DIGIT_MAX); \
35.4079 - Phi = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \
35.4080 - Pmid = (a & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \
35.4081 - Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1); \
35.4082 - Pmid <<= (MP_HALF_DIGIT_BIT + 1); \
35.4083 - Plo += Pmid; \
35.4084 - if (Plo < Pmid) \
35.4085 - ++Phi; \
35.4086 - }
35.4087 -#endif
35.4088 -
35.4089 -#if !defined(MP_ASSEMBLY_SQUARE)
35.4090 -/* Add the squares of the digits of a to the digits of b. */
35.4091 -void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
35.4092 -{
35.4093 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
35.4094 - mp_word w;
35.4095 - mp_digit d;
35.4096 - mp_size ix;
35.4097 -
35.4098 - w = 0;
35.4099 -#define ADD_SQUARE(n) \
35.4100 - d = pa[n]; \
35.4101 - w += (d * (mp_word)d) + ps[2*n]; \
35.4102 - ps[2*n] = ACCUM(w); \
35.4103 - w = (w >> DIGIT_BIT) + ps[2*n+1]; \
35.4104 - ps[2*n+1] = ACCUM(w); \
35.4105 - w = (w >> DIGIT_BIT)
35.4106 -
35.4107 - for (ix = a_len; ix >= 4; ix -= 4) {
35.4108 - ADD_SQUARE(0);
35.4109 - ADD_SQUARE(1);
35.4110 - ADD_SQUARE(2);
35.4111 - ADD_SQUARE(3);
35.4112 - pa += 4;
35.4113 - ps += 8;
35.4114 - }
35.4115 - if (ix) {
35.4116 - ps += 2*ix;
35.4117 - pa += ix;
35.4118 - switch (ix) {
35.4119 - case 3: ADD_SQUARE(-3); /* FALLTHRU */
35.4120 - case 2: ADD_SQUARE(-2); /* FALLTHRU */
35.4121 - case 1: ADD_SQUARE(-1); /* FALLTHRU */
35.4122 - case 0: break;
35.4123 - }
35.4124 - }
35.4125 - while (w) {
35.4126 - w += *ps;
35.4127 - *ps++ = ACCUM(w);
35.4128 - w = (w >> DIGIT_BIT);
35.4129 - }
35.4130 -#else
35.4131 - mp_digit carry = 0;
35.4132 - while (a_len--) {
35.4133 - mp_digit a_i = *pa++;
35.4134 - mp_digit a0a0, a1a1;
35.4135 -
35.4136 - MP_SQR_D(a_i, a1a1, a0a0);
35.4137 -
35.4138 - /* here a1a1 and a0a0 constitute a_i ** 2 */
35.4139 - a0a0 += carry;
35.4140 - if (a0a0 < carry)
35.4141 - ++a1a1;
35.4142 -
35.4143 - /* now add to ps */
35.4144 - a0a0 += a_i = *ps;
35.4145 - if (a0a0 < a_i)
35.4146 - ++a1a1;
35.4147 - *ps++ = a0a0;
35.4148 - a1a1 += a_i = *ps;
35.4149 - carry = (a1a1 < a_i);
35.4150 - *ps++ = a1a1;
35.4151 - }
35.4152 - while (carry) {
35.4153 - mp_digit s_i = *ps;
35.4154 - carry += s_i;
35.4155 - *ps++ = carry;
35.4156 - carry = carry < s_i;
35.4157 - }
35.4158 -#endif
35.4159 -}
35.4160 -#endif
35.4161 -
35.4162 -#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \
35.4163 -&& !defined(MP_ASSEMBLY_DIV_2DX1D)
35.4164 -/*
35.4165 -** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
35.4166 -** so its high bit is 1. This code is from NSPR.
35.4167 -*/
35.4168 -mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
35.4169 - mp_digit *qp, mp_digit *rp)
35.4170 -{
35.4171 - mp_digit d1, d0, q1, q0;
35.4172 - mp_digit r1, r0, m;
35.4173 -
35.4174 - d1 = divisor >> MP_HALF_DIGIT_BIT;
35.4175 - d0 = divisor & MP_HALF_DIGIT_MAX;
35.4176 - r1 = Nhi % d1;
35.4177 - q1 = Nhi / d1;
35.4178 - m = q1 * d0;
35.4179 - r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);
35.4180 - if (r1 < m) {
35.4181 - q1--, r1 += divisor;
35.4182 - if (r1 >= divisor && r1 < m) {
35.4183 - q1--, r1 += divisor;
35.4184 - }
35.4185 - }
35.4186 - r1 -= m;
35.4187 - r0 = r1 % d1;
35.4188 - q0 = r1 / d1;
35.4189 - m = q0 * d0;
35.4190 - r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);
35.4191 - if (r0 < m) {
35.4192 - q0--, r0 += divisor;
35.4193 - if (r0 >= divisor && r0 < m) {
35.4194 - q0--, r0 += divisor;
35.4195 - }
35.4196 - }
35.4197 - if (qp)
35.4198 - *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
35.4199 - if (rp)
35.4200 - *rp = r0 - m;
35.4201 - return MP_OKAY;
35.4202 -}
35.4203 -#endif
35.4204 -
35.4205 -#if MP_SQUARE
35.4206 -/* {{{ s_mp_sqr(a) */
35.4207 -
35.4208 -mp_err s_mp_sqr(mp_int *a)
35.4209 -{
35.4210 - mp_err res;
35.4211 - mp_int tmp;
35.4212 -
35.4213 - if((res = mp_init_size(&tmp, 2 * USED(a), FLAG(a))) != MP_OKAY)
35.4214 - return res;
35.4215 - res = mp_sqr(a, &tmp);
35.4216 - if (res == MP_OKAY) {
35.4217 - s_mp_exch(&tmp, a);
35.4218 - }
35.4219 - mp_clear(&tmp);
35.4220 - return res;
35.4221 -}
35.4222 -
35.4223 -/* }}} */
35.4224 -#endif
35.4225 -
35.4226 -/* {{{ s_mp_div(a, b) */
35.4227 -
35.4228 -/*
35.4229 - s_mp_div(a, b)
35.4230 -
35.4231 - Compute a = a / b and b = a mod b. Assumes b > a.
35.4232 - */
35.4233 -
35.4234 -mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
35.4235 - mp_int *div, /* i: divisor */
35.4236 - mp_int *quot) /* i: 0; o: quotient */
35.4237 -{
35.4238 - mp_int part, t;
35.4239 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
35.4240 - mp_word q_msd;
35.4241 -#else
35.4242 - mp_digit q_msd;
35.4243 -#endif
35.4244 - mp_err res;
35.4245 - mp_digit d;
35.4246 - mp_digit div_msd;
35.4247 - int ix;
35.4248 -
35.4249 - if(mp_cmp_z(div) == 0)
35.4250 - return MP_RANGE;
35.4251 -
35.4252 - /* Shortcut if divisor is power of two */
35.4253 - if((ix = s_mp_ispow2(div)) >= 0) {
35.4254 - MP_CHECKOK( mp_copy(rem, quot) );
35.4255 - s_mp_div_2d(quot, (mp_digit)ix);
35.4256 - s_mp_mod_2d(rem, (mp_digit)ix);
35.4257 -
35.4258 - return MP_OKAY;
35.4259 - }
35.4260 -
35.4261 - DIGITS(&t) = 0;
35.4262 - MP_SIGN(rem) = ZPOS;
35.4263 - MP_SIGN(div) = ZPOS;
35.4264 -
35.4265 - /* A working temporary for division */
35.4266 - MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem), FLAG(rem)));
35.4267 -
35.4268 - /* Normalize to optimize guessing */
35.4269 - MP_CHECKOK( s_mp_norm(rem, div, &d) );
35.4270 -
35.4271 - part = *rem;
35.4272 -
35.4273 - /* Perform the division itself...woo! */
35.4274 - MP_USED(quot) = MP_ALLOC(quot);
35.4275 -
35.4276 - /* Find a partial substring of rem which is at least div */
35.4277 - /* If we didn't find one, we're finished dividing */
35.4278 - while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
35.4279 - int i;
35.4280 - int unusedRem;
35.4281 -
35.4282 - unusedRem = MP_USED(rem) - MP_USED(div);
35.4283 - MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
35.4284 - MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem;
35.4285 - MP_USED(&part) = MP_USED(div);
35.4286 - if (s_mp_cmp(&part, div) < 0) {
35.4287 - -- unusedRem;
35.4288 -#if MP_ARGCHK == 2
35.4289 - assert(unusedRem >= 0);
35.4290 -#endif
35.4291 - -- MP_DIGITS(&part);
35.4292 - ++ MP_USED(&part);
35.4293 - ++ MP_ALLOC(&part);
35.4294 - }
35.4295 -
35.4296 - /* Compute a guess for the next quotient digit */
35.4297 - q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
35.4298 - div_msd = MP_DIGIT(div, MP_USED(div) - 1);
35.4299 - if (q_msd >= div_msd) {
35.4300 - q_msd = 1;
35.4301 - } else if (MP_USED(&part) > 1) {
35.4302 -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
35.4303 - q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
35.4304 - q_msd /= div_msd;
35.4305 - if (q_msd == RADIX)
35.4306 - --q_msd;
35.4307 -#else
35.4308 - mp_digit r;
35.4309 - MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
35.4310 - div_msd, &q_msd, &r) );
35.4311 -#endif
35.4312 - } else {
35.4313 - q_msd = 0;
35.4314 - }
35.4315 -#if MP_ARGCHK == 2
35.4316 - assert(q_msd > 0); /* This case should never occur any more. */
35.4317 -#endif
35.4318 - if (q_msd <= 0)
35.4319 - break;
35.4320 -
35.4321 - /* See what that multiplies out to */
35.4322 - mp_copy(div, &t);
35.4323 - MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );
35.4324 -
35.4325 - /*
35.4326 - If it's too big, back it off. We should not have to do this
35.4327 - more than once, or, in rare cases, twice. Knuth describes a
35.4328 - method by which this could be reduced to a maximum of once, but
35.4329 - I didn't implement that here.
35.4330 - * When using s_mpv_div_2dx1d, we may have to do this 3 times.
35.4331 - */
35.4332 - for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
35.4333 - --q_msd;
35.4334 - s_mp_sub(&t, div); /* t -= div */
35.4335 - }
35.4336 - if (i < 0) {
35.4337 - res = MP_RANGE;
35.4338 - goto CLEANUP;
35.4339 - }
35.4340 -
35.4341 - /* At this point, q_msd should be the right next digit */
35.4342 - MP_CHECKOK( s_mp_sub(&part, &t) ); /* part -= t */
35.4343 - s_mp_clamp(rem);
35.4344 -
35.4345 - /*
35.4346 - Include the digit in the quotient. We allocated enough memory
35.4347 - for any quotient we could ever possibly get, so we should not
35.4348 - have to check for failures here
35.4349 - */
35.4350 - MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
35.4351 - }
35.4352 -
35.4353 - /* Denormalize remainder */
35.4354 - if (d) {
35.4355 - s_mp_div_2d(rem, d);
35.4356 - }
35.4357 -
35.4358 - s_mp_clamp(quot);
35.4359 -
35.4360 -CLEANUP:
35.4361 - mp_clear(&t);
35.4362 -
35.4363 - return res;
35.4364 -
35.4365 -} /* end s_mp_div() */
35.4366 -
35.4367 -
35.4368 -/* }}} */
35.4369 -
35.4370 -/* {{{ s_mp_2expt(a, k) */
35.4371 -
35.4372 -mp_err s_mp_2expt(mp_int *a, mp_digit k)
35.4373 -{
35.4374 - mp_err res;
35.4375 - mp_size dig, bit;
35.4376 -
35.4377 - dig = k / DIGIT_BIT;
35.4378 - bit = k % DIGIT_BIT;
35.4379 -
35.4380 - mp_zero(a);
35.4381 - if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
35.4382 - return res;
35.4383 -
35.4384 - DIGIT(a, dig) |= ((mp_digit)1 << bit);
35.4385 -
35.4386 - return MP_OKAY;
35.4387 -
35.4388 -} /* end s_mp_2expt() */
35.4389 -
35.4390 -/* }}} */
35.4391 -
35.4392 -/* {{{ s_mp_reduce(x, m, mu) */
35.4393 -
35.4394 -/*
35.4395 - Compute Barrett reduction, x (mod m), given a precomputed value for
35.4396 - mu = b^2k / m, where b = RADIX and k = #digits(m). This should be
35.4397 - faster than straight division, when many reductions by the same
35.4398 - value of m are required (such as in modular exponentiation). This
35.4399 - can nearly halve the time required to do modular exponentiation,
35.4400 - as compared to using the full integer divide to reduce.
35.4401 -
35.4402 - This algorithm was derived from the _Handbook of Applied
35.4403 - Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
35.4404 - pp. 603-604.
35.4405 - */
35.4406 -
35.4407 -mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
35.4408 -{
35.4409 - mp_int q;
35.4410 - mp_err res;
35.4411 -
35.4412 - if((res = mp_init_copy(&q, x)) != MP_OKAY)
35.4413 - return res;
35.4414 -
35.4415 - s_mp_rshd(&q, USED(m) - 1); /* q1 = x / b^(k-1) */
35.4416 - s_mp_mul(&q, mu); /* q2 = q1 * mu */
35.4417 - s_mp_rshd(&q, USED(m) + 1); /* q3 = q2 / b^(k+1) */
35.4418 -
35.4419 - /* x = x mod b^(k+1), quick (no division) */
35.4420 - s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));
35.4421 -
35.4422 - /* q = q * m mod b^(k+1), quick (no division) */
35.4423 - s_mp_mul(&q, m);
35.4424 - s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));
35.4425 -
35.4426 - /* x = x - q */
35.4427 - if((res = mp_sub(x, &q, x)) != MP_OKAY)
35.4428 - goto CLEANUP;
35.4429 -
35.4430 - /* If x < 0, add b^(k+1) to it */
35.4431 - if(mp_cmp_z(x) < 0) {
35.4432 - mp_set(&q, 1);
35.4433 - if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)
35.4434 - goto CLEANUP;
35.4435 - if((res = mp_add(x, &q, x)) != MP_OKAY)
35.4436 - goto CLEANUP;
35.4437 - }
35.4438 -
35.4439 - /* Back off if it's too big */
35.4440 - while(mp_cmp(x, m) >= 0) {
35.4441 - if((res = s_mp_sub(x, m)) != MP_OKAY)
35.4442 - break;
35.4443 - }
35.4444 -
35.4445 - CLEANUP:
35.4446 - mp_clear(&q);
35.4447 -
35.4448 - return res;
35.4449 -
35.4450 -} /* end s_mp_reduce() */
35.4451 -
35.4452 -/* }}} */
35.4453 -
35.4454 -/* }}} */
35.4455 -
35.4456 -/* {{{ Primitive comparisons */
35.4457 -
35.4458 -/* {{{ s_mp_cmp(a, b) */
35.4459 -
35.4460 -/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */
35.4461 -int s_mp_cmp(const mp_int *a, const mp_int *b)
35.4462 -{
35.4463 - mp_size used_a = MP_USED(a);
35.4464 - {
35.4465 - mp_size used_b = MP_USED(b);
35.4466 -
35.4467 - if (used_a > used_b)
35.4468 - goto IS_GT;
35.4469 - if (used_a < used_b)
35.4470 - goto IS_LT;
35.4471 - }
35.4472 - {
35.4473 - mp_digit *pa, *pb;
35.4474 - mp_digit da = 0, db = 0;
35.4475 -
35.4476 -#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done
35.4477 -
35.4478 - pa = MP_DIGITS(a) + used_a;
35.4479 - pb = MP_DIGITS(b) + used_a;
35.4480 - while (used_a >= 4) {
35.4481 - pa -= 4;
35.4482 - pb -= 4;
35.4483 - used_a -= 4;
35.4484 - CMP_AB(3);
35.4485 - CMP_AB(2);
35.4486 - CMP_AB(1);
35.4487 - CMP_AB(0);
35.4488 - }
35.4489 - while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))
35.4490 - /* do nothing */;
35.4491 -done:
35.4492 - if (da > db)
35.4493 - goto IS_GT;
35.4494 - if (da < db)
35.4495 - goto IS_LT;
35.4496 - }
35.4497 - return MP_EQ;
35.4498 -IS_LT:
35.4499 - return MP_LT;
35.4500 -IS_GT:
35.4501 - return MP_GT;
35.4502 -} /* end s_mp_cmp() */
35.4503 -
35.4504 -/* }}} */
35.4505 -
35.4506 -/* {{{ s_mp_cmp_d(a, d) */
35.4507 -
35.4508 -/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */
35.4509 -int s_mp_cmp_d(const mp_int *a, mp_digit d)
35.4510 -{
35.4511 - if(USED(a) > 1)
35.4512 - return MP_GT;
35.4513 -
35.4514 - if(DIGIT(a, 0) < d)
35.4515 - return MP_LT;
35.4516 - else if(DIGIT(a, 0) > d)
35.4517 - return MP_GT;
35.4518 - else
35.4519 - return MP_EQ;
35.4520 -
35.4521 -} /* end s_mp_cmp_d() */
35.4522 -
35.4523 -/* }}} */
35.4524 -
35.4525 -/* {{{ s_mp_ispow2(v) */
35.4526 -
35.4527 -/*
35.4528 - Returns -1 if the value is not a power of two; otherwise, it returns
35.4529 - k such that v = 2^k, i.e. lg(v).
35.4530 - */
35.4531 -int s_mp_ispow2(const mp_int *v)
35.4532 -{
35.4533 - mp_digit d;
35.4534 - int extra = 0, ix;
35.4535 -
35.4536 - ix = MP_USED(v) - 1;
35.4537 - d = MP_DIGIT(v, ix); /* most significant digit of v */
35.4538 -
35.4539 - extra = s_mp_ispow2d(d);
35.4540 - if (extra < 0 || ix == 0)
35.4541 - return extra;
35.4542 -
35.4543 - while (--ix >= 0) {
35.4544 - if (DIGIT(v, ix) != 0)
35.4545 - return -1; /* not a power of two */
35.4546 - extra += MP_DIGIT_BIT;
35.4547 - }
35.4548 -
35.4549 - return extra;
35.4550 -
35.4551 -} /* end s_mp_ispow2() */
35.4552 -
35.4553 -/* }}} */
35.4554 -
35.4555 -/* {{{ s_mp_ispow2d(d) */
35.4556 -
35.4557 -int s_mp_ispow2d(mp_digit d)
35.4558 -{
35.4559 - if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */
35.4560 - int pow = 0;
35.4561 -#if defined (MP_USE_UINT_DIGIT)
35.4562 - if (d & 0xffff0000U)
35.4563 - pow += 16;
35.4564 - if (d & 0xff00ff00U)
35.4565 - pow += 8;
35.4566 - if (d & 0xf0f0f0f0U)
35.4567 - pow += 4;
35.4568 - if (d & 0xccccccccU)
35.4569 - pow += 2;
35.4570 - if (d & 0xaaaaaaaaU)
35.4571 - pow += 1;
35.4572 -#elif defined(MP_USE_LONG_LONG_DIGIT)
35.4573 - if (d & 0xffffffff00000000ULL)
35.4574 - pow += 32;
35.4575 - if (d & 0xffff0000ffff0000ULL)
35.4576 - pow += 16;
35.4577 - if (d & 0xff00ff00ff00ff00ULL)
35.4578 - pow += 8;
35.4579 - if (d & 0xf0f0f0f0f0f0f0f0ULL)
35.4580 - pow += 4;
35.4581 - if (d & 0xccccccccccccccccULL)
35.4582 - pow += 2;
35.4583 - if (d & 0xaaaaaaaaaaaaaaaaULL)
35.4584 - pow += 1;
35.4585 -#elif defined(MP_USE_LONG_DIGIT)
35.4586 - if (d & 0xffffffff00000000UL)
35.4587 - pow += 32;
35.4588 - if (d & 0xffff0000ffff0000UL)
35.4589 - pow += 16;
35.4590 - if (d & 0xff00ff00ff00ff00UL)
35.4591 - pow += 8;
35.4592 - if (d & 0xf0f0f0f0f0f0f0f0UL)
35.4593 - pow += 4;
35.4594 - if (d & 0xccccccccccccccccUL)
35.4595 - pow += 2;
35.4596 - if (d & 0xaaaaaaaaaaaaaaaaUL)
35.4597 - pow += 1;
35.4598 -#else
35.4599 -#error "unknown type for mp_digit"
35.4600 -#endif
35.4601 - return pow;
35.4602 - }
35.4603 - return -1;
35.4604 -
35.4605 -} /* end s_mp_ispow2d() */
35.4606 -
35.4607 -/* }}} */
35.4608 -
35.4609 -/* }}} */
35.4610 -
35.4611 -/* {{{ Primitive I/O helpers */
35.4612 -
35.4613 -/* {{{ s_mp_tovalue(ch, r) */
35.4614 -
35.4615 -/*
35.4616 - Convert the given character to its digit value, in the given radix.
35.4617 - If the given character is not understood in the given radix, -1 is
35.4618 - returned. Otherwise the digit's numeric value is returned.
35.4619 -
35.4620 - The results will be odd if you use a radix < 2 or > 62, you are
35.4621 - expected to know what you're up to.
35.4622 - */
35.4623 -int s_mp_tovalue(char ch, int r)
35.4624 -{
35.4625 - int val, xch;
35.4626 -
35.4627 - if(r > 36)
35.4628 - xch = ch;
35.4629 - else
35.4630 - xch = toupper(ch);
35.4631 -
35.4632 - if(isdigit(xch))
35.4633 - val = xch - '0';
35.4634 - else if(isupper(xch))
35.4635 - val = xch - 'A' + 10;
35.4636 - else if(islower(xch))
35.4637 - val = xch - 'a' + 36;
35.4638 - else if(xch == '+')
35.4639 - val = 62;
35.4640 - else if(xch == '/')
35.4641 - val = 63;
35.4642 - else
35.4643 - return -1;
35.4644 -
35.4645 - if(val < 0 || val >= r)
35.4646 - return -1;
35.4647 -
35.4648 - return val;
35.4649 -
35.4650 -} /* end s_mp_tovalue() */
35.4651 -
35.4652 -/* }}} */
35.4653 -
35.4654 -/* {{{ s_mp_todigit(val, r, low) */
35.4655 -
35.4656 -/*
35.4657 - Convert val to a radix-r digit, if possible. If val is out of range
35.4658 - for r, returns zero. Otherwise, returns an ASCII character denoting
35.4659 - the value in the given radix.
35.4660 -
35.4661 - The results may be odd if you use a radix < 2 or > 64, you are
35.4662 - expected to know what you're doing.
35.4663 - */
35.4664 -
35.4665 -char s_mp_todigit(mp_digit val, int r, int low)
35.4666 -{
35.4667 - char ch;
35.4668 -
35.4669 - if(val >= r)
35.4670 - return 0;
35.4671 -
35.4672 - ch = s_dmap_1[val];
35.4673 -
35.4674 - if(r <= 36 && low)
35.4675 - ch = tolower(ch);
35.4676 -
35.4677 - return ch;
35.4678 -
35.4679 -} /* end s_mp_todigit() */
35.4680 -
35.4681 -/* }}} */
35.4682 -
35.4683 -/* {{{ s_mp_outlen(bits, radix) */
35.4684 -
35.4685 -/*
35.4686 - Return an estimate for how long a string is needed to hold a radix
35.4687 - r representation of a number with 'bits' significant bits, plus an
35.4688 - extra for a zero terminator (assuming C style strings here)
35.4689 - */
35.4690 -int s_mp_outlen(int bits, int r)
35.4691 -{
35.4692 - return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
35.4693 -
35.4694 -} /* end s_mp_outlen() */
35.4695 -
35.4696 -/* }}} */
35.4697 -
35.4698 -/* }}} */
35.4699 -
35.4700 -/* {{{ mp_read_unsigned_octets(mp, str, len) */
35.4701 -/* mp_read_unsigned_octets(mp, str, len)
35.4702 - Read in a raw value (base 256) into the given mp_int
35.4703 - No sign bit, number is positive. Leading zeros ignored.
35.4704 - */
35.4705 -
35.4706 -mp_err
35.4707 -mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
35.4708 -{
35.4709 - int count;
35.4710 - mp_err res;
35.4711 - mp_digit d;
35.4712 -
35.4713 - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
35.4714 -
35.4715 - mp_zero(mp);
35.4716 -
35.4717 - count = len % sizeof(mp_digit);
35.4718 - if (count) {
35.4719 - for (d = 0; count-- > 0; --len) {
35.4720 - d = (d << 8) | *str++;
35.4721 - }
35.4722 - MP_DIGIT(mp, 0) = d;
35.4723 - }
35.4724 -
35.4725 - /* Read the rest of the digits */
35.4726 - for(; len > 0; len -= sizeof(mp_digit)) {
35.4727 - for (d = 0, count = sizeof(mp_digit); count > 0; --count) {
35.4728 - d = (d << 8) | *str++;
35.4729 - }
35.4730 - if (MP_EQ == mp_cmp_z(mp)) {
35.4731 - if (!d)
35.4732 - continue;
35.4733 - } else {
35.4734 - if((res = s_mp_lshd(mp, 1)) != MP_OKAY)
35.4735 - return res;
35.4736 - }
35.4737 - MP_DIGIT(mp, 0) = d;
35.4738 - }
35.4739 - return MP_OKAY;
35.4740 -} /* end mp_read_unsigned_octets() */
35.4741 -/* }}} */
35.4742 -
35.4743 -/* {{{ mp_unsigned_octet_size(mp) */
35.4744 -int
35.4745 -mp_unsigned_octet_size(const mp_int *mp)
35.4746 -{
35.4747 - int bytes;
35.4748 - int ix;
35.4749 - mp_digit d = 0;
35.4750 -
35.4751 - ARGCHK(mp != NULL, MP_BADARG);
35.4752 - ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);
35.4753 -
35.4754 - bytes = (USED(mp) * sizeof(mp_digit));
35.4755 -
35.4756 - /* subtract leading zeros. */
35.4757 - /* Iterate over each digit... */
35.4758 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.4759 - d = DIGIT(mp, ix);
35.4760 - if (d)
35.4761 - break;
35.4762 - bytes -= sizeof(d);
35.4763 - }
35.4764 - if (!bytes)
35.4765 - return 1;
35.4766 -
35.4767 - /* Have MSD, check digit bytes, high order first */
35.4768 - for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {
35.4769 - unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));
35.4770 - if (x)
35.4771 - break;
35.4772 - --bytes;
35.4773 - }
35.4774 - return bytes;
35.4775 -} /* end mp_unsigned_octet_size() */
35.4776 -/* }}} */
35.4777 -
35.4778 -/* {{{ mp_to_unsigned_octets(mp, str) */
35.4779 -/* output a buffer of big endian octets no longer than specified. */
35.4780 -mp_err
35.4781 -mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
35.4782 -{
35.4783 - int ix, pos = 0;
35.4784 - int bytes;
35.4785 -
35.4786 - ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
35.4787 -
35.4788 - bytes = mp_unsigned_octet_size(mp);
35.4789 - ARGCHK(bytes <= maxlen, MP_BADARG);
35.4790 -
35.4791 - /* Iterate over each digit... */
35.4792 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.4793 - mp_digit d = DIGIT(mp, ix);
35.4794 - int jx;
35.4795 -
35.4796 - /* Unpack digit bytes, high order first */
35.4797 - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
35.4798 - unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
35.4799 - if (!pos && !x) /* suppress leading zeros */
35.4800 - continue;
35.4801 - str[pos++] = x;
35.4802 - }
35.4803 - }
35.4804 - if (!pos)
35.4805 - str[pos++] = 0;
35.4806 - return pos;
35.4807 -} /* end mp_to_unsigned_octets() */
35.4808 -/* }}} */
35.4809 -
35.4810 -/* {{{ mp_to_signed_octets(mp, str) */
35.4811 -/* output a buffer of big endian octets no longer than specified. */
35.4812 -mp_err
35.4813 -mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
35.4814 -{
35.4815 - int ix, pos = 0;
35.4816 - int bytes;
35.4817 -
35.4818 - ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
35.4819 -
35.4820 - bytes = mp_unsigned_octet_size(mp);
35.4821 - ARGCHK(bytes <= maxlen, MP_BADARG);
35.4822 -
35.4823 - /* Iterate over each digit... */
35.4824 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.4825 - mp_digit d = DIGIT(mp, ix);
35.4826 - int jx;
35.4827 -
35.4828 - /* Unpack digit bytes, high order first */
35.4829 - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
35.4830 - unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
35.4831 - if (!pos) {
35.4832 - if (!x) /* suppress leading zeros */
35.4833 - continue;
35.4834 - if (x & 0x80) { /* add one leading zero to make output positive. */
35.4835 - ARGCHK(bytes + 1 <= maxlen, MP_BADARG);
35.4836 - if (bytes + 1 > maxlen)
35.4837 - return MP_BADARG;
35.4838 - str[pos++] = 0;
35.4839 - }
35.4840 - }
35.4841 - str[pos++] = x;
35.4842 - }
35.4843 - }
35.4844 - if (!pos)
35.4845 - str[pos++] = 0;
35.4846 - return pos;
35.4847 -} /* end mp_to_signed_octets() */
35.4848 -/* }}} */
35.4849 -
35.4850 -/* {{{ mp_to_fixlen_octets(mp, str) */
35.4851 -/* output a buffer of big endian octets exactly as long as requested. */
35.4852 -mp_err
35.4853 -mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
35.4854 -{
35.4855 - int ix, pos = 0;
35.4856 - int bytes;
35.4857 -
35.4858 - ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
35.4859 -
35.4860 - bytes = mp_unsigned_octet_size(mp);
35.4861 - ARGCHK(bytes <= length, MP_BADARG);
35.4862 -
35.4863 - /* place any needed leading zeros */
35.4864 - for (;length > bytes; --length) {
35.4865 - *str++ = 0;
35.4866 - }
35.4867 -
35.4868 - /* Iterate over each digit... */
35.4869 - for(ix = USED(mp) - 1; ix >= 0; ix--) {
35.4870 - mp_digit d = DIGIT(mp, ix);
35.4871 - int jx;
35.4872 -
35.4873 - /* Unpack digit bytes, high order first */
35.4874 - for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
35.4875 - unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
35.4876 - if (!pos && !x) /* suppress leading zeros */
35.4877 - continue;
35.4878 - str[pos++] = x;
35.4879 - }
35.4880 - }
35.4881 - if (!pos)
35.4882 - str[pos++] = 0;
35.4883 - return MP_OKAY;
35.4884 -} /* end mp_to_fixlen_octets() */
35.4885 -/* }}} */
35.4886 -
35.4887 -
35.4888 -/*------------------------------------------------------------------------*/
35.4889 -/* HERE THERE BE DRAGONS */
36.1 --- a/src/share/native/sun/security/ec/mpi.h Tue Oct 13 15:25:58 2009 -0700
36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
36.3 @@ -1,409 +0,0 @@
36.4 -/* *********************************************************************
36.5 - *
36.6 - * Sun elects to have this file available under and governed by the
36.7 - * Mozilla Public License Version 1.1 ("MPL") (see
36.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
36.9 - * of doubt and subject to the following, Sun also elects to allow
36.10 - * licensees to use this file under the MPL, the GNU General Public
36.11 - * License version 2 only or the Lesser General Public License version
36.12 - * 2.1 only. Any references to the "GNU General Public License version 2
36.13 - * or later" or "GPL" in the following shall be construed to mean the
36.14 - * GNU General Public License version 2 only. Any references to the "GNU
36.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
36.16 - * following shall be construed to mean the GNU Lesser General Public
36.17 - * License version 2.1 only. However, the following notice accompanied
36.18 - * the original version of this file:
36.19 - *
36.20 - *
36.21 - * Arbitrary precision integer arithmetic library
36.22 - *
36.23 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
36.24 - *
36.25 - * The contents of this file are subject to the Mozilla Public License Version
36.26 - * 1.1 (the "License"); you may not use this file except in compliance with
36.27 - * the License. You may obtain a copy of the License at
36.28 - * http://www.mozilla.org/MPL/
36.29 - *
36.30 - * Software distributed under the License is distributed on an "AS IS" basis,
36.31 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
36.32 - * for the specific language governing rights and limitations under the
36.33 - * License.
36.34 - *
36.35 - * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
36.36 - *
36.37 - * The Initial Developer of the Original Code is
36.38 - * Michael J. Fromberger.
36.39 - * Portions created by the Initial Developer are Copyright (C) 1998
36.40 - * the Initial Developer. All Rights Reserved.
36.41 - *
36.42 - * Contributor(s):
36.43 - * Netscape Communications Corporation
36.44 - *
36.45 - * Alternatively, the contents of this file may be used under the terms of
36.46 - * either the GNU General Public License Version 2 or later (the "GPL"), or
36.47 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
36.48 - * in which case the provisions of the GPL or the LGPL are applicable instead
36.49 - * of those above. If you wish to allow use of your version of this file only
36.50 - * under the terms of either the GPL or the LGPL, and not to allow others to
36.51 - * use your version of this file under the terms of the MPL, indicate your
36.52 - * decision by deleting the provisions above and replace them with the notice
36.53 - * and other provisions required by the GPL or the LGPL. If you do not delete
36.54 - * the provisions above, a recipient may use your version of this file under
36.55 - * the terms of any one of the MPL, the GPL or the LGPL.
36.56 - *
36.57 - *********************************************************************** */
36.58 -/*
36.59 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
36.60 - * Use is subject to license terms.
36.61 - */
36.62 -
36.63 -#ifndef _MPI_H
36.64 -#define _MPI_H
36.65 -
36.66 -#pragma ident "%Z%%M% %I% %E% SMI"
36.67 -
36.68 -/* $Id: mpi.h,v 1.22 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
36.69 -
36.70 -#include "mpi-config.h"
36.71 -
36.72 -#ifndef _WIN32
36.73 -#include <sys/param.h>
36.74 -#endif /* _WIN32 */
36.75 -
36.76 -#ifdef _KERNEL
36.77 -#include <sys/debug.h>
36.78 -#include <sys/systm.h>
36.79 -#define assert ASSERT
36.80 -#define labs(a) (a >= 0 ? a : -a)
36.81 -#define UCHAR_MAX 255
36.82 -#define memset(s, c, n) bzero(s, n)
36.83 -#define memcpy(a,b,c) bcopy((caddr_t)b, (caddr_t)a, c)
36.84 -/*
36.85 - * Generic #define's to cover missing things in the kernel
36.86 - */
36.87 -#ifndef isdigit
36.88 -#define isdigit(x) ((x) >= '0' && (x) <= '9')
36.89 -#endif
36.90 -#ifndef isupper
36.91 -#define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z'))
36.92 -#endif
36.93 -#ifndef islower
36.94 -#define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z'))
36.95 -#endif
36.96 -#ifndef isalpha
36.97 -#define isalpha(x) (isupper(x) || islower(x))
36.98 -#endif
36.99 -#ifndef toupper
36.100 -#define toupper(x) (islower(x) ? (x) - 'a' + 'A' : (x))
36.101 -#endif
36.102 -#ifndef tolower
36.103 -#define tolower(x) (isupper(x) ? (x) + 'a' - 'A' : (x))
36.104 -#endif
36.105 -#ifndef isspace
36.106 -#define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \
36.107 - ((x) == '\t') || ((x) == '\b'))
36.108 -#endif
36.109 -#endif /* _KERNEL */
36.110 -
36.111 -#if MP_DEBUG
36.112 -#undef MP_IOFUNC
36.113 -#define MP_IOFUNC 1
36.114 -#endif
36.115 -
36.116 -#if MP_IOFUNC
36.117 -#include <stdio.h>
36.118 -#include <ctype.h>
36.119 -#endif
36.120 -
36.121 -#ifndef _KERNEL
36.122 -#include <limits.h>
36.123 -#endif
36.124 -
36.125 -#if defined(BSDI)
36.126 -#undef ULLONG_MAX
36.127 -#endif
36.128 -
36.129 -#if defined( macintosh )
36.130 -#include <Types.h>
36.131 -#elif defined( _WIN32_WCE)
36.132 -/* #include <sys/types.h> What do we need here ?? */
36.133 -#else
36.134 -#include <sys/types.h>
36.135 -#endif
36.136 -
36.137 -#define MP_NEG 1
36.138 -#define MP_ZPOS 0
36.139 -
36.140 -#define MP_OKAY 0 /* no error, all is well */
36.141 -#define MP_YES 0 /* yes (boolean result) */
36.142 -#define MP_NO -1 /* no (boolean result) */
36.143 -#define MP_MEM -2 /* out of memory */
36.144 -#define MP_RANGE -3 /* argument out of range */
36.145 -#define MP_BADARG -4 /* invalid parameter */
36.146 -#define MP_UNDEF -5 /* answer is undefined */
36.147 -#define MP_LAST_CODE MP_UNDEF
36.148 -
36.149 -typedef unsigned int mp_sign;
36.150 -typedef unsigned int mp_size;
36.151 -typedef int mp_err;
36.152 -typedef int mp_flag;
36.153 -
36.154 -#define MP_32BIT_MAX 4294967295U
36.155 -
36.156 -#if !defined(ULONG_MAX)
36.157 -#error "ULONG_MAX not defined"
36.158 -#elif !defined(UINT_MAX)
36.159 -#error "UINT_MAX not defined"
36.160 -#elif !defined(USHRT_MAX)
36.161 -#error "USHRT_MAX not defined"
36.162 -#endif
36.163 -
36.164 -#if defined(ULONG_LONG_MAX) /* GCC, HPUX */
36.165 -#define MP_ULONG_LONG_MAX ULONG_LONG_MAX
36.166 -#elif defined(ULLONG_MAX) /* Solaris */
36.167 -#define MP_ULONG_LONG_MAX ULLONG_MAX
36.168 -/* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */
36.169 -#elif defined(ULONGLONG_MAX) /* IRIX, AIX */
36.170 -#define MP_ULONG_LONG_MAX ULONGLONG_MAX
36.171 -#endif
36.172 -
36.173 -/* We only use unsigned long for mp_digit iff long is more than 32 bits. */
36.174 -#if !defined(MP_USE_UINT_DIGIT) && ULONG_MAX > MP_32BIT_MAX
36.175 -typedef unsigned long mp_digit;
36.176 -#define MP_DIGIT_MAX ULONG_MAX
36.177 -#define MP_DIGIT_FMT "%016lX" /* printf() format for 1 digit */
36.178 -#define MP_HALF_DIGIT_MAX UINT_MAX
36.179 -#undef MP_NO_MP_WORD
36.180 -#define MP_NO_MP_WORD 1
36.181 -#undef MP_USE_LONG_DIGIT
36.182 -#define MP_USE_LONG_DIGIT 1
36.183 -#undef MP_USE_LONG_LONG_DIGIT
36.184 -
36.185 -#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX)
36.186 -typedef unsigned long long mp_digit;
36.187 -#define MP_DIGIT_MAX MP_ULONG_LONG_MAX
36.188 -#define MP_DIGIT_FMT "%016llX" /* printf() format for 1 digit */
36.189 -#define MP_HALF_DIGIT_MAX UINT_MAX
36.190 -#undef MP_NO_MP_WORD
36.191 -#define MP_NO_MP_WORD 1
36.192 -#undef MP_USE_LONG_LONG_DIGIT
36.193 -#define MP_USE_LONG_LONG_DIGIT 1
36.194 -#undef MP_USE_LONG_DIGIT
36.195 -
36.196 -#else
36.197 -typedef unsigned int mp_digit;
36.198 -#define MP_DIGIT_MAX UINT_MAX
36.199 -#define MP_DIGIT_FMT "%08X" /* printf() format for 1 digit */
36.200 -#define MP_HALF_DIGIT_MAX USHRT_MAX
36.201 -#undef MP_USE_UINT_DIGIT
36.202 -#define MP_USE_UINT_DIGIT 1
36.203 -#undef MP_USE_LONG_LONG_DIGIT
36.204 -#undef MP_USE_LONG_DIGIT
36.205 -#endif
36.206 -
36.207 -#if !defined(MP_NO_MP_WORD)
36.208 -#if defined(MP_USE_UINT_DIGIT) && \
36.209 - (defined(MP_ULONG_LONG_MAX) || (ULONG_MAX > UINT_MAX))
36.210 -
36.211 -#if (ULONG_MAX > UINT_MAX)
36.212 -typedef unsigned long mp_word;
36.213 -typedef long mp_sword;
36.214 -#define MP_WORD_MAX ULONG_MAX
36.215 -
36.216 -#else
36.217 -typedef unsigned long long mp_word;
36.218 -typedef long long mp_sword;
36.219 -#define MP_WORD_MAX MP_ULONG_LONG_MAX
36.220 -#endif
36.221 -
36.222 -#else
36.223 -#define MP_NO_MP_WORD 1
36.224 -#endif
36.225 -#endif /* !defined(MP_NO_MP_WORD) */
36.226 -
36.227 -#if !defined(MP_WORD_MAX) && defined(MP_DEFINE_SMALL_WORD)
36.228 -typedef unsigned int mp_word;
36.229 -typedef int mp_sword;
36.230 -#define MP_WORD_MAX UINT_MAX
36.231 -#endif
36.232 -
36.233 -#ifndef CHAR_BIT
36.234 -#define CHAR_BIT 8
36.235 -#endif
36.236 -
36.237 -#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
36.238 -#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
36.239 -#define MP_RADIX (1+(mp_word)MP_DIGIT_MAX)
36.240 -
36.241 -#define MP_HALF_DIGIT_BIT (MP_DIGIT_BIT/2)
36.242 -#define MP_HALF_RADIX (1+(mp_digit)MP_HALF_DIGIT_MAX)
36.243 -/* MP_HALF_RADIX really ought to be called MP_SQRT_RADIX, but it's named
36.244 -** MP_HALF_RADIX because it's the radix for MP_HALF_DIGITs, and it's
36.245 -** consistent with the other _HALF_ names.
36.246 -*/
36.247 -
36.248 -
36.249 -/* Macros for accessing the mp_int internals */
36.250 -#define MP_FLAG(MP) ((MP)->flag)
36.251 -#define MP_SIGN(MP) ((MP)->sign)
36.252 -#define MP_USED(MP) ((MP)->used)
36.253 -#define MP_ALLOC(MP) ((MP)->alloc)
36.254 -#define MP_DIGITS(MP) ((MP)->dp)
36.255 -#define MP_DIGIT(MP,N) (MP)->dp[(N)]
36.256 -
36.257 -/* This defines the maximum I/O base (minimum is 2) */
36.258 -#define MP_MAX_RADIX 64
36.259 -
36.260 -typedef struct {
36.261 - mp_sign flag; /* KM_SLEEP/KM_NOSLEEP */
36.262 - mp_sign sign; /* sign of this quantity */
36.263 - mp_size alloc; /* how many digits allocated */
36.264 - mp_size used; /* how many digits used */
36.265 - mp_digit *dp; /* the digits themselves */
36.266 -} mp_int;
36.267 -
36.268 -/* Default precision */
36.269 -mp_size mp_get_prec(void);
36.270 -void mp_set_prec(mp_size prec);
36.271 -
36.272 -/* Memory management */
36.273 -mp_err mp_init(mp_int *mp, int kmflag);
36.274 -mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag);
36.275 -mp_err mp_init_copy(mp_int *mp, const mp_int *from);
36.276 -mp_err mp_copy(const mp_int *from, mp_int *to);
36.277 -void mp_exch(mp_int *mp1, mp_int *mp2);
36.278 -void mp_clear(mp_int *mp);
36.279 -void mp_zero(mp_int *mp);
36.280 -void mp_set(mp_int *mp, mp_digit d);
36.281 -mp_err mp_set_int(mp_int *mp, long z);
36.282 -#define mp_set_long(mp,z) mp_set_int(mp,z)
36.283 -mp_err mp_set_ulong(mp_int *mp, unsigned long z);
36.284 -
36.285 -/* Single digit arithmetic */
36.286 -mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b);
36.287 -mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b);
36.288 -mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b);
36.289 -mp_err mp_mul_2(const mp_int *a, mp_int *c);
36.290 -mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
36.291 -mp_err mp_div_2(const mp_int *a, mp_int *c);
36.292 -mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c);
36.293 -
36.294 -/* Sign manipulations */
36.295 -mp_err mp_abs(const mp_int *a, mp_int *b);
36.296 -mp_err mp_neg(const mp_int *a, mp_int *b);
36.297 -
36.298 -/* Full arithmetic */
36.299 -mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c);
36.300 -mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
36.301 -mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
36.302 -#if MP_SQUARE
36.303 -mp_err mp_sqr(const mp_int *a, mp_int *b);
36.304 -#else
36.305 -#define mp_sqr(a, b) mp_mul(a, a, b)
36.306 -#endif
36.307 -mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r);
36.308 -mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r);
36.309 -mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
36.310 -mp_err mp_2expt(mp_int *a, mp_digit k);
36.311 -mp_err mp_sqrt(const mp_int *a, mp_int *b);
36.312 -
36.313 -/* Modular arithmetic */
36.314 -#if MP_MODARITH
36.315 -mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c);
36.316 -mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c);
36.317 -mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
36.318 -mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
36.319 -mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
36.320 -#if MP_SQUARE
36.321 -mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c);
36.322 -#else
36.323 -#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
36.324 -#endif
36.325 -mp_err mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
36.326 -mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
36.327 -#endif /* MP_MODARITH */
36.328 -
36.329 -/* Comparisons */
36.330 -int mp_cmp_z(const mp_int *a);
36.331 -int mp_cmp_d(const mp_int *a, mp_digit d);
36.332 -int mp_cmp(const mp_int *a, const mp_int *b);
36.333 -int mp_cmp_mag(mp_int *a, mp_int *b);
36.334 -int mp_cmp_int(const mp_int *a, long z, int kmflag);
36.335 -int mp_isodd(const mp_int *a);
36.336 -int mp_iseven(const mp_int *a);
36.337 -
36.338 -/* Number theoretic */
36.339 -#if MP_NUMTH
36.340 -mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
36.341 -mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
36.342 -mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y);
36.343 -mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c);
36.344 -mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c);
36.345 -#endif /* end MP_NUMTH */
36.346 -
36.347 -/* Input and output */
36.348 -#if MP_IOFUNC
36.349 -void mp_print(mp_int *mp, FILE *ofp);
36.350 -#endif /* end MP_IOFUNC */
36.351 -
36.352 -/* Base conversion */
36.353 -mp_err mp_read_raw(mp_int *mp, char *str, int len);
36.354 -int mp_raw_size(mp_int *mp);
36.355 -mp_err mp_toraw(mp_int *mp, char *str);
36.356 -mp_err mp_read_radix(mp_int *mp, const char *str, int radix);
36.357 -mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix);
36.358 -int mp_radix_size(mp_int *mp, int radix);
36.359 -mp_err mp_toradix(mp_int *mp, char *str, int radix);
36.360 -int mp_tovalue(char ch, int r);
36.361 -
36.362 -#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
36.363 -#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
36.364 -#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
36.365 -#define mp_tohex(M, S) mp_toradix((M), (S), 16)
36.366 -
36.367 -/* Error strings */
36.368 -const char *mp_strerror(mp_err ec);
36.369 -
36.370 -/* Octet string conversion functions */
36.371 -mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len);
36.372 -int mp_unsigned_octet_size(const mp_int *mp);
36.373 -mp_err mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
36.374 -mp_err mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
36.375 -mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size len);
36.376 -
36.377 -/* Miscellaneous */
36.378 -mp_size mp_trailing_zeros(const mp_int *mp);
36.379 -
36.380 -#define MP_CHECKOK(x) if (MP_OKAY > (res = (x))) goto CLEANUP
36.381 -#define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP
36.382 -
36.383 -#if defined(MP_API_COMPATIBLE)
36.384 -#define NEG MP_NEG
36.385 -#define ZPOS MP_ZPOS
36.386 -#define DIGIT_MAX MP_DIGIT_MAX
36.387 -#define DIGIT_BIT MP_DIGIT_BIT
36.388 -#define DIGIT_FMT MP_DIGIT_FMT
36.389 -#define RADIX MP_RADIX
36.390 -#define MAX_RADIX MP_MAX_RADIX
36.391 -#define FLAG(MP) MP_FLAG(MP)
36.392 -#define SIGN(MP) MP_SIGN(MP)
36.393 -#define USED(MP) MP_USED(MP)
36.394 -#define ALLOC(MP) MP_ALLOC(MP)
36.395 -#define DIGITS(MP) MP_DIGITS(MP)
36.396 -#define DIGIT(MP,N) MP_DIGIT(MP,N)
36.397 -
36.398 -#if MP_ARGCHK == 1
36.399 -#define ARGCHK(X,Y) {if(!(X)){return (Y);}}
36.400 -#elif MP_ARGCHK == 2
36.401 -#ifdef _KERNEL
36.402 -#define ARGCHK(X,Y) ASSERT(X)
36.403 -#else
36.404 -#include <assert.h>
36.405 -#define ARGCHK(X,Y) assert(X)
36.406 -#endif
36.407 -#else
36.408 -#define ARGCHK(X,Y) /* */
36.409 -#endif
36.410 -#endif /* defined MP_API_COMPATIBLE */
36.411 -
36.412 -#endif /* _MPI_H */
37.1 --- a/src/share/native/sun/security/ec/mplogic.c Tue Oct 13 15:25:58 2009 -0700
37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
37.3 @@ -1,242 +0,0 @@
37.4 -/* *********************************************************************
37.5 - *
37.6 - * Sun elects to have this file available under and governed by the
37.7 - * Mozilla Public License Version 1.1 ("MPL") (see
37.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
37.9 - * of doubt and subject to the following, Sun also elects to allow
37.10 - * licensees to use this file under the MPL, the GNU General Public
37.11 - * License version 2 only or the Lesser General Public License version
37.12 - * 2.1 only. Any references to the "GNU General Public License version 2
37.13 - * or later" or "GPL" in the following shall be construed to mean the
37.14 - * GNU General Public License version 2 only. Any references to the "GNU
37.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
37.16 - * following shall be construed to mean the GNU Lesser General Public
37.17 - * License version 2.1 only. However, the following notice accompanied
37.18 - * the original version of this file:
37.19 - *
37.20 - *
37.21 - * Bitwise logical operations on MPI values
37.22 - *
37.23 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
37.24 - *
37.25 - * The contents of this file are subject to the Mozilla Public License Version
37.26 - * 1.1 (the "License"); you may not use this file except in compliance with
37.27 - * the License. You may obtain a copy of the License at
37.28 - * http://www.mozilla.org/MPL/
37.29 - *
37.30 - * Software distributed under the License is distributed on an "AS IS" basis,
37.31 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
37.32 - * for the specific language governing rights and limitations under the
37.33 - * License.
37.34 - *
37.35 - * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
37.36 - *
37.37 - * The Initial Developer of the Original Code is
37.38 - * Michael J. Fromberger.
37.39 - * Portions created by the Initial Developer are Copyright (C) 1998
37.40 - * the Initial Developer. All Rights Reserved.
37.41 - *
37.42 - * Contributor(s):
37.43 - *
37.44 - * Alternatively, the contents of this file may be used under the terms of
37.45 - * either the GNU General Public License Version 2 or later (the "GPL"), or
37.46 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
37.47 - * in which case the provisions of the GPL or the LGPL are applicable instead
37.48 - * of those above. If you wish to allow use of your version of this file only
37.49 - * under the terms of either the GPL or the LGPL, and not to allow others to
37.50 - * use your version of this file under the terms of the MPL, indicate your
37.51 - * decision by deleting the provisions above and replace them with the notice
37.52 - * and other provisions required by the GPL or the LGPL. If you do not delete
37.53 - * the provisions above, a recipient may use your version of this file under
37.54 - * the terms of any one of the MPL, the GPL or the LGPL.
37.55 - *
37.56 - *********************************************************************** */
37.57 -/*
37.58 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
37.59 - * Use is subject to license terms.
37.60 - */
37.61 -
37.62 -#pragma ident "%Z%%M% %I% %E% SMI"
37.63 -
37.64 -/* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
37.65 -
37.66 -#include "mpi-priv.h"
37.67 -#include "mplogic.h"
37.68 -
37.69 -/* {{{ Lookup table for population count */
37.70 -
37.71 -static unsigned char bitc[] = {
37.72 - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
37.73 - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
37.74 - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
37.75 - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
37.76 - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
37.77 - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
37.78 - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
37.79 - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
37.80 - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
37.81 - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
37.82 - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
37.83 - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
37.84 - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
37.85 - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
37.86 - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
37.87 - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
37.88 -};
37.89 -
37.90 -/* }}} */
37.91 -
37.92 -/*
37.93 - mpl_rsh(a, b, d) - b = a >> d
37.94 - mpl_lsh(a, b, d) - b = a << d
37.95 - */
37.96 -
37.97 -/* {{{ mpl_rsh(a, b, d) */
37.98 -
37.99 -mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
37.100 -{
37.101 - mp_err res;
37.102 -
37.103 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
37.104 -
37.105 - if((res = mp_copy(a, b)) != MP_OKAY)
37.106 - return res;
37.107 -
37.108 - s_mp_div_2d(b, d);
37.109 -
37.110 - return MP_OKAY;
37.111 -
37.112 -} /* end mpl_rsh() */
37.113 -
37.114 -/* }}} */
37.115 -
37.116 -/* {{{ mpl_lsh(a, b, d) */
37.117 -
37.118 -mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
37.119 -{
37.120 - mp_err res;
37.121 -
37.122 - ARGCHK(a != NULL && b != NULL, MP_BADARG);
37.123 -
37.124 - if((res = mp_copy(a, b)) != MP_OKAY)
37.125 - return res;
37.126 -
37.127 - return s_mp_mul_2d(b, d);
37.128 -
37.129 -} /* end mpl_lsh() */
37.130 -
37.131 -/* }}} */
37.132 -
37.133 -/*------------------------------------------------------------------------*/
37.134 -/*
37.135 - mpl_set_bit
37.136 -
37.137 - Returns MP_OKAY or some error code.
37.138 - Grows a if needed to set a bit to 1.
37.139 - */
37.140 -mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
37.141 -{
37.142 - mp_size ix;
37.143 - mp_err rv;
37.144 - mp_digit mask;
37.145 -
37.146 - ARGCHK(a != NULL, MP_BADARG);
37.147 -
37.148 - ix = bitNum / MP_DIGIT_BIT;
37.149 - if (ix + 1 > MP_USED(a)) {
37.150 - rv = s_mp_pad(a, ix + 1);
37.151 - if (rv != MP_OKAY)
37.152 - return rv;
37.153 - }
37.154 -
37.155 - bitNum = bitNum % MP_DIGIT_BIT;
37.156 - mask = (mp_digit)1 << bitNum;
37.157 - if (value)
37.158 - MP_DIGIT(a,ix) |= mask;
37.159 - else
37.160 - MP_DIGIT(a,ix) &= ~mask;
37.161 - s_mp_clamp(a);
37.162 - return MP_OKAY;
37.163 -}
37.164 -
37.165 -/*
37.166 - mpl_get_bit
37.167 -
37.168 - returns 0 or 1 or some (negative) error code.
37.169 - */
37.170 -mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
37.171 -{
37.172 - mp_size bit, ix;
37.173 - mp_err rv;
37.174 -
37.175 - ARGCHK(a != NULL, MP_BADARG);
37.176 -
37.177 - ix = bitNum / MP_DIGIT_BIT;
37.178 - ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
37.179 -
37.180 - bit = bitNum % MP_DIGIT_BIT;
37.181 - rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1;
37.182 - return rv;
37.183 -}
37.184 -
37.185 -/*
37.186 - mpl_get_bits
37.187 - - Extracts numBits bits from a, where the least significant extracted bit
37.188 - is bit lsbNum. Returns a negative value if error occurs.
37.189 - - Because sign bit is used to indicate error, maximum number of bits to
37.190 - be returned is the lesser of (a) the number of bits in an mp_digit, or
37.191 - (b) one less than the number of bits in an mp_err.
37.192 - - lsbNum + numbits can be greater than the number of significant bits in
37.193 - integer a, as long as bit lsbNum is in the high order digit of a.
37.194 - */
37.195 -mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
37.196 -{
37.197 - mp_size rshift = (lsbNum % MP_DIGIT_BIT);
37.198 - mp_size lsWndx = (lsbNum / MP_DIGIT_BIT);
37.199 - mp_digit * digit = MP_DIGITS(a) + lsWndx;
37.200 - mp_digit mask = ((1 << numBits) - 1);
37.201 -
37.202 - ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG);
37.203 - ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE);
37.204 -
37.205 - if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) ||
37.206 - (lsWndx + 1 >= MP_USED(a))) {
37.207 - mask &= (digit[0] >> rshift);
37.208 - } else {
37.209 - mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift)));
37.210 - }
37.211 - return (mp_err)mask;
37.212 -}
37.213 -
37.214 -/*
37.215 - mpl_significant_bits
37.216 - returns number of significnant bits in abs(a).
37.217 - returns 1 if value is zero.
37.218 - */
37.219 -mp_err mpl_significant_bits(const mp_int *a)
37.220 -{
37.221 - mp_err bits = 0;
37.222 - int ix;
37.223 -
37.224 - ARGCHK(a != NULL, MP_BADARG);
37.225 -
37.226 - ix = MP_USED(a);
37.227 - for (ix = MP_USED(a); ix > 0; ) {
37.228 - mp_digit d;
37.229 - d = MP_DIGIT(a, --ix);
37.230 - if (d) {
37.231 - while (d) {
37.232 - ++bits;
37.233 - d >>= 1;
37.234 - }
37.235 - break;
37.236 - }
37.237 - }
37.238 - bits += ix * MP_DIGIT_BIT;
37.239 - if (!bits)
37.240 - bits = 1;
37.241 - return bits;
37.242 -}
37.243 -
37.244 -/*------------------------------------------------------------------------*/
37.245 -/* HERE THERE BE DRAGONS */
38.1 --- a/src/share/native/sun/security/ec/mplogic.h Tue Oct 13 15:25:58 2009 -0700
38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
38.3 @@ -1,105 +0,0 @@
38.4 -/* *********************************************************************
38.5 - *
38.6 - * Sun elects to have this file available under and governed by the
38.7 - * Mozilla Public License Version 1.1 ("MPL") (see
38.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
38.9 - * of doubt and subject to the following, Sun also elects to allow
38.10 - * licensees to use this file under the MPL, the GNU General Public
38.11 - * License version 2 only or the Lesser General Public License version
38.12 - * 2.1 only. Any references to the "GNU General Public License version 2
38.13 - * or later" or "GPL" in the following shall be construed to mean the
38.14 - * GNU General Public License version 2 only. Any references to the "GNU
38.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
38.16 - * following shall be construed to mean the GNU Lesser General Public
38.17 - * License version 2.1 only. However, the following notice accompanied
38.18 - * the original version of this file:
38.19 - *
38.20 - *
38.21 - * Bitwise logical operations on MPI values
38.22 - *
38.23 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
38.24 - *
38.25 - * The contents of this file are subject to the Mozilla Public License Version
38.26 - * 1.1 (the "License"); you may not use this file except in compliance with
38.27 - * the License. You may obtain a copy of the License at
38.28 - * http://www.mozilla.org/MPL/
38.29 - *
38.30 - * Software distributed under the License is distributed on an "AS IS" basis,
38.31 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
38.32 - * for the specific language governing rights and limitations under the
38.33 - * License.
38.34 - *
38.35 - * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
38.36 - *
38.37 - * The Initial Developer of the Original Code is
38.38 - * Michael J. Fromberger.
38.39 - * Portions created by the Initial Developer are Copyright (C) 1998
38.40 - * the Initial Developer. All Rights Reserved.
38.41 - *
38.42 - * Contributor(s):
38.43 - *
38.44 - * Alternatively, the contents of this file may be used under the terms of
38.45 - * either the GNU General Public License Version 2 or later (the "GPL"), or
38.46 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
38.47 - * in which case the provisions of the GPL or the LGPL are applicable instead
38.48 - * of those above. If you wish to allow use of your version of this file only
38.49 - * under the terms of either the GPL or the LGPL, and not to allow others to
38.50 - * use your version of this file under the terms of the MPL, indicate your
38.51 - * decision by deleting the provisions above and replace them with the notice
38.52 - * and other provisions required by the GPL or the LGPL. If you do not delete
38.53 - * the provisions above, a recipient may use your version of this file under
38.54 - * the terms of any one of the MPL, the GPL or the LGPL.
38.55 - *
38.56 - *********************************************************************** */
38.57 -/*
38.58 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
38.59 - * Use is subject to license terms.
38.60 - */
38.61 -
38.62 -#ifndef _MPLOGIC_H
38.63 -#define _MPLOGIC_H
38.64 -
38.65 -#pragma ident "%Z%%M% %I% %E% SMI"
38.66 -
38.67 -/* $Id: mplogic.h,v 1.7 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
38.68 -
38.69 -#include "mpi.h"
38.70 -
38.71 -/*
38.72 - The logical operations treat an mp_int as if it were a bit vector,
38.73 - without regard to its sign (an mp_int is represented in a signed
38.74 - magnitude format). Values are treated as if they had an infinite
38.75 - string of zeros left of the most-significant bit.
38.76 - */
38.77 -
38.78 -/* Parity results */
38.79 -
38.80 -#define MP_EVEN MP_YES
38.81 -#define MP_ODD MP_NO
38.82 -
38.83 -/* Bitwise functions */
38.84 -
38.85 -mp_err mpl_not(mp_int *a, mp_int *b); /* one's complement */
38.86 -mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c); /* bitwise AND */
38.87 -mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c); /* bitwise OR */
38.88 -mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c); /* bitwise XOR */
38.89 -
38.90 -/* Shift functions */
38.91 -
38.92 -mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d); /* right shift */
38.93 -mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d); /* left shift */
38.94 -
38.95 -/* Bit count and parity */
38.96 -
38.97 -mp_err mpl_num_set(mp_int *a, int *num); /* count set bits */
38.98 -mp_err mpl_num_clear(mp_int *a, int *num); /* count clear bits */
38.99 -mp_err mpl_parity(mp_int *a); /* determine parity */
38.100 -
38.101 -/* Get & Set the value of a bit */
38.102 -
38.103 -mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value);
38.104 -mp_err mpl_get_bit(const mp_int *a, mp_size bitNum);
38.105 -mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits);
38.106 -mp_err mpl_significant_bits(const mp_int *a);
38.107 -
38.108 -#endif /* _MPLOGIC_H */
39.1 --- a/src/share/native/sun/security/ec/mpmontg.c Tue Oct 13 15:25:58 2009 -0700
39.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
39.3 @@ -1,199 +0,0 @@
39.4 -/* *********************************************************************
39.5 - *
39.6 - * Sun elects to have this file available under and governed by the
39.7 - * Mozilla Public License Version 1.1 ("MPL") (see
39.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
39.9 - * of doubt and subject to the following, Sun also elects to allow
39.10 - * licensees to use this file under the MPL, the GNU General Public
39.11 - * License version 2 only or the Lesser General Public License version
39.12 - * 2.1 only. Any references to the "GNU General Public License version 2
39.13 - * or later" or "GPL" in the following shall be construed to mean the
39.14 - * GNU General Public License version 2 only. Any references to the "GNU
39.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
39.16 - * following shall be construed to mean the GNU Lesser General Public
39.17 - * License version 2.1 only. However, the following notice accompanied
39.18 - * the original version of this file:
39.19 - *
39.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
39.21 - *
39.22 - * The contents of this file are subject to the Mozilla Public License Version
39.23 - * 1.1 (the "License"); you may not use this file except in compliance with
39.24 - * the License. You may obtain a copy of the License at
39.25 - * http://www.mozilla.org/MPL/
39.26 - *
39.27 - * Software distributed under the License is distributed on an "AS IS" basis,
39.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
39.29 - * for the specific language governing rights and limitations under the
39.30 - * License.
39.31 - *
39.32 - * The Original Code is the Netscape security libraries.
39.33 - *
39.34 - * The Initial Developer of the Original Code is
39.35 - * Netscape Communications Corporation.
39.36 - * Portions created by the Initial Developer are Copyright (C) 2000
39.37 - * the Initial Developer. All Rights Reserved.
39.38 - *
39.39 - * Contributor(s):
39.40 - * Sheueling Chang Shantz <sheueling.chang@sun.com>,
39.41 - * Stephen Fung <stephen.fung@sun.com>, and
39.42 - * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
39.43 - *
39.44 - * Alternatively, the contents of this file may be used under the terms of
39.45 - * either the GNU General Public License Version 2 or later (the "GPL"), or
39.46 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
39.47 - * in which case the provisions of the GPL or the LGPL are applicable instead
39.48 - * of those above. If you wish to allow use of your version of this file only
39.49 - * under the terms of either the GPL or the LGPL, and not to allow others to
39.50 - * use your version of this file under the terms of the MPL, indicate your
39.51 - * decision by deleting the provisions above and replace them with the notice
39.52 - * and other provisions required by the GPL or the LGPL. If you do not delete
39.53 - * the provisions above, a recipient may use your version of this file under
39.54 - * the terms of any one of the MPL, the GPL or the LGPL.
39.55 - *
39.56 - *********************************************************************** */
39.57 -/*
39.58 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
39.59 - * Use is subject to license terms.
39.60 - */
39.61 -
39.62 -#pragma ident "%Z%%M% %I% %E% SMI"
39.63 -
39.64 -/* $Id: mpmontg.c,v 1.20 2006/08/29 02:41:38 nelson%bolyard.com Exp $ */
39.65 -
39.66 -/* This file implements moduluar exponentiation using Montgomery's
39.67 - * method for modular reduction. This file implements the method
39.68 - * described as "Improvement 1" in the paper "A Cryptogrpahic Library for
39.69 - * the Motorola DSP56000" by Stephen R. Dusse' and Burton S. Kaliski Jr.
39.70 - * published in "Advances in Cryptology: Proceedings of EUROCRYPT '90"
39.71 - * "Lecture Notes in Computer Science" volume 473, 1991, pg 230-244,
39.72 - * published by Springer Verlag.
39.73 - */
39.74 -
39.75 -#define MP_USING_CACHE_SAFE_MOD_EXP 1
39.76 -#ifndef _KERNEL
39.77 -#include <string.h>
39.78 -#include <stddef.h> /* ptrdiff_t */
39.79 -#endif
39.80 -#include "mpi-priv.h"
39.81 -#include "mplogic.h"
39.82 -#include "mpprime.h"
39.83 -#ifdef MP_USING_MONT_MULF
39.84 -#include "montmulf.h"
39.85 -#endif
39.86 -
39.87 -/* if MP_CHAR_STORE_SLOW is defined, we */
39.88 -/* need to know endianness of this platform. */
39.89 -#ifdef MP_CHAR_STORE_SLOW
39.90 -#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN)
39.91 -#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \
39.92 - " if you define MP_CHAR_STORE_SLOW."
39.93 -#endif
39.94 -#endif
39.95 -
39.96 -#ifndef STATIC
39.97 -#define STATIC
39.98 -#endif
39.99 -
39.100 -#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
39.101 -
39.102 -#ifndef _KERNEL
39.103 -#if defined(_WIN32_WCE)
39.104 -#define ABORT res = MP_UNDEF; goto CLEANUP
39.105 -#else
39.106 -#define ABORT abort()
39.107 -#endif
39.108 -#else
39.109 -#define ABORT res = MP_UNDEF; goto CLEANUP
39.110 -#endif /* _KERNEL */
39.111 -
39.112 -/* computes T = REDC(T), 2^b == R */
39.113 -mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm)
39.114 -{
39.115 - mp_err res;
39.116 - mp_size i;
39.117 -
39.118 - i = MP_USED(T) + MP_USED(&mmm->N) + 2;
39.119 - MP_CHECKOK( s_mp_pad(T, i) );
39.120 - for (i = 0; i < MP_USED(&mmm->N); ++i ) {
39.121 - mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime;
39.122 - /* T += N * m_i * (MP_RADIX ** i); */
39.123 - MP_CHECKOK( s_mp_mul_d_add_offset(&mmm->N, m_i, T, i) );
39.124 - }
39.125 - s_mp_clamp(T);
39.126 -
39.127 - /* T /= R */
39.128 - s_mp_div_2d(T, mmm->b);
39.129 -
39.130 - if ((res = s_mp_cmp(T, &mmm->N)) >= 0) {
39.131 - /* T = T - N */
39.132 - MP_CHECKOK( s_mp_sub(T, &mmm->N) );
39.133 -#ifdef DEBUG
39.134 - if ((res = mp_cmp(T, &mmm->N)) >= 0) {
39.135 - res = MP_UNDEF;
39.136 - goto CLEANUP;
39.137 - }
39.138 -#endif
39.139 - }
39.140 - res = MP_OKAY;
39.141 -CLEANUP:
39.142 - return res;
39.143 -}
39.144 -
39.145 -#if !defined(MP_ASSEMBLY_MUL_MONT) && !defined(MP_MONT_USE_MP_MUL)
39.146 -mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
39.147 - mp_mont_modulus *mmm)
39.148 -{
39.149 - mp_digit *pb;
39.150 - mp_digit m_i;
39.151 - mp_err res;
39.152 - mp_size ib;
39.153 - mp_size useda, usedb;
39.154 -
39.155 - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
39.156 -
39.157 - if (MP_USED(a) < MP_USED(b)) {
39.158 - const mp_int *xch = b; /* switch a and b, to do fewer outer loops */
39.159 - b = a;
39.160 - a = xch;
39.161 - }
39.162 -
39.163 - MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
39.164 - ib = MP_USED(a) + MP_MAX(MP_USED(b), MP_USED(&mmm->N)) + 2;
39.165 - if((res = s_mp_pad(c, ib)) != MP_OKAY)
39.166 - goto CLEANUP;
39.167 -
39.168 - useda = MP_USED(a);
39.169 - pb = MP_DIGITS(b);
39.170 - s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c));
39.171 - s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1));
39.172 - m_i = MP_DIGIT(c, 0) * mmm->n0prime;
39.173 - s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0);
39.174 -
39.175 - /* Outer loop: Digits of b */
39.176 - usedb = MP_USED(b);
39.177 - for (ib = 1; ib < usedb; ib++) {
39.178 - mp_digit b_i = *pb++;
39.179 -
39.180 - /* Inner product: Digits of a */
39.181 - if (b_i)
39.182 - s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
39.183 - m_i = MP_DIGIT(c, ib) * mmm->n0prime;
39.184 - s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
39.185 - }
39.186 - if (usedb < MP_USED(&mmm->N)) {
39.187 - for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib ) {
39.188 - m_i = MP_DIGIT(c, ib) * mmm->n0prime;
39.189 - s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
39.190 - }
39.191 - }
39.192 - s_mp_clamp(c);
39.193 - s_mp_div_2d(c, mmm->b);
39.194 - if (s_mp_cmp(c, &mmm->N) >= 0) {
39.195 - MP_CHECKOK( s_mp_sub(c, &mmm->N) );
39.196 - }
39.197 - res = MP_OKAY;
39.198 -
39.199 -CLEANUP:
39.200 - return res;
39.201 -}
39.202 -#endif
40.1 --- a/src/share/native/sun/security/ec/mpprime.h Tue Oct 13 15:25:58 2009 -0700
40.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
40.3 @@ -1,89 +0,0 @@
40.4 -/* *********************************************************************
40.5 - *
40.6 - * Sun elects to have this file available under and governed by the
40.7 - * Mozilla Public License Version 1.1 ("MPL") (see
40.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
40.9 - * of doubt and subject to the following, Sun also elects to allow
40.10 - * licensees to use this file under the MPL, the GNU General Public
40.11 - * License version 2 only or the Lesser General Public License version
40.12 - * 2.1 only. Any references to the "GNU General Public License version 2
40.13 - * or later" or "GPL" in the following shall be construed to mean the
40.14 - * GNU General Public License version 2 only. Any references to the "GNU
40.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
40.16 - * following shall be construed to mean the GNU Lesser General Public
40.17 - * License version 2.1 only. However, the following notice accompanied
40.18 - * the original version of this file:
40.19 - *
40.20 - *
40.21 - * Utilities for finding and working with prime and pseudo-prime
40.22 - * integers
40.23 - *
40.24 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
40.25 - *
40.26 - * The contents of this file are subject to the Mozilla Public License Version
40.27 - * 1.1 (the "License"); you may not use this file except in compliance with
40.28 - * the License. You may obtain a copy of the License at
40.29 - * http://www.mozilla.org/MPL/
40.30 - *
40.31 - * Software distributed under the License is distributed on an "AS IS" basis,
40.32 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
40.33 - * for the specific language governing rights and limitations under the
40.34 - * License.
40.35 - *
40.36 - * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
40.37 - *
40.38 - * The Initial Developer of the Original Code is
40.39 - * Michael J. Fromberger.
40.40 - * Portions created by the Initial Developer are Copyright (C) 1997
40.41 - * the Initial Developer. All Rights Reserved.
40.42 - *
40.43 - * Contributor(s):
40.44 - *
40.45 - * Alternatively, the contents of this file may be used under the terms of
40.46 - * either the GNU General Public License Version 2 or later (the "GPL"), or
40.47 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
40.48 - * in which case the provisions of the GPL or the LGPL are applicable instead
40.49 - * of those above. If you wish to allow use of your version of this file only
40.50 - * under the terms of either the GPL or the LGPL, and not to allow others to
40.51 - * use your version of this file under the terms of the MPL, indicate your
40.52 - * decision by deleting the provisions above and replace them with the notice
40.53 - * and other provisions required by the GPL or the LGPL. If you do not delete
40.54 - * the provisions above, a recipient may use your version of this file under
40.55 - * the terms of any one of the MPL, the GPL or the LGPL.
40.56 - *
40.57 - *********************************************************************** */
40.58 -/*
40.59 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
40.60 - * Use is subject to license terms.
40.61 - */
40.62 -
40.63 -#ifndef _MP_PRIME_H
40.64 -#define _MP_PRIME_H
40.65 -
40.66 -#pragma ident "%Z%%M% %I% %E% SMI"
40.67 -
40.68 -#include "mpi.h"
40.69 -
40.70 -extern const int prime_tab_size; /* number of primes available */
40.71 -extern const mp_digit prime_tab[];
40.72 -
40.73 -/* Tests for divisibility */
40.74 -mp_err mpp_divis(mp_int *a, mp_int *b);
40.75 -mp_err mpp_divis_d(mp_int *a, mp_digit d);
40.76 -
40.77 -/* Random selection */
40.78 -mp_err mpp_random(mp_int *a);
40.79 -mp_err mpp_random_size(mp_int *a, mp_size prec);
40.80 -
40.81 -/* Pseudo-primality testing */
40.82 -mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which);
40.83 -mp_err mpp_divis_primes(mp_int *a, mp_digit *np);
40.84 -mp_err mpp_fermat(mp_int *a, mp_digit w);
40.85 -mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes);
40.86 -mp_err mpp_pprime(mp_int *a, int nt);
40.87 -mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
40.88 - unsigned char *sieve, mp_size nSieve);
40.89 -mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
40.90 - unsigned long * nTries);
40.91 -
40.92 -#endif /* _MP_PRIME_H */
41.1 --- a/src/share/native/sun/security/ec/oid.c Tue Oct 13 15:25:58 2009 -0700
41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
41.3 @@ -1,473 +0,0 @@
41.4 -/* *********************************************************************
41.5 - *
41.6 - * Sun elects to have this file available under and governed by the
41.7 - * Mozilla Public License Version 1.1 ("MPL") (see
41.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
41.9 - * of doubt and subject to the following, Sun also elects to allow
41.10 - * licensees to use this file under the MPL, the GNU General Public
41.11 - * License version 2 only or the Lesser General Public License version
41.12 - * 2.1 only. Any references to the "GNU General Public License version 2
41.13 - * or later" or "GPL" in the following shall be construed to mean the
41.14 - * GNU General Public License version 2 only. Any references to the "GNU
41.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
41.16 - * following shall be construed to mean the GNU Lesser General Public
41.17 - * License version 2.1 only. However, the following notice accompanied
41.18 - * the original version of this file:
41.19 - *
41.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
41.21 - *
41.22 - * The contents of this file are subject to the Mozilla Public License Version
41.23 - * 1.1 (the "License"); you may not use this file except in compliance with
41.24 - * the License. You may obtain a copy of the License at
41.25 - * http://www.mozilla.org/MPL/
41.26 - *
41.27 - * Software distributed under the License is distributed on an "AS IS" basis,
41.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
41.29 - * for the specific language governing rights and limitations under the
41.30 - * License.
41.31 - *
41.32 - * The Original Code is the Netscape security libraries.
41.33 - *
41.34 - * The Initial Developer of the Original Code is
41.35 - * Netscape Communications Corporation.
41.36 - * Portions created by the Initial Developer are Copyright (C) 1994-2000
41.37 - * the Initial Developer. All Rights Reserved.
41.38 - *
41.39 - * Contributor(s):
41.40 - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
41.41 - *
41.42 - * Alternatively, the contents of this file may be used under the terms of
41.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
41.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
41.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
41.46 - * of those above. If you wish to allow use of your version of this file only
41.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
41.48 - * use your version of this file under the terms of the MPL, indicate your
41.49 - * decision by deleting the provisions above and replace them with the notice
41.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
41.51 - * the provisions above, a recipient may use your version of this file under
41.52 - * the terms of any one of the MPL, the GPL or the LGPL.
41.53 - *
41.54 - *********************************************************************** */
41.55 -/*
41.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
41.57 - * Use is subject to license terms.
41.58 - */
41.59 -
41.60 -#pragma ident "%Z%%M% %I% %E% SMI"
41.61 -
41.62 -#include <sys/types.h>
41.63 -
41.64 -#ifndef _WIN32
41.65 -#ifndef __linux__
41.66 -#include <sys/systm.h>
41.67 -#endif /* __linux__ */
41.68 -#include <sys/param.h>
41.69 -#endif /* _WIN32 */
41.70 -
41.71 -#ifdef _KERNEL
41.72 -#include <sys/kmem.h>
41.73 -#else
41.74 -#include <string.h>
41.75 -#endif
41.76 -#include "ec.h"
41.77 -#include "ecl-curve.h"
41.78 -#include "ecc_impl.h"
41.79 -#include "secoidt.h"
41.80 -
41.81 -#define CERTICOM_OID 0x2b, 0x81, 0x04
41.82 -#define SECG_OID CERTICOM_OID, 0x00
41.83 -
41.84 -#define ANSI_X962_OID 0x2a, 0x86, 0x48, 0xce, 0x3d
41.85 -#define ANSI_X962_CURVE_OID ANSI_X962_OID, 0x03
41.86 -#define ANSI_X962_GF2m_OID ANSI_X962_CURVE_OID, 0x00
41.87 -#define ANSI_X962_GFp_OID ANSI_X962_CURVE_OID, 0x01
41.88 -
41.89 -#define CONST_OID static const unsigned char
41.90 -
41.91 -/* ANSI X9.62 prime curve OIDs */
41.92 -/* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the
41.93 - * same as secp256r1
41.94 - */
41.95 -CONST_OID ansiX962prime192v1[] = { ANSI_X962_GFp_OID, 0x01 };
41.96 -CONST_OID ansiX962prime192v2[] = { ANSI_X962_GFp_OID, 0x02 };
41.97 -CONST_OID ansiX962prime192v3[] = { ANSI_X962_GFp_OID, 0x03 };
41.98 -CONST_OID ansiX962prime239v1[] = { ANSI_X962_GFp_OID, 0x04 };
41.99 -CONST_OID ansiX962prime239v2[] = { ANSI_X962_GFp_OID, 0x05 };
41.100 -CONST_OID ansiX962prime239v3[] = { ANSI_X962_GFp_OID, 0x06 };
41.101 -CONST_OID ansiX962prime256v1[] = { ANSI_X962_GFp_OID, 0x07 };
41.102 -
41.103 -/* SECG prime curve OIDs */
41.104 -CONST_OID secgECsecp112r1[] = { SECG_OID, 0x06 };
41.105 -CONST_OID secgECsecp112r2[] = { SECG_OID, 0x07 };
41.106 -CONST_OID secgECsecp128r1[] = { SECG_OID, 0x1c };
41.107 -CONST_OID secgECsecp128r2[] = { SECG_OID, 0x1d };
41.108 -CONST_OID secgECsecp160k1[] = { SECG_OID, 0x09 };
41.109 -CONST_OID secgECsecp160r1[] = { SECG_OID, 0x08 };
41.110 -CONST_OID secgECsecp160r2[] = { SECG_OID, 0x1e };
41.111 -CONST_OID secgECsecp192k1[] = { SECG_OID, 0x1f };
41.112 -CONST_OID secgECsecp224k1[] = { SECG_OID, 0x20 };
41.113 -CONST_OID secgECsecp224r1[] = { SECG_OID, 0x21 };
41.114 -CONST_OID secgECsecp256k1[] = { SECG_OID, 0x0a };
41.115 -CONST_OID secgECsecp384r1[] = { SECG_OID, 0x22 };
41.116 -CONST_OID secgECsecp521r1[] = { SECG_OID, 0x23 };
41.117 -
41.118 -/* SECG characterisitic two curve OIDs */
41.119 -CONST_OID secgECsect113r1[] = {SECG_OID, 0x04 };
41.120 -CONST_OID secgECsect113r2[] = {SECG_OID, 0x05 };
41.121 -CONST_OID secgECsect131r1[] = {SECG_OID, 0x16 };
41.122 -CONST_OID secgECsect131r2[] = {SECG_OID, 0x17 };
41.123 -CONST_OID secgECsect163k1[] = {SECG_OID, 0x01 };
41.124 -CONST_OID secgECsect163r1[] = {SECG_OID, 0x02 };
41.125 -CONST_OID secgECsect163r2[] = {SECG_OID, 0x0f };
41.126 -CONST_OID secgECsect193r1[] = {SECG_OID, 0x18 };
41.127 -CONST_OID secgECsect193r2[] = {SECG_OID, 0x19 };
41.128 -CONST_OID secgECsect233k1[] = {SECG_OID, 0x1a };
41.129 -CONST_OID secgECsect233r1[] = {SECG_OID, 0x1b };
41.130 -CONST_OID secgECsect239k1[] = {SECG_OID, 0x03 };
41.131 -CONST_OID secgECsect283k1[] = {SECG_OID, 0x10 };
41.132 -CONST_OID secgECsect283r1[] = {SECG_OID, 0x11 };
41.133 -CONST_OID secgECsect409k1[] = {SECG_OID, 0x24 };
41.134 -CONST_OID secgECsect409r1[] = {SECG_OID, 0x25 };
41.135 -CONST_OID secgECsect571k1[] = {SECG_OID, 0x26 };
41.136 -CONST_OID secgECsect571r1[] = {SECG_OID, 0x27 };
41.137 -
41.138 -/* ANSI X9.62 characteristic two curve OIDs */
41.139 -CONST_OID ansiX962c2pnb163v1[] = { ANSI_X962_GF2m_OID, 0x01 };
41.140 -CONST_OID ansiX962c2pnb163v2[] = { ANSI_X962_GF2m_OID, 0x02 };
41.141 -CONST_OID ansiX962c2pnb163v3[] = { ANSI_X962_GF2m_OID, 0x03 };
41.142 -CONST_OID ansiX962c2pnb176v1[] = { ANSI_X962_GF2m_OID, 0x04 };
41.143 -CONST_OID ansiX962c2tnb191v1[] = { ANSI_X962_GF2m_OID, 0x05 };
41.144 -CONST_OID ansiX962c2tnb191v2[] = { ANSI_X962_GF2m_OID, 0x06 };
41.145 -CONST_OID ansiX962c2tnb191v3[] = { ANSI_X962_GF2m_OID, 0x07 };
41.146 -CONST_OID ansiX962c2onb191v4[] = { ANSI_X962_GF2m_OID, 0x08 };
41.147 -CONST_OID ansiX962c2onb191v5[] = { ANSI_X962_GF2m_OID, 0x09 };
41.148 -CONST_OID ansiX962c2pnb208w1[] = { ANSI_X962_GF2m_OID, 0x0a };
41.149 -CONST_OID ansiX962c2tnb239v1[] = { ANSI_X962_GF2m_OID, 0x0b };
41.150 -CONST_OID ansiX962c2tnb239v2[] = { ANSI_X962_GF2m_OID, 0x0c };
41.151 -CONST_OID ansiX962c2tnb239v3[] = { ANSI_X962_GF2m_OID, 0x0d };
41.152 -CONST_OID ansiX962c2onb239v4[] = { ANSI_X962_GF2m_OID, 0x0e };
41.153 -CONST_OID ansiX962c2onb239v5[] = { ANSI_X962_GF2m_OID, 0x0f };
41.154 -CONST_OID ansiX962c2pnb272w1[] = { ANSI_X962_GF2m_OID, 0x10 };
41.155 -CONST_OID ansiX962c2pnb304w1[] = { ANSI_X962_GF2m_OID, 0x11 };
41.156 -CONST_OID ansiX962c2tnb359v1[] = { ANSI_X962_GF2m_OID, 0x12 };
41.157 -CONST_OID ansiX962c2pnb368w1[] = { ANSI_X962_GF2m_OID, 0x13 };
41.158 -CONST_OID ansiX962c2tnb431r1[] = { ANSI_X962_GF2m_OID, 0x14 };
41.159 -
41.160 -#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
41.161 -#ifndef SECOID_NO_STRINGS
41.162 -#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, desc, mech, ext }
41.163 -#else
41.164 -#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, 0, mech, ext }
41.165 -#endif
41.166 -
41.167 -#define CKM_INVALID_MECHANISM 0xffffffffUL
41.168 -
41.169 -/* XXX this is incorrect */
41.170 -#define INVALID_CERT_EXTENSION 1
41.171 -
41.172 -#define CKM_ECDSA 0x00001041
41.173 -#define CKM_ECDSA_SHA1 0x00001042
41.174 -#define CKM_ECDH1_DERIVE 0x00001050
41.175 -
41.176 -static SECOidData ANSI_prime_oids[] = {
41.177 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.178 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.179 -
41.180 - OD( ansiX962prime192v1, ECCurve_NIST_P192,
41.181 - "ANSI X9.62 elliptic curve prime192v1 (aka secp192r1, NIST P-192)",
41.182 - CKM_INVALID_MECHANISM,
41.183 - INVALID_CERT_EXTENSION ),
41.184 - OD( ansiX962prime192v2, ECCurve_X9_62_PRIME_192V2,
41.185 - "ANSI X9.62 elliptic curve prime192v2",
41.186 - CKM_INVALID_MECHANISM,
41.187 - INVALID_CERT_EXTENSION ),
41.188 - OD( ansiX962prime192v3, ECCurve_X9_62_PRIME_192V3,
41.189 - "ANSI X9.62 elliptic curve prime192v3",
41.190 - CKM_INVALID_MECHANISM,
41.191 - INVALID_CERT_EXTENSION ),
41.192 - OD( ansiX962prime239v1, ECCurve_X9_62_PRIME_239V1,
41.193 - "ANSI X9.62 elliptic curve prime239v1",
41.194 - CKM_INVALID_MECHANISM,
41.195 - INVALID_CERT_EXTENSION ),
41.196 - OD( ansiX962prime239v2, ECCurve_X9_62_PRIME_239V2,
41.197 - "ANSI X9.62 elliptic curve prime239v2",
41.198 - CKM_INVALID_MECHANISM,
41.199 - INVALID_CERT_EXTENSION ),
41.200 - OD( ansiX962prime239v3, ECCurve_X9_62_PRIME_239V3,
41.201 - "ANSI X9.62 elliptic curve prime239v3",
41.202 - CKM_INVALID_MECHANISM,
41.203 - INVALID_CERT_EXTENSION ),
41.204 - OD( ansiX962prime256v1, ECCurve_NIST_P256,
41.205 - "ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)",
41.206 - CKM_INVALID_MECHANISM,
41.207 - INVALID_CERT_EXTENSION )
41.208 -};
41.209 -
41.210 -static SECOidData SECG_oids[] = {
41.211 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.212 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.213 -
41.214 - OD( secgECsect163k1, ECCurve_NIST_K163,
41.215 - "SECG elliptic curve sect163k1 (aka NIST K-163)",
41.216 - CKM_INVALID_MECHANISM,
41.217 - INVALID_CERT_EXTENSION ),
41.218 - OD( secgECsect163r1, ECCurve_SECG_CHAR2_163R1,
41.219 - "SECG elliptic curve sect163r1",
41.220 - CKM_INVALID_MECHANISM,
41.221 - INVALID_CERT_EXTENSION ),
41.222 - OD( secgECsect239k1, ECCurve_SECG_CHAR2_239K1,
41.223 - "SECG elliptic curve sect239k1",
41.224 - CKM_INVALID_MECHANISM,
41.225 - INVALID_CERT_EXTENSION ),
41.226 - OD( secgECsect113r1, ECCurve_SECG_CHAR2_113R1,
41.227 - "SECG elliptic curve sect113r1",
41.228 - CKM_INVALID_MECHANISM,
41.229 - INVALID_CERT_EXTENSION ),
41.230 - OD( secgECsect113r2, ECCurve_SECG_CHAR2_113R2,
41.231 - "SECG elliptic curve sect113r2",
41.232 - CKM_INVALID_MECHANISM,
41.233 - INVALID_CERT_EXTENSION ),
41.234 - OD( secgECsecp112r1, ECCurve_SECG_PRIME_112R1,
41.235 - "SECG elliptic curve secp112r1",
41.236 - CKM_INVALID_MECHANISM,
41.237 - INVALID_CERT_EXTENSION ),
41.238 - OD( secgECsecp112r2, ECCurve_SECG_PRIME_112R2,
41.239 - "SECG elliptic curve secp112r2",
41.240 - CKM_INVALID_MECHANISM,
41.241 - INVALID_CERT_EXTENSION ),
41.242 - OD( secgECsecp160r1, ECCurve_SECG_PRIME_160R1,
41.243 - "SECG elliptic curve secp160r1",
41.244 - CKM_INVALID_MECHANISM,
41.245 - INVALID_CERT_EXTENSION ),
41.246 - OD( secgECsecp160k1, ECCurve_SECG_PRIME_160K1,
41.247 - "SECG elliptic curve secp160k1",
41.248 - CKM_INVALID_MECHANISM,
41.249 - INVALID_CERT_EXTENSION ),
41.250 - OD( secgECsecp256k1, ECCurve_SECG_PRIME_256K1,
41.251 - "SECG elliptic curve secp256k1",
41.252 - CKM_INVALID_MECHANISM,
41.253 - INVALID_CERT_EXTENSION ),
41.254 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.255 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.256 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.257 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.258 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.259 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.260 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.261 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.262 - OD( secgECsect163r2, ECCurve_NIST_B163,
41.263 - "SECG elliptic curve sect163r2 (aka NIST B-163)",
41.264 - CKM_INVALID_MECHANISM,
41.265 - INVALID_CERT_EXTENSION ),
41.266 - OD( secgECsect283k1, ECCurve_NIST_K283,
41.267 - "SECG elliptic curve sect283k1 (aka NIST K-283)",
41.268 - CKM_INVALID_MECHANISM,
41.269 - INVALID_CERT_EXTENSION ),
41.270 - OD( secgECsect283r1, ECCurve_NIST_B283,
41.271 - "SECG elliptic curve sect283r1 (aka NIST B-283)",
41.272 - CKM_INVALID_MECHANISM,
41.273 - INVALID_CERT_EXTENSION ),
41.274 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.275 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.276 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.277 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.278 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.279 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.280 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.281 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.282 - OD( secgECsect131r1, ECCurve_SECG_CHAR2_131R1,
41.283 - "SECG elliptic curve sect131r1",
41.284 - CKM_INVALID_MECHANISM,
41.285 - INVALID_CERT_EXTENSION ),
41.286 - OD( secgECsect131r2, ECCurve_SECG_CHAR2_131R2,
41.287 - "SECG elliptic curve sect131r2",
41.288 - CKM_INVALID_MECHANISM,
41.289 - INVALID_CERT_EXTENSION ),
41.290 - OD( secgECsect193r1, ECCurve_SECG_CHAR2_193R1,
41.291 - "SECG elliptic curve sect193r1",
41.292 - CKM_INVALID_MECHANISM,
41.293 - INVALID_CERT_EXTENSION ),
41.294 - OD( secgECsect193r2, ECCurve_SECG_CHAR2_193R2,
41.295 - "SECG elliptic curve sect193r2",
41.296 - CKM_INVALID_MECHANISM,
41.297 - INVALID_CERT_EXTENSION ),
41.298 - OD( secgECsect233k1, ECCurve_NIST_K233,
41.299 - "SECG elliptic curve sect233k1 (aka NIST K-233)",
41.300 - CKM_INVALID_MECHANISM,
41.301 - INVALID_CERT_EXTENSION ),
41.302 - OD( secgECsect233r1, ECCurve_NIST_B233,
41.303 - "SECG elliptic curve sect233r1 (aka NIST B-233)",
41.304 - CKM_INVALID_MECHANISM,
41.305 - INVALID_CERT_EXTENSION ),
41.306 - OD( secgECsecp128r1, ECCurve_SECG_PRIME_128R1,
41.307 - "SECG elliptic curve secp128r1",
41.308 - CKM_INVALID_MECHANISM,
41.309 - INVALID_CERT_EXTENSION ),
41.310 - OD( secgECsecp128r2, ECCurve_SECG_PRIME_128R2,
41.311 - "SECG elliptic curve secp128r2",
41.312 - CKM_INVALID_MECHANISM,
41.313 - INVALID_CERT_EXTENSION ),
41.314 - OD( secgECsecp160r2, ECCurve_SECG_PRIME_160R2,
41.315 - "SECG elliptic curve secp160r2",
41.316 - CKM_INVALID_MECHANISM,
41.317 - INVALID_CERT_EXTENSION ),
41.318 - OD( secgECsecp192k1, ECCurve_SECG_PRIME_192K1,
41.319 - "SECG elliptic curve secp192k1",
41.320 - CKM_INVALID_MECHANISM,
41.321 - INVALID_CERT_EXTENSION ),
41.322 - OD( secgECsecp224k1, ECCurve_SECG_PRIME_224K1,
41.323 - "SECG elliptic curve secp224k1",
41.324 - CKM_INVALID_MECHANISM,
41.325 - INVALID_CERT_EXTENSION ),
41.326 - OD( secgECsecp224r1, ECCurve_NIST_P224,
41.327 - "SECG elliptic curve secp224r1 (aka NIST P-224)",
41.328 - CKM_INVALID_MECHANISM,
41.329 - INVALID_CERT_EXTENSION ),
41.330 - OD( secgECsecp384r1, ECCurve_NIST_P384,
41.331 - "SECG elliptic curve secp384r1 (aka NIST P-384)",
41.332 - CKM_INVALID_MECHANISM,
41.333 - INVALID_CERT_EXTENSION ),
41.334 - OD( secgECsecp521r1, ECCurve_NIST_P521,
41.335 - "SECG elliptic curve secp521r1 (aka NIST P-521)",
41.336 - CKM_INVALID_MECHANISM,
41.337 - INVALID_CERT_EXTENSION ),
41.338 - OD( secgECsect409k1, ECCurve_NIST_K409,
41.339 - "SECG elliptic curve sect409k1 (aka NIST K-409)",
41.340 - CKM_INVALID_MECHANISM,
41.341 - INVALID_CERT_EXTENSION ),
41.342 - OD( secgECsect409r1, ECCurve_NIST_B409,
41.343 - "SECG elliptic curve sect409r1 (aka NIST B-409)",
41.344 - CKM_INVALID_MECHANISM,
41.345 - INVALID_CERT_EXTENSION ),
41.346 - OD( secgECsect571k1, ECCurve_NIST_K571,
41.347 - "SECG elliptic curve sect571k1 (aka NIST K-571)",
41.348 - CKM_INVALID_MECHANISM,
41.349 - INVALID_CERT_EXTENSION ),
41.350 - OD( secgECsect571r1, ECCurve_NIST_B571,
41.351 - "SECG elliptic curve sect571r1 (aka NIST B-571)",
41.352 - CKM_INVALID_MECHANISM,
41.353 - INVALID_CERT_EXTENSION )
41.354 -};
41.355 -
41.356 -static SECOidData ANSI_oids[] = {
41.357 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.358 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.359 -
41.360 - /* ANSI X9.62 named elliptic curves (characteristic two field) */
41.361 - OD( ansiX962c2pnb163v1, ECCurve_X9_62_CHAR2_PNB163V1,
41.362 - "ANSI X9.62 elliptic curve c2pnb163v1",
41.363 - CKM_INVALID_MECHANISM,
41.364 - INVALID_CERT_EXTENSION ),
41.365 - OD( ansiX962c2pnb163v2, ECCurve_X9_62_CHAR2_PNB163V2,
41.366 - "ANSI X9.62 elliptic curve c2pnb163v2",
41.367 - CKM_INVALID_MECHANISM,
41.368 - INVALID_CERT_EXTENSION ),
41.369 - OD( ansiX962c2pnb163v3, ECCurve_X9_62_CHAR2_PNB163V3,
41.370 - "ANSI X9.62 elliptic curve c2pnb163v3",
41.371 - CKM_INVALID_MECHANISM,
41.372 - INVALID_CERT_EXTENSION ),
41.373 - OD( ansiX962c2pnb176v1, ECCurve_X9_62_CHAR2_PNB176V1,
41.374 - "ANSI X9.62 elliptic curve c2pnb176v1",
41.375 - CKM_INVALID_MECHANISM,
41.376 - INVALID_CERT_EXTENSION ),
41.377 - OD( ansiX962c2tnb191v1, ECCurve_X9_62_CHAR2_TNB191V1,
41.378 - "ANSI X9.62 elliptic curve c2tnb191v1",
41.379 - CKM_INVALID_MECHANISM,
41.380 - INVALID_CERT_EXTENSION ),
41.381 - OD( ansiX962c2tnb191v2, ECCurve_X9_62_CHAR2_TNB191V2,
41.382 - "ANSI X9.62 elliptic curve c2tnb191v2",
41.383 - CKM_INVALID_MECHANISM,
41.384 - INVALID_CERT_EXTENSION ),
41.385 - OD( ansiX962c2tnb191v3, ECCurve_X9_62_CHAR2_TNB191V3,
41.386 - "ANSI X9.62 elliptic curve c2tnb191v3",
41.387 - CKM_INVALID_MECHANISM,
41.388 - INVALID_CERT_EXTENSION ),
41.389 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.390 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.391 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.392 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.393 - OD( ansiX962c2pnb208w1, ECCurve_X9_62_CHAR2_PNB208W1,
41.394 - "ANSI X9.62 elliptic curve c2pnb208w1",
41.395 - CKM_INVALID_MECHANISM,
41.396 - INVALID_CERT_EXTENSION ),
41.397 - OD( ansiX962c2tnb239v1, ECCurve_X9_62_CHAR2_TNB239V1,
41.398 - "ANSI X9.62 elliptic curve c2tnb239v1",
41.399 - CKM_INVALID_MECHANISM,
41.400 - INVALID_CERT_EXTENSION ),
41.401 - OD( ansiX962c2tnb239v2, ECCurve_X9_62_CHAR2_TNB239V2,
41.402 - "ANSI X9.62 elliptic curve c2tnb239v2",
41.403 - CKM_INVALID_MECHANISM,
41.404 - INVALID_CERT_EXTENSION ),
41.405 - OD( ansiX962c2tnb239v3, ECCurve_X9_62_CHAR2_TNB239V3,
41.406 - "ANSI X9.62 elliptic curve c2tnb239v3",
41.407 - CKM_INVALID_MECHANISM,
41.408 - INVALID_CERT_EXTENSION ),
41.409 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.410 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.411 - { { siDEROID, NULL, 0 }, ECCurve_noName,
41.412 - "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
41.413 - OD( ansiX962c2pnb272w1, ECCurve_X9_62_CHAR2_PNB272W1,
41.414 - "ANSI X9.62 elliptic curve c2pnb272w1",
41.415 - CKM_INVALID_MECHANISM,
41.416 - INVALID_CERT_EXTENSION ),
41.417 - OD( ansiX962c2pnb304w1, ECCurve_X9_62_CHAR2_PNB304W1,
41.418 - "ANSI X9.62 elliptic curve c2pnb304w1",
41.419 - CKM_INVALID_MECHANISM,
41.420 - INVALID_CERT_EXTENSION ),
41.421 - OD( ansiX962c2tnb359v1, ECCurve_X9_62_CHAR2_TNB359V1,
41.422 - "ANSI X9.62 elliptic curve c2tnb359v1",
41.423 - CKM_INVALID_MECHANISM,
41.424 - INVALID_CERT_EXTENSION ),
41.425 - OD( ansiX962c2pnb368w1, ECCurve_X9_62_CHAR2_PNB368W1,
41.426 - "ANSI X9.62 elliptic curve c2pnb368w1",
41.427 - CKM_INVALID_MECHANISM,
41.428 - INVALID_CERT_EXTENSION ),
41.429 - OD( ansiX962c2tnb431r1, ECCurve_X9_62_CHAR2_TNB431R1,
41.430 - "ANSI X9.62 elliptic curve c2tnb431r1",
41.431 - CKM_INVALID_MECHANISM,
41.432 - INVALID_CERT_EXTENSION )
41.433 -};
41.434 -
41.435 -SECOidData *
41.436 -SECOID_FindOID(const SECItem *oid)
41.437 -{
41.438 - SECOidData *po;
41.439 - SECOidData *ret;
41.440 - int i;
41.441 -
41.442 - if (oid->len == 8) {
41.443 - if (oid->data[6] == 0x00) {
41.444 - /* XXX bounds check */
41.445 - po = &ANSI_oids[oid->data[7]];
41.446 - if (memcmp(oid->data, po->oid.data, 8) == 0)
41.447 - ret = po;
41.448 - }
41.449 - if (oid->data[6] == 0x01) {
41.450 - /* XXX bounds check */
41.451 - po = &ANSI_prime_oids[oid->data[7]];
41.452 - if (memcmp(oid->data, po->oid.data, 8) == 0)
41.453 - ret = po;
41.454 - }
41.455 - } else if (oid->len == 5) {
41.456 - /* XXX bounds check */
41.457 - po = &SECG_oids[oid->data[4]];
41.458 - if (memcmp(oid->data, po->oid.data, 5) == 0)
41.459 - ret = po;
41.460 - } else {
41.461 - ret = NULL;
41.462 - }
41.463 - return(ret);
41.464 -}
41.465 -
41.466 -ECCurveName
41.467 -SECOID_FindOIDTag(const SECItem *oid)
41.468 -{
41.469 - SECOidData *oiddata;
41.470 -
41.471 - oiddata = SECOID_FindOID (oid);
41.472 - if (oiddata == NULL)
41.473 - return ECCurve_noName;
41.474 -
41.475 - return oiddata->offset;
41.476 -}
42.1 --- a/src/share/native/sun/security/ec/secitem.c Tue Oct 13 15:25:58 2009 -0700
42.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
42.3 @@ -1,199 +0,0 @@
42.4 -/* *********************************************************************
42.5 - *
42.6 - * Sun elects to have this file available under and governed by the
42.7 - * Mozilla Public License Version 1.1 ("MPL") (see
42.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
42.9 - * of doubt and subject to the following, Sun also elects to allow
42.10 - * licensees to use this file under the MPL, the GNU General Public
42.11 - * License version 2 only or the Lesser General Public License version
42.12 - * 2.1 only. Any references to the "GNU General Public License version 2
42.13 - * or later" or "GPL" in the following shall be construed to mean the
42.14 - * GNU General Public License version 2 only. Any references to the "GNU
42.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
42.16 - * following shall be construed to mean the GNU Lesser General Public
42.17 - * License version 2.1 only. However, the following notice accompanied
42.18 - * the original version of this file:
42.19 - *
42.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
42.21 - *
42.22 - * The contents of this file are subject to the Mozilla Public License Version
42.23 - * 1.1 (the "License"); you may not use this file except in compliance with
42.24 - * the License. You may obtain a copy of the License at
42.25 - * http://www.mozilla.org/MPL/
42.26 - *
42.27 - * Software distributed under the License is distributed on an "AS IS" basis,
42.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
42.29 - * for the specific language governing rights and limitations under the
42.30 - * License.
42.31 - *
42.32 - * The Original Code is the Netscape security libraries.
42.33 - *
42.34 - * The Initial Developer of the Original Code is
42.35 - * Netscape Communications Corporation.
42.36 - * Portions created by the Initial Developer are Copyright (C) 1994-2000
42.37 - * the Initial Developer. All Rights Reserved.
42.38 - *
42.39 - * Contributor(s):
42.40 - *
42.41 - * Alternatively, the contents of this file may be used under the terms of
42.42 - * either the GNU General Public License Version 2 or later (the "GPL"), or
42.43 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
42.44 - * in which case the provisions of the GPL or the LGPL are applicable instead
42.45 - * of those above. If you wish to allow use of your version of this file only
42.46 - * under the terms of either the GPL or the LGPL, and not to allow others to
42.47 - * use your version of this file under the terms of the MPL, indicate your
42.48 - * decision by deleting the provisions above and replace them with the notice
42.49 - * and other provisions required by the GPL or the LGPL. If you do not delete
42.50 - * the provisions above, a recipient may use your version of this file under
42.51 - * the terms of any one of the MPL, the GPL or the LGPL.
42.52 - *
42.53 - *********************************************************************** */
42.54 -/*
42.55 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
42.56 - * Use is subject to license terms.
42.57 - */
42.58 -
42.59 -#pragma ident "%Z%%M% %I% %E% SMI"
42.60 -
42.61 -/*
42.62 - * Support routines for SECItem data structure.
42.63 - *
42.64 - * $Id: secitem.c,v 1.14 2006/05/22 22:24:34 wtchang%redhat.com Exp $
42.65 - */
42.66 -
42.67 -#include <sys/types.h>
42.68 -
42.69 -#ifndef _WIN32
42.70 -#ifndef __linux__
42.71 -#include <sys/systm.h>
42.72 -#endif /* __linux__ */
42.73 -#include <sys/param.h>
42.74 -#endif /* _WIN32 */
42.75 -
42.76 -#ifdef _KERNEL
42.77 -#include <sys/kmem.h>
42.78 -#else
42.79 -#include <string.h>
42.80 -
42.81 -#ifndef _WIN32
42.82 -#include <strings.h>
42.83 -#endif /* _WIN32 */
42.84 -
42.85 -#include <assert.h>
42.86 -#endif
42.87 -#include "ec.h"
42.88 -#include "ecl-curve.h"
42.89 -#include "ecc_impl.h"
42.90 -
42.91 -void SECITEM_FreeItem(SECItem *, PRBool);
42.92 -
42.93 -SECItem *
42.94 -SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len,
42.95 - int kmflag)
42.96 -{
42.97 - SECItem *result = NULL;
42.98 - void *mark = NULL;
42.99 -
42.100 - if (arena != NULL) {
42.101 - mark = PORT_ArenaMark(arena);
42.102 - }
42.103 -
42.104 - if (item == NULL) {
42.105 - if (arena != NULL) {
42.106 - result = PORT_ArenaZAlloc(arena, sizeof(SECItem), kmflag);
42.107 - } else {
42.108 - result = PORT_ZAlloc(sizeof(SECItem), kmflag);
42.109 - }
42.110 - if (result == NULL) {
42.111 - goto loser;
42.112 - }
42.113 - } else {
42.114 - PORT_Assert(item->data == NULL);
42.115 - result = item;
42.116 - }
42.117 -
42.118 - result->len = len;
42.119 - if (len) {
42.120 - if (arena != NULL) {
42.121 - result->data = PORT_ArenaAlloc(arena, len, kmflag);
42.122 - } else {
42.123 - result->data = PORT_Alloc(len, kmflag);
42.124 - }
42.125 - if (result->data == NULL) {
42.126 - goto loser;
42.127 - }
42.128 - } else {
42.129 - result->data = NULL;
42.130 - }
42.131 -
42.132 - if (mark) {
42.133 - PORT_ArenaUnmark(arena, mark);
42.134 - }
42.135 - return(result);
42.136 -
42.137 -loser:
42.138 - if ( arena != NULL ) {
42.139 - if (mark) {
42.140 - PORT_ArenaRelease(arena, mark);
42.141 - }
42.142 - if (item != NULL) {
42.143 - item->data = NULL;
42.144 - item->len = 0;
42.145 - }
42.146 - } else {
42.147 - if (result != NULL) {
42.148 - SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE);
42.149 - }
42.150 - /*
42.151 - * If item is not NULL, the above has set item->data and
42.152 - * item->len to 0.
42.153 - */
42.154 - }
42.155 - return(NULL);
42.156 -}
42.157 -
42.158 -SECStatus
42.159 -SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from,
42.160 - int kmflag)
42.161 -{
42.162 - to->type = from->type;
42.163 - if (from->data && from->len) {
42.164 - if ( arena ) {
42.165 - to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len,
42.166 - kmflag);
42.167 - } else {
42.168 - to->data = (unsigned char*) PORT_Alloc(from->len, kmflag);
42.169 - }
42.170 -
42.171 - if (!to->data) {
42.172 - return SECFailure;
42.173 - }
42.174 - PORT_Memcpy(to->data, from->data, from->len);
42.175 - to->len = from->len;
42.176 - } else {
42.177 - to->data = 0;
42.178 - to->len = 0;
42.179 - }
42.180 - return SECSuccess;
42.181 -}
42.182 -
42.183 -void
42.184 -SECITEM_FreeItem(SECItem *zap, PRBool freeit)
42.185 -{
42.186 - if (zap) {
42.187 -#ifdef _KERNEL
42.188 - kmem_free(zap->data, zap->len);
42.189 -#else
42.190 - free(zap->data);
42.191 -#endif
42.192 - zap->data = 0;
42.193 - zap->len = 0;
42.194 - if (freeit) {
42.195 -#ifdef _KERNEL
42.196 - kmem_free(zap, sizeof (SECItem));
42.197 -#else
42.198 - free(zap);
42.199 -#endif
42.200 - }
42.201 - }
42.202 -}
43.1 --- a/src/share/native/sun/security/ec/secoidt.h Tue Oct 13 15:25:58 2009 -0700
43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
43.3 @@ -1,103 +0,0 @@
43.4 -/* *********************************************************************
43.5 - *
43.6 - * Sun elects to have this file available under and governed by the
43.7 - * Mozilla Public License Version 1.1 ("MPL") (see
43.8 - * http://www.mozilla.org/MPL/ for full license text). For the avoidance
43.9 - * of doubt and subject to the following, Sun also elects to allow
43.10 - * licensees to use this file under the MPL, the GNU General Public
43.11 - * License version 2 only or the Lesser General Public License version
43.12 - * 2.1 only. Any references to the "GNU General Public License version 2
43.13 - * or later" or "GPL" in the following shall be construed to mean the
43.14 - * GNU General Public License version 2 only. Any references to the "GNU
43.15 - * Lesser General Public License version 2.1 or later" or "LGPL" in the
43.16 - * following shall be construed to mean the GNU Lesser General Public
43.17 - * License version 2.1 only. However, the following notice accompanied
43.18 - * the original version of this file:
43.19 - *
43.20 - * Version: MPL 1.1/GPL 2.0/LGPL 2.1
43.21 - *
43.22 - * The contents of this file are subject to the Mozilla Public License Version
43.23 - * 1.1 (the "License"); you may not use this file except in compliance with
43.24 - * the License. You may obtain a copy of the License at
43.25 - * http://www.mozilla.org/MPL/
43.26 - *
43.27 - * Software distributed under the License is distributed on an "AS IS" basis,
43.28 - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
43.29 - * for the specific language governing rights and limitations under the
43.30 - * License.
43.31 - *
43.32 - * The Original Code is the Netscape security libraries.
43.33 - *
43.34 - * The Initial Developer of the Original Code is
43.35 - * Netscape Communications Corporation.
43.36 - * Portions created by the Initial Developer are Copyright (C) 1994-2000
43.37 - * the Initial Developer. All Rights Reserved.
43.38 - *
43.39 - * Contributor(s):
43.40 - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
43.41 - *
43.42 - * Alternatively, the contents of this file may be used under the terms of
43.43 - * either the GNU General Public License Version 2 or later (the "GPL"), or
43.44 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
43.45 - * in which case the provisions of the GPL or the LGPL are applicable instead
43.46 - * of those above. If you wish to allow use of your version of this file only
43.47 - * under the terms of either the GPL or the LGPL, and not to allow others to
43.48 - * use your version of this file under the terms of the MPL, indicate your
43.49 - * decision by deleting the provisions above and replace them with the notice
43.50 - * and other provisions required by the GPL or the LGPL. If you do not delete
43.51 - * the provisions above, a recipient may use your version of this file under
43.52 - * the terms of any one of the MPL, the GPL or the LGPL.
43.53 - *
43.54 - *********************************************************************** */
43.55 -/*
43.56 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
43.57 - * Use is subject to license terms.
43.58 - */
43.59 -
43.60 -#ifndef _SECOIDT_H_
43.61 -#define _SECOIDT_H_
43.62 -
43.63 -#pragma ident "%Z%%M% %I% %E% SMI"
43.64 -
43.65 -/*
43.66 - * secoidt.h - public data structures for ASN.1 OID functions
43.67 - *
43.68 - * $Id: secoidt.h,v 1.23 2007/05/05 22:45:16 nelson%bolyard.com Exp $
43.69 - */
43.70 -
43.71 -typedef struct SECOidDataStr SECOidData;
43.72 -typedef struct SECAlgorithmIDStr SECAlgorithmID;
43.73 -
43.74 -/*
43.75 -** An X.500 algorithm identifier
43.76 -*/
43.77 -struct SECAlgorithmIDStr {
43.78 - SECItem algorithm;
43.79 - SECItem parameters;
43.80 -};
43.81 -
43.82 -#define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
43.83 -#define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
43.84 -#define SEC_OID_PKCS12_KEY_USAGE SEC_OID_X509_KEY_USAGE
43.85 -
43.86 -/* fake OID for DSS sign/verify */
43.87 -#define SEC_OID_SHA SEC_OID_MISS_DSS
43.88 -
43.89 -typedef enum {
43.90 - INVALID_CERT_EXTENSION = 0,
43.91 - UNSUPPORTED_CERT_EXTENSION = 1,
43.92 - SUPPORTED_CERT_EXTENSION = 2
43.93 -} SECSupportExtenTag;
43.94 -
43.95 -struct SECOidDataStr {
43.96 - SECItem oid;
43.97 - ECCurveName offset;
43.98 - const char * desc;
43.99 - unsigned long mechanism;
43.100 - SECSupportExtenTag supportedExtension;
43.101 - /* only used for x.509 v3 extensions, so
43.102 - that we can print the names of those
43.103 - extensions that we don't even support */
43.104 -};
43.105 -
43.106 -#endif /* _SECOIDT_H_ */