2016-06-22 19:49:15 +03:00
/*
* Copyright ( c ) 2013 , Kenneth MacKay
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are
* met :
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# ifndef _CRYPTO_ECC_H
# define _CRYPTO_ECC_H
2018-03-30 19:55:44 +03:00
# define ECC_CURVE_NIST_P192_DIGITS 3
# define ECC_CURVE_NIST_P256_DIGITS 4
# define ECC_MAX_DIGITS ECC_CURVE_NIST_P256_DIGITS
2016-06-22 19:49:15 +03:00
# define ECC_DIGITS_TO_BYTES_SHIFT 3
2019-04-11 18:51:19 +03:00
/**
* struct ecc_point - elliptic curve point in affine coordinates
*
* @ x : X coordinate in vli form .
* @ y : Y coordinate in vli form .
* @ ndigits : Length of vlis in u64 qwords .
*/
struct ecc_point {
u64 * x ;
u64 * y ;
u8 ndigits ;
} ;
/**
* struct ecc_curve - definition of elliptic curve
*
* @ name : Short name of the curve .
* @ g : Generator point of the curve .
* @ p : Prime number , if Barrett ' s reduction is used for this curve
* pre - calculated value ' mu ' is appended to the @ p after ndigits .
* Use of Barrett ' s reduction is heuristically determined in
* vli_mmod_fast ( ) .
* @ n : Order of the curve group .
* @ a : Curve parameter a .
* @ b : Curve parameter b .
*/
struct ecc_curve {
char * name ;
struct ecc_point g ;
u64 * p ;
u64 * n ;
u64 * a ;
u64 * b ;
} ;
2016-06-22 19:49:15 +03:00
/**
* ecc_is_key_valid ( ) - Validate a given ECDH private key
*
* @ curve_id : id representing the curve to use
2017-05-25 10:18:03 +03:00
* @ ndigits : curve ' s number of digits
2016-06-22 19:49:15 +03:00
* @ private_key : private key to be used for the given curve
2017-05-25 10:18:03 +03:00
* @ private_key_len : private key length
2016-06-22 19:49:15 +03:00
*
* Returns 0 if the key is acceptable , a negative value otherwise
*/
int ecc_is_key_valid ( unsigned int curve_id , unsigned int ndigits ,
2017-05-25 10:18:05 +03:00
const u64 * private_key , unsigned int private_key_len ) ;
2016-06-22 19:49:15 +03:00
2017-05-30 17:52:48 +03:00
/**
* ecc_gen_privkey ( ) - Generates an ECC private key .
* The private key is a random integer in the range 0 < random < n , where n is a
* prime that is the order of the cyclic subgroup generated by the distinguished
* point G .
* @ curve_id : id representing the curve to use
* @ ndigits : curve number of digits
* @ private_key : buffer for storing the generated private key
*
* Returns 0 if the private key was generated successfully , a negative value
* if an error occurred .
*/
int ecc_gen_privkey ( unsigned int curve_id , unsigned int ndigits , u64 * privkey ) ;
2016-06-22 19:49:15 +03:00
/**
2017-05-30 15:37:56 +03:00
* ecc_make_pub_key ( ) - Compute an ECC public key
2016-06-22 19:49:15 +03:00
*
* @ curve_id : id representing the curve to use
2017-05-25 10:18:03 +03:00
* @ ndigits : curve ' s number of digits
2016-06-22 19:49:15 +03:00
* @ private_key : pregenerated private key for the given curve
2017-05-25 10:18:03 +03:00
* @ public_key : buffer for storing the generated public key
2016-06-22 19:49:15 +03:00
*
* Returns 0 if the public key was generated successfully , a negative value
* if an error occurred .
*/
2017-05-30 15:37:56 +03:00
int ecc_make_pub_key ( const unsigned int curve_id , unsigned int ndigits ,
const u64 * private_key , u64 * public_key ) ;
2016-06-22 19:49:15 +03:00
/**
2016-06-24 09:20:22 +03:00
* crypto_ecdh_shared_secret ( ) - Compute a shared secret
2016-06-22 19:49:15 +03:00
*
* @ curve_id : id representing the curve to use
2017-05-25 10:18:03 +03:00
* @ ndigits : curve ' s number of digits
2016-06-22 19:49:15 +03:00
* @ private_key : private key of part A
* @ public_key : public key of counterpart B
* @ secret : buffer for storing the calculated shared secret
*
2016-06-24 09:20:22 +03:00
* Note : It is recommended that you hash the result of crypto_ecdh_shared_secret
2016-06-22 19:49:15 +03:00
* before using it for symmetric encryption or HMAC .
*
* Returns 0 if the shared secret was generated successfully , a negative value
* if an error occurred .
*/
2016-06-24 09:20:22 +03:00
int crypto_ecdh_shared_secret ( unsigned int curve_id , unsigned int ndigits ,
2017-05-25 10:18:05 +03:00
const u64 * private_key , const u64 * public_key ,
u64 * secret ) ;
2019-04-11 18:51:19 +03:00
/**
* ecc_is_pubkey_valid_partial ( ) - Partial public key validation
*
* @ curve : elliptic curve domain parameters
* @ pk : public key as a point
*
* Valdiate public key according to SP800 - 56 A section 5.6 .2 .3 .4 ECC Partial
* Public - Key Validation Routine .
*
* Note : There is no check that the public key is in the correct elliptic curve
* subgroup .
*
* Return : 0 if validation is successful , - EINVAL if validation is failed .
*/
int ecc_is_pubkey_valid_partial ( const struct ecc_curve * curve ,
struct ecc_point * pk ) ;
/**
* vli_is_zero ( ) - Determine is vli is zero
*
* @ vli : vli to check .
* @ ndigits : length of the @ vli
*/
bool vli_is_zero ( const u64 * vli , unsigned int ndigits ) ;
/**
* vli_cmp ( ) - compare left and right vlis
*
* @ left : vli
* @ right : vli
* @ ndigits : length of both vlis
*
* Returns sign of @ left - @ right , i . e . - 1 if @ left < @ right ,
* 0 if @ left = = @ right , 1 if @ left > @ right .
*/
int vli_cmp ( const u64 * left , const u64 * right , unsigned int ndigits ) ;
/**
* vli_sub ( ) - Subtracts right from left
*
* @ result : where to write result
* @ left : vli
* @ right vli
* @ ndigits : length of all vlis
*
* Note : can modify in - place .
*
* Return : carry bit .
*/
u64 vli_sub ( u64 * result , const u64 * left , const u64 * right ,
unsigned int ndigits ) ;
/**
* vli_mod_inv ( ) - Modular inversion
*
* @ result : where to write vli number
* @ input : vli value to operate on
* @ mod : modulus
* @ ndigits : length of all vlis
*/
void vli_mod_inv ( u64 * result , const u64 * input , const u64 * mod ,
unsigned int ndigits ) ;
2016-06-22 19:49:15 +03:00
# endif