浏览代码

Merge branch 'pascal-brand-st-dev/ecc_raw' into develop

This fixes #69
Steffen Jaeckel 10 年之前
父节点
当前提交
d6cea55b13
共有 3 个文件被更改,包括 129 次插入45 次删除
  1. 8 0
      src/headers/tomcrypt_pk.h
  2. 60 21
      src/pk/ecc/ecc_sign_hash.c
  3. 61 24
      src/pk/ecc/ecc_verify_hash.c

+ 8 - 0
src/headers/tomcrypt_pk.h

@@ -301,10 +301,18 @@ int  ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
                            unsigned char *out, unsigned long *outlen,
                            unsigned char *out, unsigned long *outlen,
                            ecc_key *key);
                            ecc_key *key);
 
 
+int ecc_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
+                            void   *r,   void *s,
+                            prng_state *prng, int wprng, ecc_key *key);
+
 int  ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
 int  ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
                          unsigned char *out, unsigned long *outlen,
                          unsigned char *out, unsigned long *outlen,
                          prng_state *prng, int wprng, ecc_key *key);
                          prng_state *prng, int wprng, ecc_key *key);
 
 
+int ecc_verify_hash_raw(      void   *r, void   *s,
+                        const unsigned char *hash, unsigned long hashlen,
+                        int *stat, ecc_key *key);
+
 int  ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
 int  ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
                      const unsigned char *hash, unsigned long hashlen,
                      const unsigned char *hash, unsigned long hashlen,
                      int *stat, ecc_key *key);
                      int *stat, ecc_key *key);

+ 60 - 21
src/pk/ecc/ecc_sign_hash.c

@@ -24,28 +24,28 @@
 #ifdef LTC_MECC
 #ifdef LTC_MECC
 
 
 /**
 /**
-  Sign a message digest
-  @param in        The message digest to sign
-  @param inlen     The length of the digest
-  @param out       [out] The destination for the signature
-  @param outlen    [in/out] The max size and resulting size of the signature
-  @param prng      An active PRNG state
-  @param wprng     The index of the PRNG you wish to use
-  @param key       A private ECC key
+  Sign a hash with ECC
+  @param in       The hash to sign
+  @param inlen    The length of the hash to sign
+  @param r        The "r" integer of the signature (caller must initialize with mp_init() first)
+  @param s        The "s" integer of the signature (caller must initialize with mp_init() first)
+  @param prng     An active PRNG state
+  @param wprng    The index of the PRNG desired
+  @param key      A private ECC key
   @return CRYPT_OK if successful
   @return CRYPT_OK if successful
 */
 */
-int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
-                        unsigned char *out, unsigned long *outlen, 
-                        prng_state *prng, int wprng, ecc_key *key)
+int ecc_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
+                            void *r, void *s,
+                            prng_state *prng, int wprng, ecc_key *key)
 {
 {
    ecc_key       pubkey;
    ecc_key       pubkey;
-   void          *r, *s, *e, *p;
+   void          *e, *p;
    int           err;
    int           err;
 
 
-   LTC_ARGCHK(in     != NULL);
-   LTC_ARGCHK(out    != NULL);
-   LTC_ARGCHK(outlen != NULL);
-   LTC_ARGCHK(key    != NULL);
+   LTC_ARGCHK(in  != NULL);
+   LTC_ARGCHK(r   != NULL);
+   LTC_ARGCHK(s   != NULL);
+   LTC_ARGCHK(key != NULL);
 
 
    /* is this a private key? */
    /* is this a private key? */
    if (key->type != PK_PRIVATE) {
    if (key->type != PK_PRIVATE) {
@@ -63,7 +63,7 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
 
 
    /* get the hash and load it as a bignum into 'e' */
    /* get the hash and load it as a bignum into 'e' */
    /* init the bignums */
    /* init the bignums */
-   if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { 
+   if ((err = mp_init_multi(&p, &e, NULL)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
    if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)                      { goto errnokey; }
    if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)                      { goto errnokey; }
@@ -94,16 +94,55 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
       }
       }
    }
    }
 
 
+   err = CRYPT_OK;
+   goto errnokey;
+
+error:
+   ecc_free(&pubkey);
+errnokey:
+   mp_clear_multi(p, e, NULL);
+   return err;
+}
+
+/**
+  Sign a message digest
+  @param in        The message digest to sign
+  @param inlen     The length of the digest
+  @param out       [out] The destination for the signature
+  @param outlen    [in/out] The max size and resulting size of the signature
+  @param prng      An active PRNG state
+  @param wprng     The index of the PRNG you wish to use
+  @param key       A private ECC key
+  @return CRYPT_OK if successful
+*/
+int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
+                        unsigned char *out, unsigned long *outlen,
+                        prng_state *prng, int wprng, ecc_key *key)
+{
+   void          *r, *s;
+   int           err;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+   LTC_ARGCHK(key    != NULL);
+
+   if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) {
+      return CRYPT_MEM;
+   }
+
+   if ((err = ecc_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) {
+      goto error;
+   }
+
    /* store as SEQUENCE { r, s -- integer } */
    /* store as SEQUENCE { r, s -- integer } */
    err = der_encode_sequence_multi(out, outlen,
    err = der_encode_sequence_multi(out, outlen,
                              LTC_ASN1_INTEGER, 1UL, r,
                              LTC_ASN1_INTEGER, 1UL, r,
                              LTC_ASN1_INTEGER, 1UL, s,
                              LTC_ASN1_INTEGER, 1UL, s,
                              LTC_ASN1_EOL, 0UL, NULL);
                              LTC_ASN1_EOL, 0UL, NULL);
-   goto errnokey;
+
 error:
 error:
-   ecc_free(&pubkey);
-errnokey:
-   mp_clear_multi(r, s, p, e, NULL);
+   mp_clear_multi(r, s, NULL);
    return err;   
    return err;   
 }
 }
 
 

+ 61 - 24
src/pk/ecc/ecc_verify_hash.c

@@ -34,25 +34,26 @@
  */
  */
 
 
 /**
 /**
-   Verify an ECC signature
-   @param sig         The signature to verify
-   @param siglen      The length of the signature (octets)
-   @param hash        The hash (message digest) that was signed
-   @param hashlen     The length of the hash (octets)
-   @param stat        Result of signature, 1==valid, 0==invalid
-   @param key         The corresponding public ECC key
-   @return CRYPT_OK if successful (even if the signature is not valid)
+  Verify a ECC signature
+  @param r        ECC "r" parameter
+  @param s        ECC "s" parameter
+  @param hash     The hash that was signed
+  @param hashlen  The length of the hash that was signed
+  @param stat     [out] The result of the signature verification, 1==valid, 0==invalid
+  @param key      The corresponding public DH key
+  @return CRYPT_OK if successful (even if the signature is invalid)
 */
 */
-int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
-                    const unsigned char *hash, unsigned long hashlen, 
-                    int *stat, ecc_key *key)
+int ecc_verify_hash_raw(      void   *r, void   *s,
+                        const unsigned char *hash, unsigned long hashlen,
+                        int *stat, ecc_key *key)
 {
 {
    ecc_point    *mG, *mQ;
    ecc_point    *mG, *mQ;
-   void          *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
-   void          *mp;
+   void          *v, *w, *u1, *u2, *e, *p, *m;
+   void          *mp = NULL;
    int           err;
    int           err;
 
 
-   LTC_ARGCHK(sig  != NULL);
+   LTC_ARGCHK(r    != NULL);
+   LTC_ARGCHK(s    != NULL);
    LTC_ARGCHK(hash != NULL);
    LTC_ARGCHK(hash != NULL);
    LTC_ARGCHK(stat != NULL);
    LTC_ARGCHK(stat != NULL);
    LTC_ARGCHK(key  != NULL);
    LTC_ARGCHK(key  != NULL);
@@ -67,7 +68,7 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
    }
    }
 
 
    /* allocate ints */
    /* allocate ints */
-   if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) {
+   if ((err = mp_init_multi(&v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) {
       return CRYPT_MEM;
       return CRYPT_MEM;
    }
    }
 
 
@@ -79,14 +80,6 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
       goto error;
       goto error;
    }
    }
 
 
-   /* parse header */
-   if ((err = der_decode_sequence_multi(sig, siglen,
-                                  LTC_ASN1_INTEGER, 1UL, r,
-                                  LTC_ASN1_INTEGER, 1UL, s,
-                                  LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
-      goto error;
-   }
-
    /* get the order */
    /* get the order */
    if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)                                { goto error; }
    if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)                                { goto error; }
 
 
@@ -151,13 +144,57 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
 error:
 error:
    ltc_ecc_del_point(mG);
    ltc_ecc_del_point(mG);
    ltc_ecc_del_point(mQ);
    ltc_ecc_del_point(mQ);
-   mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
+   mp_clear_multi(v, w, u1, u2, p, e, m, NULL);
    if (mp != NULL) { 
    if (mp != NULL) { 
       mp_montgomery_free(mp);
       mp_montgomery_free(mp);
    }
    }
    return err;
    return err;
 }
 }
 
 
+/**
+   Verify an ECC signature
+   @param sig         The signature to verify
+   @param siglen      The length of the signature (octets)
+   @param hash        The hash (message digest) that was signed
+   @param hashlen     The length of the hash (octets)
+   @param stat        Result of signature, 1==valid, 0==invalid
+   @param key         The corresponding public ECC key
+   @return CRYPT_OK if successful (even if the signature is not valid)
+*/
+
+int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
+                    const unsigned char *hash, unsigned long hashlen,
+                    int *stat, ecc_key *key)
+{
+   void          *r, *s;
+   int           err;
+
+   LTC_ARGCHK(sig  != NULL);
+   LTC_ARGCHK(hash != NULL);
+   LTC_ARGCHK(stat != NULL);
+   LTC_ARGCHK(key  != NULL);
+
+   /* allocate ints */
+   if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) {
+      return CRYPT_MEM;
+   }
+
+   /* parse header */
+   if ((err = der_decode_sequence_multi(sig, siglen,
+                                  LTC_ASN1_INTEGER, 1UL, r,
+                                  LTC_ASN1_INTEGER, 1UL, s,
+                                  LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
+      goto error;
+   }
+
+   /* do the op */
+   err = ecc_verify_hash_raw(r, s, hash, hashlen, stat, key);
+
+error:
+   mp_clear_multi(r, s, NULL);
+   return err;
+}
+
 #endif
 #endif
 /* $Source$ */
 /* $Source$ */
 /* $Revision$ */
 /* $Revision$ */