onb_integer.c
来自「ECC的C++源码」· C语言 代码 · 共 634 行 · 第 1/2 页
C
634 行
/************************************************************* ** Implement combinations of math packages to create ** advanced protocols. Massy-Omura is first example. ** Nyberg_Rueppel second. ** ** Author = Mike Rosing ** Date = Jan 4, 1998 ** ** NR Jan. 9, 1998 ** *************************************************************/#include <stdio.h>#include "bigint.h"#include "eliptic.h"#include "protocols.h"extern unsigned long random_seed;extern void sha_memory();/* print out an integer. input is label string and pointer to integer, sends to terminal.*/void print_int( string, number)char *string;BIGINT *number;{ char teststring[MAXSTRING], outchar[2*MAXSTRING]; bigint_to_ascii(number, teststring); sprintf(outchar, "%s\n%s\n", string, teststring); printf("%s\n", outchar);} /* function to compare BIGINT value to 1. Returns 1 if it is, 0 otherwise.*/INDEX int_onecmp( number)BIGINT *number;{ INDEX i; if ( number->hw[INTMAX] > 1) return (0); for ( i=0; i<INTMAX; i++) if ( number->hw[i]) return (0); if (number->hw[INTMAX]) return (1); return (0);}/* Generate a key pair, a random value plus a point. This was called ECKGP for Elliptic Curve Key Generation Primitive in an early draft of IEEE P1363. Input: EC parameters including public curve, point, point order and cofactor Output: EC key pair including secret key k and random point R = k* base point*/void ECKGP( Base, Key)EC_PARAMETER *Base;EC_KEYPAIR *Key;{ BIGINT key_num, point_order, quotient, remainder; FIELD2N rand_key; /* ensure random value is less than point order */ random_field( &rand_key); field_to_int( &rand_key, &key_num); field_to_int( &Base->pnt_order, &point_order); int_div( &key_num, &point_order, "ient, &remainder); int_to_field( &remainder, &Key->prvt_key); elptic_mul( &Key->prvt_key, &Base->pnt, &Key->pblc_key, &Base->crv);}/* As required in Massey-Omura protocol, create a number and its inverse over known curve order. Input is public EC parameters, output is random e and d modulo curve order where ed = 1 mod N*/void gen_MO_pair ( Public, e, d)EC_PARAMETER *Public;FIELD2N *e, *d;{ FIELD2N garbage; BIGINT gcd_check, crv_order, pnt_order, cfactor; BIGINT search, en, de;/* since 2 is always a factor, stay odd while hunting */ int_null( &search); search.hw[INTMAX] = 2;/* compute curve order */ field_to_int( &Public->pnt_order, &pnt_order); field_to_int( &Public->cofactor, &cfactor); int_mul( &cfactor, &pnt_order, &crv_order);/* 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 onb_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.*/ opt_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 */ 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 onb_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 */ elptic_mul ( &e, rcv_point, step2, &Pub_crv->crv);}/* Subroutine to compute hash of a message and return the result as an integer. Used in all signature schemes. Enter with pointer to message, message length*/void hash_to_int( Message, length, hash_value)char *Message;unsigned long length;BIGINT *hash_value; /* then to an integer */{ unsigned long message_digest[5]; /* from SHA-1 hash function */ FIELD2N mdtemp; /* convert to NUMBITS size (if needed) */ INDEX i, count; /* compute hash of input message */ sha_memory( Message, length, message_digest);/* convert message digest into an integer */ null ( &mdtemp); count = 0; SUMLOOP (i) { mdtemp.e[ NUMWORD - i] = message_digest[ 4 - i]; count++; if (count > 4) break; } mdtemp.e[0] &= UPRMASK; field_to_int( &mdtemp, hash_value);} /* Implement Nyberg-Rueppel signature scheme described in IEEE P1363 draft standard of August 1997. This uses SHA-1 as the hash algorithm on the message. Inputs are a pointer to Message, public elliptic curve parameters including the order of the curve, and the signers secret key for signing, or public key for verification.*//* Nyberg-Rueppel elliptic curve signature scheme. Inputs: pointer to Message to be signed and its length, pointer to elliptic curve parameters, pointer to signer's secret key, pointer to signature storage area. Output: fills signature storage area with 2 numbers first number = SHA(Message) + random value second number = random value - signer's secret key times first number both are done modulo base point order The output is converted back to FIELD2N variables to save space and to make verification easier.*/void NR_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; FIELD2N random_value; POINT random_point; BIGINT x_value, k_value, sig_value; BIGINT temp, quotient; BIGINT key_value, point_order; INDEX i, count;/* compute hash of input message */ hash_to_int( Message, length, &temp); field_to_int( &public_curve->pnt_order, &point_order); int_div( &temp, &point_order, "ient, &hash_value); /* create random value and generate random point on public curve */ random_field( &random_value); elptic_mul( &random_value, &public_curve->pnt, &random_point, &public_curve->crv); /* convert x component of random point to an integer and add to message digest modulo the order of the base point.*/ field_to_int( &random_point.x, &x_value); int_add( &x_value, &hash_value, &temp); int_div( &temp, &point_order, "ient, &sig_value); int_to_field( &sig_value, &signature->c);/* final step is to combine signer's secret key with random value second number = random value - secret key * first number modulo order of base point*/ field_to_int( &random_value, &k_value); field_to_int( secret_key, &key_value); int_mul( &key_value, &sig_value, &temp); int_div( &temp, &point_order, "ient, &sig_value); int_sub( &k_value, &sig_value, &sig_value); while( sig_value.hw[0] & 0x8000) int_add( &point_order, &sig_value, &sig_value); int_div( &sig_value, &point_order, "ient, &temp); int_to_field( &sig_value, &signature->d);}/* verify a signature of a message using Nyberg-Rueppel 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 NR_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 x_value, c_value; BIGINT temp, quotient; BIGINT check_value, point_order; INDEX i, count; /* find hidden point from public data */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?