📄 sigex.xml
字号:
<chapter id="tutorial"><title>Tutorial</title><para>This chapter walks through how one might implement theBoneh-Lynn-Shacham (BLS) signature scheme using the PBC library.It is based on the file <filename>example/bls.c</filename>.</para><para>Recall the scheme works as follows. We have three groupsG1, G2, GT of prime order r, and have somebilinear map e that takes two elements as input,one from G1 and one from G2,and outputs an element of GT.</para><para>First we publish the system parameter g which is a randomlychosen element of G2.</para><para>Now suppose Alice wishes to use the system.We generate her public and private keys as follows.A private key is a random element x of Zr, andthe corresponding public key is g^x.</para><para>To sign a message, Alice hashes the message to some elementh of G1, and then outputs the signature h^x.</para><para>To verify a signature sigma, one checks that e(h,g^x) = e(sigma, g).</para><section><title>BLS Signatures</title><para>First we include <filename>pbc.h</filename>:</para><screen>#include <pbc.h></screen><para>Next we initialize a pairing:</para><screen> pairing_t pairing; pairing_init_inp_str(pairing, stdin);</screen><para>Later we will give pairing parameters to our programon standard input. Any file in the <filename>param</filename> subdirectorywill suffice, for example:</para><screen>bls < param/a.param</screen><para>We shall need several <type>element_t</type> variables tohold the system parameters, keys and other quantities. We declarethem and initialize them,</para><screen> element_t g, h; element_t public_key, secret_key; element_t sig; element_t temp1, temp2; element_init_G2(g, pairing); element_init_G2(public_key, pairing); element_init_G1(h, pairing); element_init_G1(sig, pairing); element_init_GT(temp1, pairing); element_init_GT(temp2, pairing); element_init_Zr(secret_key, pairing);</screen><para>generate system parameters,</para><screen> element_random(g);</screen><para>generate a private key,</para><screen> element_random(secret_key);</screen><para>and the corresponding public key.</para><screen> element_pow_zn(public_key, g, secret_key);</screen><para>When given a message to sign, we firstcompute its hash, using some standard hash algorithm.Many libraries can do this, and this operationdoes not involve pairings, so PBC does not providefunctions for this step. For this example,and our message has already been hashed, possiblyusing another library.</para><para>Say the message hash is "ABCDEF" (a 48-bit hash).We map these bytes to an element h of G1,</para><screen> element_from_hash(h, "ABCDEF", 6);</screen><para>then sign it:</para><screen> element_pow_zn(sig, h, secret_key);</screen><para>To verify this signature, we compare theoutputs of the pairing applied to the signature and system parameter,and the pairing applied to the message hash and public key.If the pairing outputs match then the signature is valid.</para><screen> pairing_apply(temp1, sig, g, pairing); pairing_apply(temp2, h, public_key, pairing); if (!element_cmp(temp1, temp2)) { printf("signature verifies\n"); } else { printf("signature does not verify\n"); }</screen></section><section><title>Import/Export</title><para>To be useful, at some stage the signature must be convertedto bytes for storage or transmission:</para><screen> int n = pairing_length_in_bytes_compressed_G1(pairing); //alternative: //int n = element_length_in_bytes_compressed(sig); unsigned char *data = malloc(n); element_to_bytes_compressed(data, sig);</screen><para>On the other end, the signature must be decompressed:</para><screen> element_from_bytes_compressed(sig, data);</screen><para>Eliding <function>_compressed</function> in the above codewill also work but the buffer ''data'' will be roughly twice as large.</para><para>We can save more space by using the x-coordinate of the signature only</para><screen> int n = pairing_length_in_bytes_x_only_G1(pairing); //alternative: //int n = element_length_in_bytes_x_only(sig); unsigned char *data = malloc(n); element_to_bytes_compressed(data, sig);</screen><para>but then there is a complication during verification since two differentpoints have the same x-coordinate. One way to solve this problem is toguess one point and try to verify. If that fails, we try the other.It can be shown that the pairing outputs of the two points are inversesof each other, avoiding the need to compute a pairing the second time.(Actually, there are better ways to handle this.)</para><screen> int n = pairing_length_in_bytes_x_only_G1(pairing); //int n = element_length_in_bytes_x_only(sig); unsigned char *data = malloc(n); element_to_bytes_x_only(data, sig); element_from_bytes_x_only(sig, data) pairing_apply(temp1, sig, g, pairing); pairing_apply(temp2, h, public_key, pairing); if (!element_cmp(temp1, temp2)) { printf("signature verifies on first guess\n"); } else { element_invert(temp1, temp1); if (!element_cmp(temp1, temp2)) { printf("signature verifies on second guess\n"); } else { printf("signature does not verify\n"); } }</screen></section></chapter>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -