📄 ecc.c
字号:
if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* find key size */ for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++); keysize = ecc_sets[x].size; if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; } key->idx = x; /* allocate ram */ base = NULL; buf = XMALLOC(ECC_MAXSIZE); if (buf == NULL) { return CRYPT_MEM; } /* make up random string */ if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR2; } /* setup the key variables */ if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, NULL)) != MP_OKAY) { err = mpi_to_ltc_error(err); goto LBL_ERR; } base = ecc_new_point(); if (base == NULL) { mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, NULL); err = CRYPT_MEM; goto LBL_ERR; } /* read in the specs for this key */ if ((err = mp_read_radix(&prime, (char *)ecc_sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&base->x, (char *)ecc_sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&base->y, (char *)ecc_sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; } mp_set(&base->z, 1); if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; } /* make the public key */ if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1)) != CRYPT_OK) { goto LBL_ERR; } key->type = PK_PRIVATE; /* shrink key */ if ((err = mp_shrink(&key->k)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&key->pubkey.x)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&key->pubkey.y)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&key->pubkey.z)) != MP_OKAY) { goto error; } /* free up ram */ err = CRYPT_OK; goto LBL_ERR;error: err = mpi_to_ltc_error(err);LBL_ERR: ecc_del(base); mp_clear(&prime);LBL_ERR2:#ifdef LTC_CLEAN_STACK zeromem(buf, ECC_MAXSIZE);#endif XFREE(buf); return err;}/** Free an ECC key from memory @param key The key you wish to free*/void ecc_free(ecc_key *key){ LTC_ARGCHK(key != NULL); mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL);}/** Export an ECC key as a binary packet @param out [out] Destination for the key @param outlen [in/out] Max size and resulting size of the exported key @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC) @param key The key to export @return CRYPT_OK if successful*/int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key){ int err; unsigned char flags[1]; unsigned long key_size; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* type valid? */ if (key->type != PK_PRIVATE && type == PK_PRIVATE) { return CRYPT_PK_TYPE_MISMATCH; } if (is_valid_idx(key->idx) == 0) { return CRYPT_INVALID_ARG; } /* we store the NIST byte size */ key_size = ecc_sets[key->idx].size; if (type == PK_PRIVATE) { flags[0] = 1; err = der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_INTEGER, 1UL, &key->k, LTC_ASN1_EOL, 0UL, NULL); } else { flags[0] = 0; err = der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_EOL, 0UL, NULL); } return err;}/** Import an ECC key from a binary packet @param in The packet to import @param inlen The length of the packet @param key [out] The destination of the import @return CRYPT_OK if successful, upon error all allocated memory will be freed*/int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key){ unsigned long key_size; unsigned char flags[1]; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); /* init key */ if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != MP_OKAY) { return CRYPT_MEM; } /* find out what type of key it is */ if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, &flags, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } if (flags[0] == 1) { /* private key */ key->type = PK_PRIVATE; if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_INTEGER, 1UL, &key->k, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } } else { /* public key */ /* private key */ key->type = PK_PUBLIC; if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, LTC_ASN1_INTEGER, 1UL, &key->pubkey.y, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } } /* find the idx */ for (key->idx = 0; ecc_sets[key->idx].size && (unsigned long)ecc_sets[key->idx].size != key_size; ++key->idx); if (ecc_sets[key->idx].size == 0) { err = CRYPT_INVALID_PACKET; goto error; } /* set z */ mp_set(&key->pubkey.z, 1); /* we're good */ return CRYPT_OK;error: mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); return err;}/** Create an ECC shared secret between two keys @param private_key The private ECC key @param public_key The public key @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63) @param outlen [in/out] The max size and resulting size of the shared secret @return CRYPT_OK if successful*/int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, unsigned char *out, unsigned long *outlen){ unsigned long x; ecc_point *result; mp_int prime; int err; LTC_ARGCHK(private_key != NULL); LTC_ARGCHK(public_key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* type valid? */ if (private_key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } if (is_valid_idx(private_key->idx) == 0) { return CRYPT_INVALID_ARG; } if (private_key->idx != public_key->idx) { return CRYPT_PK_TYPE_MISMATCH; } /* make new point */ result = ecc_new_point(); if (result == NULL) { return CRYPT_MEM; } if ((err = mp_init(&prime)) != MP_OKAY) { ecc_del(result); return mpi_to_ltc_error(err); } if ((err = mp_read_radix(&prime, (char *)ecc_sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; } if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime, 1)) != CRYPT_OK) { goto done1; } x = (unsigned long)mp_unsigned_bin_size(&prime); if (*outlen < x) { err = CRYPT_BUFFER_OVERFLOW; goto done1; } zeromem(out, x); if ((err = mp_to_unsigned_bin(&result->x, out + (x - mp_unsigned_bin_size(&result->x)))) != MP_OKAY) { goto error; } err = CRYPT_OK; *outlen = x; goto done1;error: err = mpi_to_ltc_error(err);done1: mp_clear(&prime); ecc_del(result); return err;}/** Get the size of an ECC key @param key The key to get the size of @return The size (octets) of the key or INT_MAX on error*/int ecc_get_size(ecc_key *key){ LTC_ARGCHK(key != NULL); if (is_valid_idx(key->idx)) return ecc_sets[key->idx].size; else return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */}/** Rinick's R = P*/int ecc_copy(ecc_point *P, ecc_point *R){ int err; if ((err = mp_copy(&P->x, &R->x)) != MP_OKAY) { goto error; } if ((err = mp_copy(&P->y, &R->y)) != MP_OKAY) { goto error; } if ((err = mp_copy(&P->z, &R->z)) != MP_OKAY) { goto error; } err = CRYPT_OK; goto done;error: err = mpi_to_ltc_error(err);done: return err;}/** read base point @return CRYPT_OK if successful, upon error all allocated memory will be freed*/int ecc_read_base(int keysize, ecc_point *base, mp_int *prime, mp_int *order){ int x, err; LTC_ARGCHK(base != NULL); /* find key size */ for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++); keysize = ecc_sets[x].size; if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; } if (base == NULL) { base = ecc_new_point(); } /* read in the specs for this key */ if ((err = mp_read_radix(&base->x, (char *)ecc_sets[x].Gx, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&base->y, (char *)ecc_sets[x].Gy, 64)) != MP_OKAY) { goto error; } mp_set(&base->z, 1); if ((err = mp_read_radix(prime, (char *)ecc_sets[x].prime, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(order, (char *)ecc_sets[x].order, 64)) != MP_OKAY) { goto error; } /* shrink key */ if ((err = mp_shrink(prime)) != MP_OKAY) { goto error; } if ((err = mp_shrink(order)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&base->x)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&base->y)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&base->z)) != MP_OKAY) { goto error; } /* free up ram */ err = CRYPT_OK; goto LBL_ERR;error: err = mpi_to_ltc_error(err);LBL_ERR: return err;}#include "ecc_sys.c"#endif/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc.c,v $ *//* $Revision: 1.20 $ *//* $Date: 2005/06/14 20:42:28 $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -