poly_integer.c

来自「ECC的C++源码」· C语言 代码 · 共 575 行 · 第 1/2 页

C
575
字号
/*  find random value prime to curve order.  EC curves over	GF(2^n) are always even  */		random_field( &garbage);	garbage.e[NUMWORD] |= 1L;	field_to_int( &garbage, &en);	int_gcd( &en, &crv_order, &gcd_check);/*  hunt for value that is relatively prime to curve order  */	while ( !int_onecmp( &gcd_check))	{		int_add( &search, &en, &en);		int_gcd( &en, &crv_order, &gcd_check);	}/*  compute an inverse to complete the pair  */	mod_inv( &en, &crv_order, &de);	int_to_field( &en, e);	int_to_field( &de, d);}/*  Massey-Omura secret sharing protocol, sender side.	Computes an encryption, decryption pair (e, d) and	embeds data on public curve (Pub_crv).  	Output is e*Pm and d.*/void poly_Massey_Omura_send( Pub_crv, message, send_point, decrypt)EC_PARAMETER	*Pub_crv;FIELD2N			*message, *decrypt;POINT			*send_point;{	POINT	msg;	FIELD2N	e;	/*  embed data on given curve.  Change increment or field size to	ensure trouble free operations.*/	poly_embed( message, &Pub_crv->crv, 0, 0, &msg);/*  create random encryption and decryption pair  */	gen_MO_pair( Pub_crv, &e, decrypt);/*  compute point to transmit  */	poly_elptic_mul( &e, &msg, send_point, &Pub_crv->crv);}/*  Massey-Omura secret sharing protocol, receiver side.	input: senders point (rcv_point), public curve (Pub_crv).	generates encrypt, decrypt pair,	output: e*rcv_point (step2), decrypt*/void poly_Massey_Omura_rcv( Pub_crv, rcv_point, step2, decrypt)EC_PARAMETER	*Pub_crv;POINT			*rcv_point, *step2;FIELD2N			*decrypt;{	FIELD2N	e;	/* create encrypt, decrypt pair  */	gen_MO_pair (Pub_crv, &e, decrypt);/*  compute point to transmit back  */	poly_elptic_mul ( &e, rcv_point, step2, &Pub_crv->crv);}/*  DSA version of Elliptic curve signature primitive of IEEE P1363.	Enter with EC parameters, signers private key, pointer to message and	it's length.		Output is 2 values in SIGNITURE structure.	value "c" = x component of random point modulo point order of				public point  (random point = random key * public point)	value "d" = (random key)^-1 * (message hash + signer's key * c)*/void poly_DSA_Signature( Message, length, public_curve, secret_key, signature)char *Message;unsigned long length;EC_PARAMETER *public_curve;FIELD2N *secret_key;SIGNATURE *signature;{	BIGINT			hash_value;		/*  then to an integer  */	EC_KEYPAIR		random_key;	BIGINT			x_value, k_value, sig_value, c_value;	BIGINT			temp, quotient;	BIGINT			key_value, point_order, u_value;	INDEX			i, count;/*  compute hash of input message  */	hash_to_int( Message, length, &hash_value);	/*  create random value and generate random point on public curve  */	poly_ECKGP( public_curve, &random_key);		/*  convert x component of random point to an integer modulo	the order of the base point.  This is first part of 	signature.*/	field_to_int( &public_curve->pnt_order, &point_order);	field_to_int( &random_key.pblc_key.x, &x_value);	int_div( &x_value, &point_order, &quotient, &c_value);	int_to_field( &c_value, &signature->c);	/*	multiply that  by signers private key and add to message	digest modulo the order of the base point. 	hash value + private key * c value*/	field_to_int( secret_key, &key_value);	int_mul( &key_value, &c_value, &temp);	int_add( &temp, &hash_value, &temp);	int_div( &temp, &point_order, &quotient, &k_value);	/*  final step is to multiply by inverse of random key value		modulo order of base point.*/	field_to_int( &random_key.prvt_key, &temp);	mod_inv( &temp, &point_order, &u_value);	int_mul( &u_value, &k_value, &temp);	int_div( &temp, &point_order, &quotient, &sig_value);	int_to_field( &sig_value, &signature->d);}/*  verify a signature of a message using DSA scheme.	Inputs:	Message to be verified of given length,			elliptic curve parameters public_curve 			signer's public key (as a point),			signature block.		Output: value 1 if signature verifies,			value 0 if failure to verify.*/int poly_DSA_Verify( Message, length, public_curve, signer_point, signature)char			*Message;unsigned long 	length;EC_PARAMETER	*public_curve;POINT			*signer_point;SIGNATURE		*signature;{	BIGINT			hash_value;	POINT			Temp1, Temp2, Verify;	BIGINT			c_value, d_value;	BIGINT			temp, quotient, h1, h2;	BIGINT			check_value, point_order;	INDEX			i, count;	FIELD2N			h1_field, h2_field;/*  compute inverse of second signature value  */	field_to_int( &public_curve->pnt_order, &point_order);	field_to_int( &signature->d, &temp);	mod_inv( &temp, &point_order, &d_value);	/*  generate hash of message  */	hash_to_int( Message, length, &hash_value);/*  compute elliptic curve multipliers:	h1 = hash value * d_value, h2 = c * d_value*/	int_mul( &hash_value, &d_value, &temp);	int_div( &temp, &point_order, &quotient, &h1);	int_to_field( &h1, &h1_field);	field_to_int( &signature->c, &c_value);	int_mul( &d_value, &c_value, &temp);	int_div( &temp, &point_order, &quotient, &h2);	int_to_field( &h2, &h2_field);/*  find hidden point from public data  */	poly_elptic_mul( &h1_field, &public_curve->pnt, &Temp1, &public_curve->crv);	poly_elptic_mul( &h2_field, signer_point, &Temp2, &public_curve->crv);	poly_esum( &Temp1, &Temp2, &Verify, &public_curve->crv);	/*  convert x value of verify point to an integer modulo point order */	field_to_int( &Verify.x, &temp);	int_div( &temp, &point_order, &quotient, &check_value);	/*  compare resultant message digest from original signature  */	int_sub( &c_value, &check_value, &temp);	while( temp.hw[0] & 0x8000) 		/*  ensure positive zero */		int_add( &point_order, &temp, &temp);/*  return error if result of subtraction is not zero  */	INTLOOP(i) if (temp.hw[i]) return(0);  	return(1);}/*  Elliptic Curve Secret Value Derivation Primative, Menezes-Qu-Vanstone version.	Enter with "this sides" secret and public key, as well as ephemeral secret and	ephemeral public key, the other sides publick and ephemeral keys, and the 	elliptic curve parameters they are all based on including curve, point and 	order of the point.		Returns a shared secret value.  This version uses an integer package as well	as elliptic curve mathematics.*/void poly_mqv( Base, my_first, my_second, 				their_first, their_second,				shared_secret)EC_PARAMETER *Base;EC_KEYPAIR	 *my_first, *my_second;POINT        *their_first, *their_second;FIELD2N      *shared_secret;{	BIGINT	my_x_value;	BIGINT	my_secret, my_ephemeral;	FIELD2N	my_half_x, their_half_x;	BIGINT	temp1, quotient, temp2;	BIGINT	cfactor, point_order;	FIELD2N	e_value;	POINT	Temp, Common;	INDEX	i, limit, half_msb;	ELEMENT	mask;	/*  convert x component of my ephemeral key to an integer modulo	2^h where h is half the size of the order of the base point.	Since we are using curves with order almost equal to the 	field size, the value of h is about half NUMBITS.  	Change limit to meet the specs for your application.*/	limit = NUMBITS / 2;	half_msb = limit % WORDSIZE;	mask = ~(~0 << half_msb);	limit = limit/WORDSIZE + ( half_msb ? 1 : 0);	copy( &my_second->pblc_key.x, &my_half_x);	for( i=0; i<limit; i++) my_half_x.e[i] = 0;	my_half_x.e[i] &= mask;	my_half_x.e[i] |= 1L << half_msb;	field_to_int( &my_half_x, &my_x_value);/*  get half the other sides ephemeral key  */	copy( &their_second->x, &their_half_x);	for( i=0; i<limit; i++) their_half_x.e[i] = 0;	their_half_x.e[i] &= mask;	their_half_x.e[i] |= 1L << half_msb;	/*  compute multiplier from my secrets and x component  */	field_to_int( &my_first->prvt_key, &my_secret);	field_to_int( &my_second->prvt_key, &my_ephemeral);	field_to_int( &Base->pnt_order, &point_order);	int_mul( &my_x_value, &my_secret, &temp1);	int_add( &temp1, &my_ephemeral, &temp1);	int_div( &temp1, &point_order, &quotient, &temp2);	/*  convert integer to equivelent compressed value for 	elliptic multiply. */		int_to_field( &temp2, &e_value);/*  use other sides public points to create their 	portion of the secret.  */		poly_elptic_mul( &their_half_x, their_first, &Common, &Base->crv);	poly_esum( their_second, &Common, &Temp, &Base->crv);	poly_elptic_mul( &e_value, &Temp, &Common, &Base->crv);/*  take output from common point  */	copy( &Common.x, shared_secret);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?