The embarrassment of Xiao Wang Daily (iv)--OPENSSL implementation of the National Secret Algorithm (signature and verification)

Source: Internet
Author: User
Tags goto openssl

Yesterday, updated the implementation of encryption and decryption, today we continue to sign and verification.
Or according to the King's practice to say the theoretical knowledge first:

The following symbols apply to this section.
A,b: Two users using a public key cryptography system.
The elements in the A,B:FQ that define an elliptic curve E on the FQ.
2dA: User A's private key.
E (FQ): A set of all rational points (including Infinity Point O) on the Fq elliptic curve E.
E: The password hash function acts on the output value of message M.
e′: The password hash function acts on the output value of the message m′.
Fq
: A finite field that contains Q elements.
G: A basic point of the elliptic curve, whose order is prime.
Hv
(): A password hash function with a message digest length of v bits.
IDA: A recognizable identity for user A.
M: The message to be signed.
m′: Message to be verified.
MODN: modulo n operation. For example, 23mod7=2.
N: The order of base G (n is the #e factor of the Fq).
O: A special point on the elliptic curve, called an infinity point or 0 point, is the unit element of the Elliptic curve addition group.
PA: The public key of User A.
Q: The number of elements in a finite field fq.
X∥y:x with Y, where x, y can be a bit string or a byte string.
ZA: The hash value of user A's distinguished identification, partial elliptic curve system parameters, and user a public key.
(r,s): The signature that is sent.
(r′,s′): Signature received.
K P: The K-Times point P on the elliptic curve, that is, [k]p= p + p + + P (k p, K is a positive integer).
[X,y]: A collection of integers greater than or equal to x and less than or equal to Y.
⌈x⌉: The top function, the smallest integer greater than or equal to X. For example, ⌈7⌉=7,⌈8.3⌉=9.
⌊x⌋: A bottom function that is less than or equal to the largest integer of x. For example, ⌊7⌋=7,⌊8.3⌋=8.
#E (FQ): The number of points on E (Fq), called the Order of the Elliptic Curve E (Fq).

sm2 Signature Algorithm Flow

The message to be signed is M, in order to obtain the digital signature (r,s) of the message m, user A of the signer should implement the following operation steps
Sudden:
A1: Placing m=za∥m;
A2: Calculates e = Hv (M), converts the data type of E to an integer according to the details given in part 1th of this text 4.2.3 and 4.2.2;
A3: Generating random number k∈[1,n-1 with random number generator];
A4: Calculates the elliptic Curve point (x1,y1) =[k]g, converts the X1 data type to an integer according to the details given in part 1th of this text 4.2.7
Number
A5: Calculate r= (e+x1) MODN, if r=0 or r+k=n return A3;
A6: Compute s = ((1 + dA) −1 (K−r da)) MODN, if S=0 is returned A3;
A7: The data type of R, S is converted to a byte string, and the signature of message M is (r,s) according to the details given in part 1th of this text 4.2.1.

Here is the flowchart:

SM2 algorithm checking and verifying process

In order to verify the received message m′ and its digital signature (r′, s′), User B, who is the authenticator, should implement the following operational steps:
B1: Inspection r′∈[1,n-1] Whether set up, if not set up then verify not to pass;
B2: Inspection s′∈[1,n-1] Whether set up, if not set up then verify not to pass;
B3: Placing m′=za∥m′;
B4: Calculates e′= Hv (m′), converts the 4.2.3 data type to an integer according to the details given in 4.2.2 and e′ of the 1th part of this text;
B5: Converts the data type of r′, s′ to integers by 4.2.2 the details given in part 1th of this text, calculating t = (r′+ s′) MODN,
If T = 0, the validation does not pass;
B6: Compute Elliptic curve point (x′1; y1′) =[s′]g + [T]pa;
B7: Converts the data type of x′1 to integers by 4.2.7 the details given in part 1th of this text, evaluates r = (e′+ x′1) MODN, and checks
Whether the r=r′ is established, if it is established, the verification is passed;

Here is the flowchart:

Finally, the most critical step is code:
signed Code

int iret;
    unsigned char entla[3] = {0};

    unsigned char za[33] = {0};
    unsigned char* Z = null, *M1 = NULL;

    int Z_len;
    ec_point* KG = NULL; 


    bignum* k = null, *e = NULL, *KGX = NULL, *kgy= null, *r=null, *s=null, *da=null;
    Entla[0] = (ida_len>>8) &0xff;

    ENTLA[1] = ida_len&0xff;
    Z_len = Ida_len + 194;

    Z = new unsigned char[z_len + 1];
    memset (Z, 0, Z_len + 1);
    memcpy (Z, Entla, 2);
    memcpy (&z[2], IDA, Ida_len);
    Bn_bn2bin (This->a, &z[ida_len+2]);
    Bn_bn2bin (This->b, &z[ida_len+34]);
    Bn_bn2bin (THIS->GX, &z[ida_len+66]);
    Bn_bn2bin (This->gy, &z[ida_len + 98]);
    Bn_bn2bin (THIS->PUBX, &z[ida_len + 130]);

    Bn_bn2bin (This->puby, &z[ida_len + 162]);
        if (!hash (Z, Z_len, ZA, "sha256")) {iret =-1;
    Goto Signature_end;
    } M1 = new unsigned char[33 + M_len];
    memset (M1, 0, + M_len);
    memcpy (M1, ZA, 32); memcpy (&m1[32], M, M_len);
        if (!hash (M1, M_len +, ZA, "sha256")) {iret =-2;
    Goto Signature_end;
    } k = Bn_new ();

    Bn_rand_range (k, this->z);
    E = Bn_new ();

    Bn_bin2bn (ZA, E);
    KG = Ec_point_new (This->mgroup);

    Ec_point_mul (This->mgroup, KG, NULL, THIS->MGP, K, this->ctx);
    KGX = Bn_new ();

    KGy = Bn_new (); if (!
        EC_POINT_GET_AFFINE_COORDINATES_GFP (This->mgroup, KG, KGX, KGy, This->ctx)) {iret =-3;
    Goto Signature_end;
    } r = Bn_new ();

    s = bn_new ();
    R= (e+x1) Modn Bn_add (S, KGX, E);

    Bn_mod (R, S, This->z, this->ctx);
    S= ((K−R*DA) * (1 + dA) inverse) modn DA = Bn_new ();
    Bn_copy (DA, Ec_key_get0_private_key (This->mkey));
    Bn_mul (S, R, DA, This->ctx);

    Bn_sub (k, K, s);

    Bn_add_word (DA, 1);
    Bn_mod_inverse (S, DA, This->z, This->ctx);
    Bn_mod_mul (S, S, K, this->z, This->ctx);
    Bn_bn2bin (R, out); BN_bn2bin (S, &out[bn_num_bytes (R)));
    Signature_end:if (M1!= NULL) delete[] M1;

    if (z!= NULL) delete[] Z;
    M1 = NULL;

    Z = NULL;

    if (kg!= NULL) ec_point_free (kg);
    if (k!= NULL) Bn_free (k);
    if (e!= NULL) Bn_free (e);
    if (kgx!= NULL) bn_free (KGX);
    if (kGy!= NULL) bn_free (kGy);
    if (r!= NULL) Bn_free (R);
    if (S!= NULL) Bn_free (s);

    if (da!= NULL) bn_free (DA); return iret;

Verification Algorithm

int iret;
    unsigned char br[65] = {0};

    unsigned char bs[65] = {0};
    int Z_len; 
    unsigned char* Z = null, *M1 = NULL;
    unsigned char za[33] = {0};

    unsigned char entla[3] = {0};
    ec_point* T = null, *SG = NULL, *tpa= null;

    bignum* r = null, *s = NULL, *temp= null, *e = NULL, *t = NULL, *x = NULL, *y = NULL;
    memcpy (&br[32], sign, 32);

    memcpy (&bs[32], &sign[32], 32);
    R = bn_new ();

    s = bn_new ();
    Bn_bin2bn (BR, R);

    Bn_bin2bn (BS, s);
    temp = Bn_new ();

    Bn_one (temp); if (bn_ucmp (R, this->z) >0 | | BN_UCMP (S, this->z) >0 | | BN_UCMP (temp, R) > 0 | |
        BN_UCMP (temp, s) > 0) {iret =-1;
    Goto Verify_end;
    } Z_len = Ida_len + 194;


    Z = new unsigned char[z_len + 1];
    Entla[0] = (ida_len>>8) &0xff;

    ENTLA[1] = ida_len&0xff;
    memset (Z, 0, Z_len + 1);
    memcpy (Z, Entla, 2);
memcpy (&z[2], IDA, Ida_len);    Bn_bn2bin (This->a, &z[ida_len+2]);
    Bn_bn2bin (This->b, &z[ida_len+34]);
    Bn_bn2bin (THIS->GX, &z[ida_len+66]);
    Bn_bn2bin (This->gy, &z[ida_len + 98]);
    Bn_bn2bin (THIS->PUBX, &z[ida_len + 130]);


    Bn_bn2bin (This->puby, &z[ida_len + 162]);

    Hash (Z, Z_len, ZA, "sha256");
    M1 = new unsigned char[33 + M_len];
    memset (M1, 0, + M_len);
    memcpy (M1, ZA, 32);

    memcpy (&m1[32], M, M_len);

    Hash (M1, M_len +, ZA, "sha256");
    E = Bn_new ();

    Bn_bin2bn (ZA, E);
    t = bn_new ();

    Bn_mod_add (T, R, S, This->z, this->ctx);
    SG = Ec_point_new (This->mgroup);

    TPa = Ec_point_new (This->mgroup);

    Ec_point_mul (This->mgroup, SG, NULL, THIS->MGP, S, this->ctx);

    Ec_point_mul (This->mgroup, TPa, NULL, Ec_key_get0_public_key (This->mkey), T, This->ctx);
    T = Ec_point_new (This->mgroup); Ec_point_add (This->mgroup, T, SG, TPa, this->CTX);
    x = Bn_new ();

    y = bn_new (); if (!
        EC_POINT_GET_AFFINE_COORDINATES_GFP (This->mgroup, T, X, Y, This->ctx)) {iret =-2;
    Goto Verify_end;

    } bn_mod_add (temp, x, E, this->z, this->ctx);
        if (bn_cmp (temp, R)) {iret =-3;
    Goto Verify_end;
    } verify_end:if (z!= NULL) delete[] Z;

    if (M1!= NULL) delete[] M1;
    Z = NULL;

    M1 = NULL;
    if (SG!= NULL) ec_point_free (SG);
    if (TPA!= NULL) ec_point_free (TPA);

    if (t!= NULL) ec_point_free (t);
    if (r!= NULL) Bn_free (R);
    if (S!= NULL) Bn_free (s);
    if (temp!= NULL) bn_free (temp);
    if (e!= NULL) Bn_free (e);
    if (t!= NULL) bn_free (t);
    if (x!= NULL) bn_free (x);

    if (y!= NULL) bn_free (y); return iret;

This is just the implementation of the Code, I will optimize the efficiency of the algorithm, but it is true that we call the OpenSSL optimization range may be small, the good can go to all of their own to achieve the following, and now very few people use the soft algorithm, we all use hardware encryption.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.