]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added previous code that was fixed for y^2 = x^3 - 3x + b, because all secg curves...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 21 May 2011 06:29:58 +0000 (08:29 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 21 May 2011 06:30:49 +0000 (08:30 +0200)
Simplified file naming scheme.

14 files changed:
lib/nettle/Makefile.am
lib/nettle/ecc.h
lib/nettle/ecc_free.c
lib/nettle/ecc_make_key.c
lib/nettle/ecc_map.c [moved from lib/nettle/ltc_ecc_map.c with 94% similarity]
lib/nettle/ecc_mulmod.c [moved from lib/nettle/ltc_ecc_mulmod.c with 98% similarity]
lib/nettle/ecc_points.c [moved from lib/nettle/ltc_ecc_points.c with 94% similarity]
lib/nettle/ecc_projective_add_point.c [moved from lib/nettle/ltc_ecc_projective_add_point.c with 96% similarity]
lib/nettle/ecc_projective_dbl_point.c [moved from lib/nettle/ltc_ecc_projective_dbl_point.c with 72% similarity]
lib/nettle/ecc_projective_dbl_point_3.c [new file with mode: 0644]
lib/nettle/ecc_shared_secret.c
lib/nettle/ecc_sign_hash.c
lib/nettle/ecc_test.c
lib/nettle/ecc_verify_hash.c

index 05168007629441cdd363366837c2d223f7d9ac7e..a4bd44cfc0f9145b459ceacf708ea7dcf048aecd 100644 (file)
@@ -36,7 +36,7 @@ noinst_LTLIBRARIES = libcrypto.la
 
 libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c rnd.c init.c egd.c egd.h \
        multi.c ecc_free.c ecc.h ecc_make_key.c ecc_shared_secret.c \
-       ecc_test.c ltc_ecc_map.c \
-       ltc_ecc_mulmod.c ltc_ecc_points.c \
-       ltc_ecc_projective_add_point.c ltc_ecc_projective_dbl_point.c \
+       ecc_test.c ecc_map.c \
+       ecc_mulmod.c ecc_points.c ecc_projective_dbl_point_3.c \
+       ecc_projective_add_point.c ecc_projective_dbl_point.c \
        mp_unsigned_bin.c ecc_sign_hash.c ecc_verify_hash.c 
index 902429440200316824d92c452e45baddb35a92f7..56fafc872d214a312dccbb71e51426f3daf29f20 100644 (file)
@@ -6,8 +6,12 @@
 #include <string.h>
 #include <assert.h>
 
-#define LTC_MECC
-#define ECC256
+/* assume y^2 = x^3 - 3x + b
+ * instead of the generic y^2 = x^3 + ax + b
+ *
+ * (XXX: the generic case has not been tested)
+ */
+#define ECC_SECP_CURVES_ONLY
 
 #define PK_PRIVATE 1
 #define PK_PUBLIC 2
index a4bf451c4cc4b4b110d31e5bffb263c3e57bcd14..bbf087dfd595d3162bdc4271656fd649c9195c44 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Free an ECC key from memory
   @param key   The key you wish to free
@@ -35,7 +33,6 @@ ecc_free (ecc_key * key)
                   &key->prime, &key->order, &key->Gx, &key->Gy, NULL);
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_free.c,v $ */
 /* $Revision: 1.6 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
index f1e5cde719bc8072bdd24ad701ae09afb9fdf22e..aab6fedb6dbfb6785a284853fad8c37bc37bd6bf 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Make a new ECC key 
   @param prng         An active PRNG state
@@ -146,7 +144,6 @@ cleanup:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_make_key.c,v $ */
 /* $Revision: 1.13 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
similarity index 94%
rename from lib/nettle/ltc_ecc_map.c
rename to lib/nettle/ecc_map.c
index dca353b617194c141036b1f36abe87f44655b2f8..bbe99ec79099731c3295ec7e31b6f17cb7bd5aeb 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Map a projective jacobian point back to affine space
   @param P        [in/out] The point to map
@@ -67,8 +65,6 @@ ltc_ecc_map (ecc_point * P, mpz_t modulus)
   return err;
 }
 
-#endif
-
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_map.c,v $ */
 /* $Revision: 1.7 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
similarity index 98%
rename from lib/nettle/ltc_ecc_mulmod.c
rename to lib/nettle/ecc_mulmod.c
index f8c02dca75dffa3177e0bf81cf55512470ef242d..1236dc340b57f61ac42e96f4fa8650313bbae782 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
    Perform a point multiplication  (timing resistant)
    @param k    The scalar to multiply by
@@ -182,7 +180,6 @@ done:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c,v $ */
 /* $Revision: 1.13 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
similarity index 94%
rename from lib/nettle/ltc_ecc_points.c
rename to lib/nettle/ecc_points.c
index e4e2cd4c2de08aeb5742c0d4c7c6a463d3b44fac..fa9b5b5c927119daa7ed7ef407e29d847b01c8d9 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
    Allocate a new ECC point
    @return A newly allocated point or NULL on error 
@@ -58,7 +56,6 @@ ltc_ecc_del_point (ecc_point * p)
     }
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_points.c,v $ */
 /* $Revision: 1.7 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
similarity index 96%
rename from lib/nettle/ltc_ecc_projective_add_point.c
rename to lib/nettle/ecc_projective_add_point.c
index 31bd679e592d3698511a3153cd1dda565aa697bf..dd98eb43d81b160fa0f32cc7132b8c5764de2b73 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   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
@@ -204,8 +202,6 @@ ltc_ecc_projective_add_point (ecc_point * P, ecc_point * Q, ecc_point * R,
   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 $ */
similarity index 72%
rename from lib/nettle/ltc_ecc_projective_dbl_point.c
rename to lib/nettle/ecc_projective_dbl_point.c
index 618f0d94eb442f9a06fac226872a7cdd14a36605..6d446c28a8e3ca9c848334590d73037d66b1b22f 100644 (file)
@@ -1,27 +1,32 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+/*
+ * Copyright (C) 2011 Free Software Foundation, Inc.
  *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
+ * Author: Nikos Mavrogiannopoulos
  *
- * The library is free for all purposes without any express
- * guarantee it works.
+ * This file is part of GNUTLS.
+ *
+ * The GNUTLS library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
  *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
+/* Implements ECC point doubling over Z/pZ for curve y^2 = x^3 + ax + b
  */
 #include "ecc.h"
 
-/**
-  @file ltc_ecc_projective_dbl_point.c
-  ECC Crypto, Tom St Denis
-*/
-
-#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
+#ifndef ECC_SECP_CURVES_ONLY
 
 /**
    Double an ECC point
@@ -42,6 +47,30 @@ ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a,
   assert (R != NULL);
   assert (modulus != NULL);
 
+  /*
+    algorithm used:
+     if (Y == 0)
+       return POINT_AT_INFINITY
+     S = 4*X*Y^2
+     M = 3*X^2 + a*Z^4
+     X' = M^2 - 2*S
+     Y' = M*(S - X') - 8*Y^4
+     Z' = 2*Y*Z
+     return (X', Y', Z')
+   */
+
+  if (mpz_cmp_ui(P->y, 0) == 0)
+    {
+      /* point at infinity 
+       * under jacobian coordinates
+       */
+      mpz_set(R->x, 1);
+      mpz_set(R->y, 1);
+      mpz_set(R->z, 0);
+      
+      return 0;
+    }
+
   if ((err = mp_init_multi (&t1, &m, &s, NULL)) != 0)
     {
       return err;
@@ -54,16 +83,6 @@ ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a,
       mpz_set (R->z, P->z);
     }
 
-  /*
-     if (Y == 0)
-     return POINT_AT_INFINITY
-     S = 4*X*Y^2
-     M = 3*X^2 + a*Z^4
-     X' = M^2 - 2*S
-     Y' = M*(S - X') - 8*Y^4
-     Z' = 2*Y*Z
-     return (X', Y', Z')
-   */
 
   /* m = Z * Z */
   mpz_mul (m, R->z, R->z);
@@ -187,7 +206,5 @@ ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a,
   mp_clear_multi (&t1, &m, &s, NULL);
   return err;
 }
+
 #endif
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */
-/* $Revision: 1.11 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ecc_projective_dbl_point_3.c b/lib/nettle/ecc_projective_dbl_point_3.c
new file mode 100644 (file)
index 0000000..7c415fe
--- /dev/null
@@ -0,0 +1,148 @@
+/* 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 "ecc.h"
+
+/**
+  @file ltc_ecc_projective_dbl_point.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef ECC_SECP_CURVES_ONLY
+
+/**
+   Double an ECC point
+   @param P   The point to double
+   @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 0 on success
+*/
+int
+ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a /* a is -3 */,
+                              mpz_t modulus)
+{
+   mpz_t t1, t2;
+   int   err;
+
+   assert(P       != NULL);
+   assert(R       != NULL);
+   assert(modulus != NULL);
+
+   if ((err = mp_init_multi(&t1, &t2, NULL)) != 0) {
+      return err;
+   }
+
+   if (P != R) {
+      mpz_set(R->x, P->x);
+      mpz_set(R->y, P->y);
+      mpz_set(R->z, P->z);
+   }
+
+   /* t1 = Z * Z */
+   mpz_mul(t1, R->z, R->z);
+   mpz_mod(t1, t1, modulus);
+   /* Z = Y * Z */
+   mpz_mul(R->z, R->y, R->z);
+   mpz_mod(R->z, R->z, modulus);
+   /* Z = 2Z */
+   mpz_add(R->z, R->z, R->z);
+   if (mpz_cmp(R->z, modulus) >= 0) {
+      mpz_sub(R->z, R->z, modulus);
+   }
+   
+   /* T2 = X - T1 */
+   mpz_sub(t2, R->x, t1);
+   if (mpz_cmp_ui(t2, 0) < 0) {
+      mpz_add(t2, t2, modulus);
+   }
+   /* T1 = X + T1 */
+   mpz_add(t1, t1, R->x);
+   if (mpz_cmp(t1, modulus) >= 0) {
+      mpz_sub(t1, t1, modulus);
+   }
+   /* T2 = T1 * T2 */
+   mpz_mul(t2, t1, t2);
+   mpz_mod(t2, t2, modulus);
+   /* T1 = 2T2 */
+   mpz_add(t1, t2, t2);
+   if (mpz_cmp(t1, modulus) >= 0) {
+      mpz_sub(t1, t1, modulus);
+   }
+   /* T1 = T1 + T2 */
+   mpz_add(t1, t1, t2);
+   if (mpz_cmp(t1, modulus) >= 0) {
+      mpz_sub(t1, t1, modulus);
+   }
+
+   /* Y = 2Y */
+   mpz_add(R->y, R->y, R->y);
+   if (mpz_cmp(R->y, modulus) >= 0) {
+      mpz_sub(R->y, R->y, modulus);
+   }
+   /* Y = Y * Y */
+   mpz_mul(R->y, R->y, R->y);
+   mpz_mod(R->y, R->y, modulus);
+   /* T2 = Y * Y */
+   mpz_mul(t2, R->y, R->y);
+   mpz_mod(t2, t2, modulus);
+   /* T2 = T2/2 */
+   if (mp_isodd(t2)) {
+      mpz_add(t2, t2, modulus);
+   }
+   mpz_divexact_ui(t2, t2, 2);
+   /* Y = Y * X */
+   mpz_mul(R->y, R->y, R->x);
+   mpz_mod(R->y, R->y, modulus);
+
+   /* X  = T1 * T1 */
+   mpz_mul(R->x, t1, t1);
+   mpz_mod(R->x, R->x, modulus);
+   /* X = X - Y */
+   mpz_sub(R->x, R->x, R->y);
+   if (mpz_cmp_ui(R->x, 0) < 0) {
+      mpz_add(R->x, R->x, modulus);
+   }
+   /* X = X - Y */
+   mpz_sub(R->x, R->x, R->y);
+   if (mpz_cmp_ui(R->x, 0) < 0) {
+      mpz_add(R->x, R->x, modulus);
+   }
+
+   /* Y = Y - X */     
+   mpz_sub(R->y, R->y, R->x);
+   if (mpz_cmp_ui(R->y, 0) < 0) {
+      mpz_add(R->y, R->y, modulus);
+   }
+   /* Y = Y * T1 */
+   mpz_mul(R->y, R->y, t1);
+   mpz_mod(R->y, R->y, modulus);
+   /* Y = Y - T2 */
+   mpz_sub(R->y, R->y, t2);
+   if (mpz_cmp_ui(R->y, 0) < 0) {
+      mpz_add( R->y, R->y, modulus);
+   }
+   err = 0;
+
+   mp_clear_multi(&t1, &t2, NULL);
+   return err;
+}
+#endif
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */
+/* $Revision: 1.11 $ */
+/* $Date: 2007/05/12 14:32:35 $ */
+
index a7f5761fa95882ee654acd725799e50b9962860f..61012fd683dd2159f2fc6d52394d8472a02b6f32 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -22,8 +22,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Create an ECC shared secret between two keys
   @param private_key      The private ECC key
@@ -88,7 +86,6 @@ done:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_shared_secret.c,v $ */
 /* $Revision: 1.10 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
index 09774cb5343fba5c6396fbdcaa2bfc854467b73b..158949ffda540c74b8ebf39ee9d79ae03be2e565 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -22,8 +22,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Sign a message digest
   @param in        The message digest to sign
@@ -111,7 +109,6 @@ errnokey:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sign_hash.c,v $ */
 /* $Revision: 1.11 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
index 7e854ec9b238125de5c6e1460de109c19c70e800..0bdcd35d8f2691456f26be9b580917a75b7afc76 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -24,8 +24,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Perform on the ECC system
   @return 0 if successful
@@ -139,8 +137,6 @@ done:
   return err;
 }
 
-#endif
-
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_test.c,v $ */
 /* $Revision: 1.12 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
index 7f62d64ca36ad403addcca74264e1a534b3029c3..b9f6ec099950b46100e420e689a98e33a16b4bad 100644 (file)
@@ -9,7 +9,7 @@
  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /* verify 
  *
  * w  = s^-1 mod n
@@ -151,7 +149,6 @@ error:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_verify_hash.c,v $ */
 /* $Revision: 1.14 $ */
 /* $Date: 2007/05/12 14:32:35 $ */