Donatien Garnier / MiniTLS-GPL

Dependents:   MiniTLS-HTTPS-Example

crypto/ltc/ltc_ecc_projective_add_point.c

Committer:
MiniTLS
Date:
2014-06-09
Revision:
2:527a66d0a1a9

File content as of revision 2:527a66d0a1a9:

/*
MiniTLS - A super trimmed down TLS/SSL Library for embedded devices
Author: Donatien Garnier
Copyright (C) 2013-2014 AppNearMe Ltd

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*//* LibTomCrypt, modular cryptographic library -- Tom St Denis
 *
 * LibTomCrypt is a library that provides various cryptographic
 * algorithms in a highly modular and flexible manner.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 *
 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
 */

/* Implements ECC over Z/pZ for curve &y^2 = &x^3 - 3x + b
 *
 * All curves taken from NIST recommendation paper of July 1999
 * Available at http://csrc.nist.gov/cryptval/dss.htm
 */
#include "ltc.h"

/**
  @file ltc_ecc_projective_add_point.c
  ECC Crypto, Tom St Denis
*/  

#if defined(LTC_MECC) & (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))

/**
   Add two ECC points
   @param P        The point to add
   @param Q        The point to add
   @param R        [out] The destination of the double
   @param modulus  The modulus of the field the ECC curve is in
   @param mp       The "b" value from montgomery_setup()
   @return MINITLS_OK on success
*/
int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
{
   fp_int  t1, t2, x, y, z;
   int    err;

   LTC_ARGCHK(P       != NULL);
   LTC_ARGCHK(Q       != NULL);
   LTC_ARGCHK(R       != NULL);
   LTC_ARGCHK(modulus != NULL);
   LTC_ARGCHK(mp      != NULL);

   if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MINITLS_OK) {
      return err;
   }
   
   /* should we dbl instead? */
   /*if ((err =*/ mp_sub(modulus, &Q->y, &t1);/*) != MINITLS_OK)                          { goto done; }*/

   if ( (mp_cmp(&P->x, &Q->x) == MP_EQ) &&
        ((&Q->z != NULL) && mp_cmp(&P->z, &Q->z) == MP_EQ) &&
        (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &t1) == MP_EQ)) {
        mp_clear_multi(&t1, &t2, &x, &y, &z, NULL);
        return ltc_ecc_projective_dbl_point(P, R, modulus, mp);
   }

   /*if ((err =*/ mp_copy(&P->x, &x);/*) != MINITLS_OK)                                   { goto done; }*/
   /*if ((err =*/ mp_copy(&P->y, &y);/*) != MINITLS_OK)                                   { goto done; }*/
   /*if ((err =*/ mp_copy(&P->z, &z);/*) != MINITLS_OK)                                   { goto done; }*/

   /* if Z is one then these are no-operations */
   if (&Q->z != NULL) {
      /* T1 = Z' * Z' */
      /*if ((err = */mp_sqr(&Q->z, &t1);/*) != MINITLS_OK)                                { goto done; }*/
      /*if ((err = */mp_montgomery_reduce(&t1, modulus, mp);/*) != MINITLS_OK)           { goto done; }*/
      /* X = X * T1 */
      /*if ((err = */mp_mul(&t1, &x, &x);/*) != MINITLS_OK)                                { goto done; }*/
      /*if ((err = */mp_montgomery_reduce(&x, modulus, mp);/*) != MINITLS_OK)            { goto done; }*/
      /* T1 = Z' * T1 */
      /*if ((err = */mp_mul(&Q->z, &t1, &t1);/*) != MINITLS_OK)                            { goto done; }*/
      /*if ((err = */mp_montgomery_reduce(&t1, modulus, mp);/*) != MINITLS_OK)           { goto done; }*/
      /* Y = Y * T1 */
      /*if ((err = */mp_mul(&t1, &y, &y);/*) != MINITLS_OK)                                { goto done; }*/
      /*if ((err = */mp_montgomery_reduce(&y, modulus, mp);/*) != MINITLS_OK)            { goto done; }*/
   }

   /* T1 = Z*Z */
   /*if ((err = */mp_sqr(&z, &t1);/*) != MINITLS_OK)                                      { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t1, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/
   /* T2 = X' * T1 */
   /*if ((err = */mp_mul(&Q->x, &t1, &t2);/*) != MINITLS_OK)                               { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t2, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/
   /* T1 = Z * T1 */
   /*if ((err = */mp_mul(&z, &t1, &t1);/*) != MINITLS_OK)                                  { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t1, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/
   /* T1 = Y' * T1 */
   /*if ((err = */mp_mul(&Q->y, &t1, &t1);/*) != MINITLS_OK)                               { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t1, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/

   /* Y = Y - T1 */
   /*if ((err = */mp_sub(&y, &t1, &y);/*) != MINITLS_OK)                                   { goto done; }*/
   if (mp_cmp_d(&y, 0) == MP_LT) {
      /*if ((err = */mp_add(&y, modulus, &y);/*) != MINITLS_OK)                           { goto done; }*/
   }
   /* T1 = 2T1 */
   /*if ((err = */mp_add(&t1, &t1, &t1);/*) != MINITLS_OK)                                 { goto done; }*/
   if (mp_cmp(&t1, modulus) != MP_LT) {
      /*if ((err = */mp_sub(&t1, modulus, &t1);/*) != MINITLS_OK)                         { goto done; }*/
   }
   /* T1 = Y + T1 */
   /*if ((err = */mp_add(&t1, &y, &t1);/*) != MINITLS_OK)                                  { goto done; }*/
   if (mp_cmp(&t1, modulus) != MP_LT) {
      /*if ((err = */mp_sub(&t1, modulus, &t1);/*) != MINITLS_OK)                         { goto done; }*/
   }
   /* X = X - T2 */
   /*if ((err = */mp_sub(&x, &t2, &x);/*) != MINITLS_OK)                                   { goto done; }*/
   if (mp_cmp_d(&x, 0) == MP_LT) {
      /*if ((err = */mp_add(&x, modulus, &x);/*) != MINITLS_OK)                           { goto done; }*/
   }
   /* T2 = 2T2 */
   /*if ((err = */mp_add(&t2, &t2, &t2);/*) != MINITLS_OK)                                 { goto done; }*/
   if (mp_cmp(&t2, modulus) != MP_LT) {
      /*if ((err = */mp_sub(&t2, modulus, &t2);/*) != MINITLS_OK)                         { goto done; }*/
   }
   /* T2 = X + T2 */
   /*if ((err = */mp_add(&t2, &x, &t2);/*) != MINITLS_OK)                                  { goto done; }*/
   if (mp_cmp(&t2, modulus) != MP_LT) {
      /*if ((err = */mp_sub(&t2, modulus, &t2);/*) != MINITLS_OK)                         { goto done; }*/
   }

   /* if Z' != 1 */
   if (&Q->z != NULL) {
      /* Z = Z * Z' */
      /*if ((err = */mp_mul(&z, &Q->z, &z);/*) != MINITLS_OK)                              { goto done; }*/
      /*if ((err = */mp_montgomery_reduce(&z, modulus, mp);/*) != MINITLS_OK)            { goto done; }*/
   }

   /* Z = Z * X */
   /*if ((err = */mp_mul(&z, &x, &z);/*) != MINITLS_OK)                                    { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&z, modulus, mp);/*) != MINITLS_OK)               { goto done; }*/

   /* T1 = T1 * X  */
   /*if ((err = */mp_mul(&t1, &x, &t1);/*) != MINITLS_OK)                                  { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t1, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/
   /* X = X * X */
   /*if ((err = */mp_sqr(&x, &x);/*) != MINITLS_OK)                                       { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&x, modulus, mp);/*) != MINITLS_OK)               { goto done; }*/
   /* T2 = T2 * &x */
   /*if ((err = */mp_mul(&t2, &x, &t2);/*) != MINITLS_OK)                                  { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t2, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/
   /* T1 = T1 * X  */
   /*if ((err = */mp_mul(&t1, &x, &t1);/*) != MINITLS_OK)                                  { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t1, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/
 
   /* X = Y*Y */
   /*if ((err = */mp_sqr(&y, &x);/*) != MINITLS_OK)                                       { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&x, modulus, mp);/*) != MINITLS_OK)               { goto done; }*/
   /* X = X - T2 */
   /*if ((err = */mp_sub(&x, &t2, &x);/*) != MINITLS_OK)                                   { goto done; }*/
   if (mp_cmp_d(&x, 0) == MP_LT) {
      /*if ((err = */mp_add(&x, modulus, &x);/*) != MINITLS_OK)                           { goto done; }*/
   }

   /* T2 = T2 - X */
   /*if ((err = */mp_sub(&t2, &x, &t2);/*) != MINITLS_OK)                                  { goto done; }*/
   if (mp_cmp_d(&t2, 0) == MP_LT) {
      /*if ((err = */mp_add(&t2, modulus, &t2);/*) != MINITLS_OK)                         { goto done; }*/
   } 
   /* T2 = T2 - X */
   /*if ((err = */mp_sub(&t2, &x, &t2);/*) != MINITLS_OK)                                  { goto done; }*/
   if (mp_cmp_d(&t2, 0) == MP_LT) {
      /*if ((err = */mp_add(&t2, modulus, &t2);/*) != MINITLS_OK)                         { goto done; }*/
   }
   /* T2 = T2 * Y */
   /*if ((err = */mp_mul(&t2, &y, &t2);/*) != MINITLS_OK)                                  { goto done; }*/
   /*if ((err = */mp_montgomery_reduce(&t2, modulus, mp);/*) != MINITLS_OK)              { goto done; }*/
   /* Y = T2 - T1 */
   /*if ((err = */mp_sub(&t2, &t1, &y);/*) != MINITLS_OK)                                  { goto done; }*/
   if (mp_cmp_d(&y, 0) == MP_LT) {
      /*if ((err = */mp_add(&y, modulus, &y);/*) != MINITLS_OK)                           { goto done; }*/
   }
   /* Y = Y/2 */
   if (mp_isodd(&y)) {
      /*if ((err = */mp_add(&y, modulus, &y);/*) != MINITLS_OK)                           { goto done; }*/
   }
   /*if ((err = */mp_div_2(&y, &y);/*) != MINITLS_OK)                                     { goto done; }*/

   /*if ((err = */mp_copy(&x, &R->x);/*) != MINITLS_OK)                                   { goto done; }*/
   /*if ((err = */mp_copy(&y, &R->y);/*) != MINITLS_OK)                                   { goto done; }*/
   /*if ((err = */mp_copy(&z, &R->z);/*) != MINITLS_OK)                                   { goto done; }*/

   err = MINITLS_OK;
/*done:*/ //Not used
   mp_clear_multi(&t1, &t2, &x, &y, &z, NULL);
   return err;
}

#endif

/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c,v $ */
/* $Revision: 1.16 $ */
/* $Date: 2007/05/12 14:32:35 $ */