Codebase list libcryptx-perl / 1037a09
Update upstream source from tag 'upstream/0.056' Update to upstream version '0.056' with Debian dir 289b6372ddd8c740dfad7b38378cc7ae1544ba1d gregor herrmann 6 years ago
308 changed file(s) with 7707 addition(s) and 6737 deletion(s). Raw diff Collapse all Expand all
00 Changes for CryptX
1
2 0.056 2017-12-22
3 - new Crypt::Stream::Rabbit
14
25 0.055 2017-11-28
36 - new Crypt::Cipher::IDEA
7272 sosemanuk_state state;
7373 int id;
7474 } *Crypt__Stream__Sosemanuk;
75
76 typedef struct rabbit_struct { /* used by Crypt::Stream::Rabbit */
77 rabbit_state state;
78 int id;
79 } *Crypt__Stream__Rabbit;
7580
7681 typedef struct rc4_struct { /* used by Crypt::Stream::RC4 */
7782 rc4_state state;
622627 if (len == 0) XSRETURN_UNDEF;
623628
624629 mp_init(&mpi);
625 if (mp_read_unsigned_bin(&mpi, in_data, len) == CRYPT_OK) {
630 if (mp_read_unsigned_bin(&mpi, in_data, (unsigned long)len) == CRYPT_OK) {
626631 mp_init_copy(&tmp, &mpi);
627632 while (mp_iszero(&tmp) == MP_NO) {
628633 mp_div_d(&tmp, (mp_digit)radix, &tmp, &d);
692697 INCLUDE: inc/CryptX_Stream_RC4.xs.inc
693698 INCLUDE: inc/CryptX_Stream_Sober128.xs.inc
694699 INCLUDE: inc/CryptX_Stream_Sosemanuk.xs.inc
700 INCLUDE: inc/CryptX_Stream_Rabbit.xs.inc
695701
696702 INCLUDE: inc/CryptX_Mac_F9.xs.inc
697703 INCLUDE: inc/CryptX_Mac_HMAC.xs.inc
3131 inc/CryptX_PK_RSA.xs.inc
3232 inc/CryptX_PRNG.xs.inc
3333 inc/CryptX_Stream_ChaCha.xs.inc
34 inc/CryptX_Stream_Rabbit.xs.inc
3435 inc/CryptX_Stream_RC4.xs.inc
3536 inc/CryptX_Stream_Salsa20.xs.inc
3637 inc/CryptX_Stream_Sober128.xs.inc
131132 lib/Crypt/PRNG/Sober128.pm
132133 lib/Crypt/PRNG/Yarrow.pm
133134 lib/Crypt/Stream/ChaCha.pm
135 lib/Crypt/Stream/Rabbit.pm
134136 lib/Crypt/Stream/RC4.pm
135137 lib/Crypt/Stream/Salsa20.pm
136138 lib/Crypt/Stream/Sober128.pm
309311 src/ltc/misc/base64/base64_encode.c
310312 src/ltc/misc/burn_stack.c
311313 src/ltc/misc/compare_testvector.c
314 src/ltc/misc/copy_or_zeromem.c
312315 src/ltc/misc/crc32.c
313316 src/ltc/misc/crypt/crypt.c
314317 src/ltc/misc/crypt/crypt_argchk.c
525528 src/ltc/stream/chacha/chacha_ivctr64.c
526529 src/ltc/stream/chacha/chacha_keystream.c
527530 src/ltc/stream/chacha/chacha_setup.c
531 src/ltc/stream/rabbit/rabbit.c
528532 src/ltc/stream/rc4/rc4_stream.c
529533 src/ltc/stream/salsa20/salsa20_crypt.c
530534 src/ltc/stream/salsa20/salsa20_done.c
712716 t/cipher_serpent_compat.t
713717 t/cipher_skipjack.t
714718 t/cipher_stream.t
719 t/cipher_stream_rabbit.t
715720 t/cipher_stream_salsa20.t
716721 t/cipher_test_vectors_ltc.t
717722 t/cipher_test_vectors_openssl.t
4444 "url" : "https://github.com/DCIT/perl-CryptX"
4545 }
4646 },
47 "version" : "0.055",
47 "version" : "0.056",
4848 "x_serialization_backend" : "JSON::PP version 2.94"
4949 }
2121 resources:
2222 bugtracker: https://github.com/DCIT/perl-CryptX/issues
2323 repository: https://github.com/DCIT/perl-CryptX
24 version: '0.055'
24 version: '0.056'
2525 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
2121
2222 - Stream ciphers
2323
24 [Crypt::Stream::RC4](https://metacpan.org/pod/Crypt::Stream::RC4), [Crypt::Stream::ChaCha](https://metacpan.org/pod/Crypt::Stream::ChaCha), [Crypt::Stream::Salsa20](https://metacpan.org/pod/Crypt::Stream::Salsa20), [Crypt::Stream::Sober128](https://metacpan.org/pod/Crypt::Stream::Sober128), [Crypt::Stream::Sosemanuk](https://metacpan.org/pod/Crypt::Stream::Sosemanuk)
24 [Crypt::Stream::RC4](https://metacpan.org/pod/Crypt::Stream::RC4), [Crypt::Stream::ChaCha](https://metacpan.org/pod/Crypt::Stream::ChaCha), [Crypt::Stream::Salsa20](https://metacpan.org/pod/Crypt::Stream::Salsa20), [Crypt::Stream::Sober128](https://metacpan.org/pod/Crypt::Stream::Sober128),
25 [Crypt::Stream::Sosemanuk](https://metacpan.org/pod/Crypt::Stream::Sosemanuk), [Crypt::Stream::Rabbit](https://metacpan.org/pod/Crypt::Stream::Rabbit)
2526
2627 - Authenticated encryption modes
2728
2626 Newz(0, RETVAL, 1, struct ccm_struct);
2727 if (!RETVAL) croak("FATAL: Newz failed");
2828
29 rv = ccm_init(&RETVAL->state, id, k, (unsigned long)k_len, pt_len, tag_len, h_len);
29 rv = ccm_init(&RETVAL->state, id, k, (int)k_len, (int)pt_len, (int)tag_len, (int)h_len); /* XXX-TODO why int? */
3030 if (rv != CRYPT_OK) {
3131 Safefree(RETVAL);
3232 croak("FATAL: ccm_init failed: %s", error_to_string(rv));
8989 SvREFCNT_dec(RETVAL);
9090 croak("FATAL: ccm_process failed: %s", error_to_string(rv));
9191 }
92 self->pt_len -= in_data_len;
92 self->pt_len -= (unsigned long)in_data_len;
9393 }
9494 }
9595 OUTPUT:
9999 decrypt_add(Crypt::AuthEnc::CCM self, SV * data)
100100 CODE:
101101 {
102 int rv, i;
102 int rv;
103103 STRLEN in_data_len;
104104 unsigned char *in_data, *out_data;
105105
122122 SvREFCNT_dec(RETVAL);
123123 croak("FATAL: ccm_process failed: %s", error_to_string(rv));
124124 }
125 self->pt_len -= in_data_len;
125 self->pt_len -= (unsigned long)in_data_len;
126126 }
127127 }
128128 OUTPUT:
33 new(Class)
44 CODE:
55 {
6 int rv;
76 Newz(0, RETVAL, 1, crc32_state);
87 if (!RETVAL) croak("FATAL: Newz failed");
98 crc32_init(RETVAL); /* returns void */
8282 if (len == 0) {
8383 RETVAL = newSVpvn("", 0);
8484 }
85 else if (len == self->desc->block_length) {
85 else if (len == (STRLEN)self->desc->block_length) {
8686 RETVAL = NEWSV(0, len);
8787 SvPOK_only(RETVAL);
8888 SvCUR_set(RETVAL, len);
112112 if (len == 0) {
113113 RETVAL = newSVpvn("", 0);
114114 }
115 else if (len == self->desc->block_length) {
115 else if (len == (STRLEN)self->desc->block_length) {
116116 RETVAL = NEWSV(0, len);
117117 SvPOK_only(RETVAL);
118118 SvCUR_set(RETVAL, len);
7171 SvPOK_only(RETVAL);
7272 SvCUR_set(RETVAL, out_len);
7373 out_data = (unsigned char *)SvPVX(RETVAL);
74 rv = sha3_shake_done(&self->state, out_data, out_len);
74 rv = sha3_shake_done(&self->state, out_data, (unsigned long)out_len);
7575 if (rv != CRYPT_OK) {
7676 SvREFCNT_dec(RETVAL);
7777 croak("FATAL: sha3_shake_done failed: %s", error_to_string(rv));
6565 STRLEN data_len=0;
6666 data = (unsigned char *)SvPVbyte(dhparam, data_len);
6767 /* load d p q */
68 rv = dh_set_pg_dhparam(data, data_len, &self->key);
68 rv = dh_set_pg_dhparam(data, (unsigned long)data_len, &self->key);
6969 if (rv != CRYPT_OK) croak("FATAL: dh_set_pg_dhparam failed: %s", error_to_string(rv));
7070 /* gen the key */
7171 rv = dh_generate_key(&self->pstate, self->pindex, &self->key);
4141 STRLEN data_len=0;
4242 data = (unsigned char *)SvPVbyte(dsaparam, data_len);
4343 /* load d p q */
44 rv = dsa_set_pqg_dsaparam(data, data_len, &self->key);
44 rv = dsa_set_pqg_dsaparam(data, (unsigned long)data_len, &self->key);
4545 if (rv != CRYPT_OK) croak("FATAL: dsa_set_pqg_dsaparam failed: %s", error_to_string(rv));
4646 /* gen the key */
4747 rv = dsa_generate_key(&self->pstate, self->pindex, &self->key);
6363 pwd = (unsigned char *)SvPVbyte(passwd, pwd_len);
6464 }
6565 _ecc_free_key(&self->key, &self->dp);
66 rv = ecc_import_pkcs8(data, (unsigned long)data_len, pwd, pwd_len, &self->key, &self->dp);
66 rv = ecc_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key, &self->dp);
6767 if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv));
6868 XPUSHs(ST(0)); /* return self */
6969 }
6161 pwd = (unsigned char *)SvPVbyte(passwd, pwd_len);
6262 }
6363 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
64 rv = rsa_import_pkcs8(data, (unsigned long)data_len, pwd, pwd_len, &self->key);
64 rv = rsa_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key);
6565 if (rv != CRYPT_OK) croak("FATAL: rsa_import_pkcs8 failed: %s", error_to_string(rv));
6666 XPUSHs(ST(0)); /* return self */
6767 }
6969 SvPOK_only(RETVAL);
7070 SvCUR_set(RETVAL, out_len);
7171 out_data = (unsigned char *)SvPVX(RETVAL);
72 rv = chacha_keystream(&self->state, out_data, out_len);
72 rv = chacha_keystream(&self->state, out_data, (unsigned long)out_len);
7373 if (rv != CRYPT_OK) {
7474 SvREFCNT_dec(RETVAL);
7575 croak("FATAL: chacha_keystream failed: %s", error_to_string(rv));
4848 SvPOK_only(RETVAL);
4949 SvCUR_set(RETVAL, out_len);
5050 out_data = (unsigned char *)SvPVX(RETVAL);
51 rv = rc4_stream_keystream(&self->state, out_data, out_len);
51 rv = rc4_stream_keystream(&self->state, out_data, (unsigned long)out_len);
5252 if (rv != CRYPT_OK) {
5353 SvREFCNT_dec(RETVAL);
5454 croak("FATAL: rc4_stream_keystream failed: %s", error_to_string(rv));
0 MODULE = CryptX PACKAGE = Crypt::Stream::Rabbit
1
2 Crypt::Stream::Rabbit
3 new(Class, SV * key, SV * nonce=&PL_sv_undef)
4 CODE:
5 {
6 int rv;
7 STRLEN iv_len=0, k_len=0;
8 unsigned char *iv=NULL, *k=NULL;
9
10 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
11 k = (unsigned char *)SvPVbyte(key, k_len);
12
13 Newz(0, RETVAL, 1, struct rabbit_struct);
14 if (!RETVAL) croak("FATAL: Newz failed");
15
16 rv = rabbit_setup(&RETVAL->state, k, (unsigned long)k_len);
17 if (rv != CRYPT_OK) {
18 Safefree(RETVAL);
19 croak("FATAL: rabbit_setup failed: %s", error_to_string(rv));
20 }
21
22 if (SvOK(nonce)) {
23 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
24 iv = (unsigned char *)SvPVbyte(nonce, iv_len);
25 rv = rabbit_setiv(&RETVAL->state, iv, (unsigned long)iv_len);
26 if (rv != CRYPT_OK) {
27 Safefree(RETVAL);
28 croak("FATAL: rabbit_setiv failed: %s", error_to_string(rv));
29 }
30 }
31
32 }
33 OUTPUT:
34 RETVAL
35
36 void
37 DESTROY(Crypt::Stream::Rabbit self)
38 CODE:
39 rabbit_done(&self->state);
40 Safefree(self);
41
42 Crypt::Stream::Rabbit
43 clone(Crypt::Stream::Rabbit self)
44 CODE:
45 Newz(0, RETVAL, 1, struct rabbit_struct);
46 if (!RETVAL) croak("FATAL: Newz failed");
47 Copy(&self->state, &RETVAL->state, 1, struct rabbit_struct);
48 OUTPUT:
49 RETVAL
50
51 SV *
52 keystream(Crypt::Stream::Rabbit self, STRLEN out_len)
53 CODE:
54 {
55 int rv;
56 unsigned char *out_data;
57
58 RETVAL = NEWSV(0, out_len);
59 SvPOK_only(RETVAL);
60 SvCUR_set(RETVAL, out_len);
61 out_data = (unsigned char *)SvPVX(RETVAL);
62 rv = rabbit_keystream(&self->state, out_data, (unsigned long)out_len);
63 if (rv != CRYPT_OK) {
64 SvREFCNT_dec(RETVAL);
65 croak("FATAL: rabbit_keystream failed: %s", error_to_string(rv));
66 }
67 }
68 OUTPUT:
69 RETVAL
70
71 SV *
72 crypt(Crypt::Stream::Rabbit self, SV * data)
73 CODE:
74 {
75 int rv;
76 STRLEN in_data_len;
77 unsigned char *in_data, *out_data;
78
79 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
80 if (in_data_len == 0) {
81 RETVAL = newSVpvn("", 0);
82 }
83 else {
84 RETVAL = NEWSV(0, in_data_len);
85 SvPOK_only(RETVAL);
86 SvCUR_set(RETVAL, in_data_len);
87 out_data = (unsigned char *)SvPVX(RETVAL);
88 rv = rabbit_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
89 if (rv != CRYPT_OK) {
90 SvREFCNT_dec(RETVAL);
91 croak("FATAL: rabbit_crypt failed: %s", error_to_string(rv));
92 }
93 }
94 }
95 OUTPUT:
96 RETVAL
5656 SvPOK_only(RETVAL);
5757 SvCUR_set(RETVAL, out_len);
5858 out_data = (unsigned char *)SvPVX(RETVAL);
59 rv = salsa20_keystream(&self->state, out_data, out_len);
59 rv = salsa20_keystream(&self->state, out_data, (unsigned long)out_len);
6060 if (rv != CRYPT_OK) {
6161 SvREFCNT_dec(RETVAL);
6262 croak("FATAL: salsa20_keystream failed: %s", error_to_string(rv));
5656 SvPOK_only(RETVAL);
5757 SvCUR_set(RETVAL, out_len);
5858 out_data = (unsigned char *)SvPVX(RETVAL);
59 rv = sober128_stream_keystream(&self->state, out_data, out_len);
59 rv = sober128_stream_keystream(&self->state, out_data, (unsigned long)out_len);
6060 if (rv != CRYPT_OK) {
6161 SvREFCNT_dec(RETVAL);
6262 croak("FATAL: sober128_stream_keystream failed: %s", error_to_string(rv));
6262 SvPOK_only(RETVAL);
6363 SvCUR_set(RETVAL, out_len);
6464 out_data = (unsigned char *)SvPVX(RETVAL);
65 rv = sosemanuk_keystream(&self->state, out_data, out_len);
65 rv = sosemanuk_keystream(&self->state, out_data, (unsigned long)out_len);
6666 if (rv != CRYPT_OK) {
6767 SvREFCNT_dec(RETVAL);
6868 croak("FATAL: sosemanuk_keystream failed: %s", error_to_string(rv));
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::AuthEnc Exporter);
77 our %EXPORT_TAGS = ( all => [qw( ccm_encrypt_authenticate ccm_decrypt_verify )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::AuthEnc Exporter);
77 our %EXPORT_TAGS = ( all => [qw( chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::AuthEnc Exporter);
77 our %EXPORT_TAGS = ( all => [qw( eax_encrypt_authenticate eax_decrypt_verify )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::AuthEnc Exporter);
77 our %EXPORT_TAGS = ( all => [qw( gcm_encrypt_authenticate gcm_decrypt_verify )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::AuthEnc Exporter);
77 our %EXPORT_TAGS = ( all => [qw( ocb_encrypt_authenticate ocb_decrypt_verify )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 sub CLONE_SKIP { 1 } # prevent cloning
77
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use Carp;
77 $Carp::Internal{(__PACKAGE__)}++;
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use Carp;
77 $Carp::Internal{(__PACKAGE__)}++;
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw/
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use CryptX;
99 use base 'Crypt::Cipher';
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use Carp;
77 $Carp::Internal{(__PACKAGE__)}++;
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use Carp;
77 $Carp::Internal{(__PACKAGE__)}++;
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Digest Exporter);
99 our %EXPORT_TAGS = ( all => [qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw(pbkdf1 pbkdf2 hkdf hkdf_expand hkdf_extract)] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2b blake2b_hex blake2b_b64 blake2b_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( blake2s blake2s_hex blake2s_b64 blake2s_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( f9 f9_hex f9_b64 f9_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( hmac hmac_hex hmac_b64 hmac_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( omac omac_hex omac_b64 omac_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( pmac pmac_hex pmac_b64 pmac_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( pelican pelican_hex pelican_b64 pelican_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( poly1305 poly1305_hex poly1305_b64 poly1305_b64u )] );
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use base qw(Crypt::Mac Exporter);
99 our %EXPORT_TAGS = ( all => [qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw( mac mac_hex )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import';
77 use Carp 'croak';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use Crypt::Cipher;
99 use base 'Crypt::Mode';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use Crypt::Cipher;
99 use base 'Crypt::Mode';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use Crypt::Cipher;
99 use base 'Crypt::Mode';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use Crypt::Cipher;
99 use base 'Crypt::Mode';
33
44 use strict;
55 use warnings;
6 our $VERSION = '0.055';
6 our $VERSION = '0.056';
77
88 use Crypt::Cipher;
99 use base 'Crypt::Mode';
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 ### METHODS
77
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw( dh_shared_secret )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw( dsa_encrypt dsa_decrypt dsa_sign_message dsa_verify_message dsa_sign_hash dsa_verify_hash )] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw( ecc_encrypt ecc_decrypt ecc_sign_message ecc_verify_message ecc_sign_hash ecc_verify_hash ecc_shared_secret )] );
10931093
10941094 =head2 export_key_raw
10951095
1096 Export raw public/private key. Public key is exported in ANS X9.63 format (compressed or uncompressed),
1096 Export raw public/private key. Public key is exported in ASN X9.62 format (compressed or uncompressed),
10971097 private key is exported as raw bytes (padded with leading zeros to have the same size as the ECC curve).
10981098
10991099 my $pubkey_octets = $pk->export_key_raw('public');
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import';
77 our %EXPORT_TAGS = ( all => [qw(rsa_encrypt rsa_decrypt rsa_sign_message rsa_verify_message rsa_sign_hash rsa_verify_hash)] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use Carp;
77
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::PRNG Exporter);
77 our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::PRNG Exporter);
77 our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::PRNG Exporter);
77 our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::PRNG Exporter);
77 our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Crypt::PRNG Exporter);
77 our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Exporter);
77 our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] );
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use CryptX;
77
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use CryptX;
77
0 package Crypt::Stream::Rabbit;
1
2 use strict;
3 use warnings;
4 our $VERSION = '0.056';
5
6 use CryptX;
7
8 1;
9
10 =pod
11
12 =head1 NAME
13
14 Crypt::Stream::Rabbit - Stream cipher Rabbit
15
16 =head1 SYNOPSIS
17
18 use Crypt::Stream::Rabbit;
19
20 # encrypt
21 $key = "1234567890123456";
22 $iv = "12345678";
23 $stream = Crypt::Stream::Rabbit->new($key, $iv);
24 $ct = $stream->crypt("plain message");
25
26 # decrypt
27 $key = "1234567890123456";
28 $iv = "12345678";
29 $stream = Crypt::Stream::Rabbit->new($key, $iv);
30 $pt = $stream->crypt($ct);
31
32 =head1 DESCRIPTION
33
34 Provides an interface to the Rabbit stream cipher.
35
36 =head1 METHODS
37
38 =head2 new
39
40 $stream = Crypt::Stream::Rabbit->new($key, $iv);
41 # $key .. keylen must be up to 16 bytes
42 # $iv .. ivlen must be up to 8 bytes
43
44 $stream = Crypt::Stream::Rabbit->new($key);
45 #BEWARE: this is different from new($key, "")
46
47 =head2 crypt
48
49 $ciphertext = $stream->crypt($plaintext);
50 #or
51 $plaintext = $stream->crypt($ciphertext);
52
53 =head2 keystream
54
55 $random_key = $stream->keystream($length);
56
57 =head2 clone
58
59 $stream->clone();
60
61 =head1 SEE ALSO
62
63 =over
64
65 =item * L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128>
66
67 =item * L<https://en.wikipedia.org/wiki/Rabbit_(cipher)>
68
69 =back
70
71 =cut
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use CryptX;
77
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use CryptX;
77
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use CryptX;
77
6161
6262 =item * L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128>
6363
64 =item * L<https://en.wikipedia.org/wiki/SOBER-128|https://en.wikipedia.org/wiki/SOBER-128>
64 =item * L<https://en.wikipedia.org/wiki/SOSEMANUK>
6565
6666 =back
6767
11
22 use strict;
33 use warnings ;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use base qw(Exporter);
77 our @EXPORT_OK = qw();
8484
8585 =item * Stream ciphers
8686
87 L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128>, L<Crypt::Stream::Sosemanuk>
87 L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128>,
88 L<Crypt::Stream::Sosemanuk>, L<Crypt::Stream::Rabbit>
8889
8990 =item * Authenticated encryption modes
9091
11
22 use strict;
33 use warnings;
4 our $VERSION = '0.055';
4 our $VERSION = '0.056';
55
66 use CryptX;
77
3939 ltc/mac/xcbc/xcbc_file.o ltc/mac/xcbc/xcbc_init.o ltc/mac/xcbc/xcbc_memory.o ltc/mac/xcbc/xcbc_memory_multi.o \
4040 ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/radix_to_bin.o \
4141 ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \
42 ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/crc32.o \
43 ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o ltc/misc/zeromem.o \
44 ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o ltc/misc/base64/base64_decode.o \
45 ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o \
46 ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_constants.o \
47 ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o \
48 ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o \
49 ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o \
50 ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o \
51 ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o \
52 ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \
42 ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/copy_or_zeromem.o \
43 ltc/misc/crc32.o ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o \
44 ltc/misc/zeromem.o ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o \
45 ltc/misc/base64/base64_decode.o ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o \
46 ltc/misc/crypt/crypt_argchk.o ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o \
47 ltc/misc/crypt/crypt_constants.o ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o \
48 ltc/misc/crypt/crypt_find_cipher_id.o ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o \
49 ltc/misc/crypt/crypt_find_hash_id.o ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o \
50 ltc/misc/crypt/crypt_fsa.o ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o \
51 ltc/misc/crypt/crypt_inits.o ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o \
52 ltc/misc/crypt/crypt_prng_is_valid.o ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \
5353 ltc/misc/crypt/crypt_register_all_hashes.o ltc/misc/crypt/crypt_register_all_prngs.o \
5454 ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o \
5555 ltc/misc/crypt/crypt_sizes.o ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o \
115115 ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \
116116 ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \
117117 ltc/stream/chacha/chacha_ivctr32.o ltc/stream/chacha/chacha_ivctr64.o ltc/stream/chacha/chacha_keystream.o \
118 ltc/stream/chacha/chacha_setup.o ltc/stream/rc4/rc4_stream.o ltc/stream/salsa20/salsa20_crypt.o \
119 ltc/stream/salsa20/salsa20_done.o ltc/stream/salsa20/salsa20_ivctr64.o ltc/stream/salsa20/salsa20_keystream.o \
120 ltc/stream/salsa20/salsa20_setup.o ltc/stream/sober128/sober128_stream.o ltc/stream/sosemanuk/sosemanuk.o \
121 ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o \
122 ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o \
123 ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o ltm/bn_mp_addmod.o ltm/bn_mp_add_d.o \
124 ltm/bn_mp_and.o ltm/bn_mp_clamp.o ltm/bn_mp_clear.o ltm/bn_mp_clear_multi.o ltm/bn_mp_cmp.o \
125 ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o ltm/bn_mp_cnt_lsb.o ltm/bn_mp_copy.o ltm/bn_mp_count_bits.o \
126 ltm/bn_mp_div.o ltm/bn_mp_div_2.o ltm/bn_mp_div_2d.o ltm/bn_mp_div_3.o ltm/bn_mp_div_d.o \
127 ltm/bn_mp_dr_is_modulus.o ltm/bn_mp_dr_reduce.o ltm/bn_mp_dr_setup.o ltm/bn_mp_exch.o \
128 ltm/bn_mp_export.o ltm/bn_mp_exptmod.o ltm/bn_mp_exptmod_fast.o ltm/bn_mp_expt_d.o \
129 ltm/bn_mp_expt_d_ex.o ltm/bn_mp_exteuclid.o ltm/bn_mp_fread.o ltm/bn_mp_fwrite.o \
130 ltm/bn_mp_gcd.o ltm/bn_mp_get_int.o ltm/bn_mp_get_long.o ltm/bn_mp_get_long_long.o \
118 ltc/stream/chacha/chacha_setup.o ltc/stream/rabbit/rabbit.o ltc/stream/rc4/rc4_stream.o \
119 ltc/stream/salsa20/salsa20_crypt.o ltc/stream/salsa20/salsa20_done.o ltc/stream/salsa20/salsa20_ivctr64.o \
120 ltc/stream/salsa20/salsa20_keystream.o ltc/stream/salsa20/salsa20_setup.o ltc/stream/sober128/sober128_stream.o \
121 ltc/stream/sosemanuk/sosemanuk.o ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o \
122 ltm/bn_fast_mp_montgomery_reduce.o ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o \
123 ltm/bn_fast_s_mp_sqr.o ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o ltm/bn_mp_addmod.o \
124 ltm/bn_mp_add_d.o ltm/bn_mp_and.o ltm/bn_mp_clamp.o ltm/bn_mp_clear.o ltm/bn_mp_clear_multi.o \
125 ltm/bn_mp_cmp.o ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o ltm/bn_mp_cnt_lsb.o ltm/bn_mp_copy.o \
126 ltm/bn_mp_count_bits.o ltm/bn_mp_div.o ltm/bn_mp_div_2.o ltm/bn_mp_div_2d.o ltm/bn_mp_div_3.o \
127 ltm/bn_mp_div_d.o ltm/bn_mp_dr_is_modulus.o ltm/bn_mp_dr_reduce.o ltm/bn_mp_dr_setup.o \
128 ltm/bn_mp_exch.o ltm/bn_mp_export.o ltm/bn_mp_exptmod.o ltm/bn_mp_exptmod_fast.o \
129 ltm/bn_mp_expt_d.o ltm/bn_mp_expt_d_ex.o ltm/bn_mp_exteuclid.o ltm/bn_mp_fread.o \
130 ltm/bn_mp_fwrite.o ltm/bn_mp_gcd.o ltm/bn_mp_get_int.o ltm/bn_mp_get_long.o ltm/bn_mp_get_long_long.o \
131131 ltm/bn_mp_grow.o ltm/bn_mp_import.o ltm/bn_mp_init.o ltm/bn_mp_init_copy.o ltm/bn_mp_init_multi.o \
132132 ltm/bn_mp_init_set.o ltm/bn_mp_init_set_int.o ltm/bn_mp_init_size.o ltm/bn_mp_invmod.o \
133133 ltm/bn_mp_invmod_slow.o ltm/bn_mp_is_square.o ltm/bn_mp_jacobi.o ltm/bn_mp_karatsuba_mul.o \
4242 ltc/mac/xcbc/xcbc_init.obj ltc/mac/xcbc/xcbc_memory.obj ltc/mac/xcbc/xcbc_memory_multi.obj \
4343 ltc/mac/xcbc/xcbc_process.obj ltc/math/ltm_desc.obj ltc/math/multi.obj ltc/math/radix_to_bin.obj \
4444 ltc/math/rand_bn.obj ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj \
45 ltc/misc/adler32.obj ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/crc32.obj \
46 ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj ltc/misc/zeromem.obj \
47 ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj ltc/misc/base64/base64_decode.obj \
48 ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj \
49 ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \
45 ltc/misc/adler32.obj ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/copy_or_zeromem.obj \
46 ltc/misc/crc32.obj ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj \
47 ltc/misc/zeromem.obj ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj \
48 ltc/misc/base64/base64_decode.obj ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj \
49 ltc/misc/crypt/crypt_argchk.obj ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \
5050 ltc/misc/crypt/crypt_constants.obj ltc/misc/crypt/crypt_find_cipher.obj ltc/misc/crypt/crypt_find_cipher_any.obj \
5151 ltc/misc/crypt/crypt_find_cipher_id.obj ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj \
5252 ltc/misc/crypt/crypt_find_hash_id.obj ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj \
123123 ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \
124124 ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \
125125 ltc/stream/chacha/chacha_ivctr32.obj ltc/stream/chacha/chacha_ivctr64.obj ltc/stream/chacha/chacha_keystream.obj \
126 ltc/stream/chacha/chacha_setup.obj ltc/stream/rc4/rc4_stream.obj ltc/stream/salsa20/salsa20_crypt.obj \
127 ltc/stream/salsa20/salsa20_done.obj ltc/stream/salsa20/salsa20_ivctr64.obj ltc/stream/salsa20/salsa20_keystream.obj \
128 ltc/stream/salsa20/salsa20_setup.obj ltc/stream/sober128/sober128_stream.obj ltc/stream/sosemanuk/sosemanuk.obj \
129 ltm/bncore.obj ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj ltm/bn_fast_mp_montgomery_reduce.obj \
130 ltm/bn_fast_s_mp_mul_digs.obj ltm/bn_fast_s_mp_mul_high_digs.obj ltm/bn_fast_s_mp_sqr.obj \
131 ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj ltm/bn_mp_addmod.obj ltm/bn_mp_add_d.obj \
132 ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj ltm/bn_mp_clear.obj ltm/bn_mp_clear_multi.obj \
133 ltm/bn_mp_cmp.obj ltm/bn_mp_cmp_d.obj ltm/bn_mp_cmp_mag.obj ltm/bn_mp_cnt_lsb.obj \
134 ltm/bn_mp_copy.obj ltm/bn_mp_count_bits.obj ltm/bn_mp_div.obj ltm/bn_mp_div_2.obj \
135 ltm/bn_mp_div_2d.obj ltm/bn_mp_div_3.obj ltm/bn_mp_div_d.obj ltm/bn_mp_dr_is_modulus.obj \
136 ltm/bn_mp_dr_reduce.obj ltm/bn_mp_dr_setup.obj ltm/bn_mp_exch.obj ltm/bn_mp_export.obj \
137 ltm/bn_mp_exptmod.obj ltm/bn_mp_exptmod_fast.obj ltm/bn_mp_expt_d.obj ltm/bn_mp_expt_d_ex.obj \
138 ltm/bn_mp_exteuclid.obj ltm/bn_mp_fread.obj ltm/bn_mp_fwrite.obj ltm/bn_mp_gcd.obj \
139 ltm/bn_mp_get_int.obj ltm/bn_mp_get_long.obj ltm/bn_mp_get_long_long.obj ltm/bn_mp_grow.obj \
140 ltm/bn_mp_import.obj ltm/bn_mp_init.obj ltm/bn_mp_init_copy.obj ltm/bn_mp_init_multi.obj \
141 ltm/bn_mp_init_set.obj ltm/bn_mp_init_set_int.obj ltm/bn_mp_init_size.obj ltm/bn_mp_invmod.obj \
142 ltm/bn_mp_invmod_slow.obj ltm/bn_mp_is_square.obj ltm/bn_mp_jacobi.obj ltm/bn_mp_karatsuba_mul.obj \
143 ltm/bn_mp_karatsuba_sqr.obj ltm/bn_mp_lcm.obj ltm/bn_mp_lshd.obj ltm/bn_mp_mod.obj \
144 ltm/bn_mp_mod_2d.obj ltm/bn_mp_mod_d.obj ltm/bn_mp_montgomery_calc_normalization.obj \
126 ltc/stream/chacha/chacha_setup.obj ltc/stream/rabbit/rabbit.obj ltc/stream/rc4/rc4_stream.obj \
127 ltc/stream/salsa20/salsa20_crypt.obj ltc/stream/salsa20/salsa20_done.obj ltc/stream/salsa20/salsa20_ivctr64.obj \
128 ltc/stream/salsa20/salsa20_keystream.obj ltc/stream/salsa20/salsa20_setup.obj ltc/stream/sober128/sober128_stream.obj \
129 ltc/stream/sosemanuk/sosemanuk.obj ltm/bncore.obj ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj \
130 ltm/bn_fast_mp_montgomery_reduce.obj ltm/bn_fast_s_mp_mul_digs.obj ltm/bn_fast_s_mp_mul_high_digs.obj \
131 ltm/bn_fast_s_mp_sqr.obj ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj \
132 ltm/bn_mp_addmod.obj ltm/bn_mp_add_d.obj ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj ltm/bn_mp_clear.obj \
133 ltm/bn_mp_clear_multi.obj ltm/bn_mp_cmp.obj ltm/bn_mp_cmp_d.obj ltm/bn_mp_cmp_mag.obj \
134 ltm/bn_mp_cnt_lsb.obj ltm/bn_mp_copy.obj ltm/bn_mp_count_bits.obj ltm/bn_mp_div.obj \
135 ltm/bn_mp_div_2.obj ltm/bn_mp_div_2d.obj ltm/bn_mp_div_3.obj ltm/bn_mp_div_d.obj \
136 ltm/bn_mp_dr_is_modulus.obj ltm/bn_mp_dr_reduce.obj ltm/bn_mp_dr_setup.obj ltm/bn_mp_exch.obj \
137 ltm/bn_mp_export.obj ltm/bn_mp_exptmod.obj ltm/bn_mp_exptmod_fast.obj ltm/bn_mp_expt_d.obj \
138 ltm/bn_mp_expt_d_ex.obj ltm/bn_mp_exteuclid.obj ltm/bn_mp_fread.obj ltm/bn_mp_fwrite.obj \
139 ltm/bn_mp_gcd.obj ltm/bn_mp_get_int.obj ltm/bn_mp_get_long.obj ltm/bn_mp_get_long_long.obj \
140 ltm/bn_mp_grow.obj ltm/bn_mp_import.obj ltm/bn_mp_init.obj ltm/bn_mp_init_copy.obj \
141 ltm/bn_mp_init_multi.obj ltm/bn_mp_init_set.obj ltm/bn_mp_init_set_int.obj ltm/bn_mp_init_size.obj \
142 ltm/bn_mp_invmod.obj ltm/bn_mp_invmod_slow.obj ltm/bn_mp_is_square.obj ltm/bn_mp_jacobi.obj \
143 ltm/bn_mp_karatsuba_mul.obj ltm/bn_mp_karatsuba_sqr.obj ltm/bn_mp_lcm.obj ltm/bn_mp_lshd.obj \
144 ltm/bn_mp_mod.obj ltm/bn_mp_mod_2d.obj ltm/bn_mp_mod_d.obj ltm/bn_mp_montgomery_calc_normalization.obj \
145145 ltm/bn_mp_montgomery_reduce.obj ltm/bn_mp_montgomery_setup.obj ltm/bn_mp_mul.obj \
146146 ltm/bn_mp_mulmod.obj ltm/bn_mp_mul_2.obj ltm/bn_mp_mul_2d.obj ltm/bn_mp_mul_d.obj \
147147 ltm/bn_mp_neg.obj ltm/bn_mp_n_root.obj ltm/bn_mp_n_root_ex.obj ltm/bn_mp_or.obj ltm/bn_mp_prime_fermat.obj \
5050 symmetric_key *skey;
5151 int err;
5252 unsigned long len, L, x, y, z, CTRlen;
53 #ifdef LTC_FAST
54 LTC_FAST_TYPE fastMask = ~0; /* initialize fastMask at all zeroes */
55 #endif
56 unsigned char mask = 0xff; /* initialize mask at all zeroes */
5753
5854 if (uskey == NULL) {
5955 LTC_ARGCHK(key != NULL);
359355
360356 /* Zero the plaintext if the tag was invalid (in constant time) */
361357 if (ptlen > 0) {
362 y = 0;
363 mask *= 1 - err; /* mask = ( err ? 0 : 0xff ) */
364 #ifdef LTC_FAST
365 fastMask *= 1 - err;
366 if (ptlen & ~15) {
367 for (; y < (ptlen & ~15); y += 16) {
368 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
369 *(LTC_FAST_TYPE_PTR_CAST(&pt_real[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) & fastMask;
370 }
371 }
372 }
373 #endif
374 for (; y < ptlen; y++) {
375 pt_real[y] = pt[y] & mask;
376 }
358 copy_or_zeromem(pt, pt_real, ptlen, err);
377359 }
378360 }
379361
380362 #ifdef LTC_CLEAN_STACK
381 #ifdef LTC_FAST
382 fastMask = 0;
383 #endif
384 mask = 0;
385363 zeromem(PAD, sizeof(PAD));
386364 zeromem(CTRPAD, sizeof(CTRPAD));
387365 if (pt_work != NULL) {
10301030
10311031 #endif /* LTC_SALSA20 */
10321032
1033
1034
10351033 #ifdef LTC_SOSEMANUK
10361034
10371035 typedef struct {
10561054
10571055 #endif /* LTC_SOSEMANUK */
10581056
1059
1057 #ifdef LTC_RABBIT
1058
1059 typedef struct {
1060 ulong32 x[8];
1061 ulong32 c[8];
1062 ulong32 carry;
1063 } rabbit_ctx;
1064
1065 typedef struct {
1066 rabbit_ctx master_ctx;
1067 rabbit_ctx work_ctx;
1068 unsigned char block[16]; /* last keystream block containing unused bytes */
1069 ulong32 unused; /* count fm right */
1070 } rabbit_state;
1071
1072 int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen);
1073 int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen);
1074 int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out);
1075 int rabbit_keystream(rabbit_state* st, unsigned char *out, unsigned long outlen);
1076 int rabbit_done(rabbit_state *st);
1077 int rabbit_test(void);
1078
1079 #endif /* LTC_RABBIT */
10601080
10611081 #ifdef LTC_RC4_STREAM
10621082
208208 #define LTC_CHACHA
209209 #define LTC_SALSA20
210210 #define LTC_SOSEMANUK
211 #define LTC_RABBIT
211212 #define LTC_RC4_STREAM
212213 #define LTC_SOBER128_STREAM
213214
582583 #define LTC_MUTEX_INIT(x) LTC_ARGCHK(pthread_mutex_init(x, NULL) == 0);
583584 #define LTC_MUTEX_LOCK(x) LTC_ARGCHK(pthread_mutex_lock(x) == 0);
584585 #define LTC_MUTEX_UNLOCK(x) LTC_ARGCHK(pthread_mutex_unlock(x) == 0);
586 #define LTC_MUTEX_DESTROY(x) LTC_ARGCHK(pthread_mutex_destroy(x) == 0);
585587
586588 #else
587589
592594 #define LTC_MUTEX_INIT(x)
593595 #define LTC_MUTEX_LOCK(x)
594596 #define LTC_MUTEX_UNLOCK(x)
597 #define LTC_MUTEX_DESTROY(x)
595598
596599 #endif
597600
145145 int blake2bmac_test(void);
146146 #endif /* LTC_BLAKE2BMAC */
147147
148 #ifdef LTC_EAX_MODE
149
150 #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
151 #error LTC_EAX_MODE requires LTC_OMAC and CTR
152 #endif
153
154 typedef struct {
155 unsigned char N[MAXBLOCKSIZE];
156 symmetric_CTR ctr;
157 omac_state headeromac, ctomac;
158 } eax_state;
159
160 int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
161 const unsigned char *nonce, unsigned long noncelen,
162 const unsigned char *header, unsigned long headerlen);
163
164 int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
165 int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
166 int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
167 int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
168
169 int eax_encrypt_authenticate_memory(int cipher,
170 const unsigned char *key, unsigned long keylen,
171 const unsigned char *nonce, unsigned long noncelen,
172 const unsigned char *header, unsigned long headerlen,
173 const unsigned char *pt, unsigned long ptlen,
174 unsigned char *ct,
175 unsigned char *tag, unsigned long *taglen);
176
177 int eax_decrypt_verify_memory(int cipher,
178 const unsigned char *key, unsigned long keylen,
179 const unsigned char *nonce, unsigned long noncelen,
180 const unsigned char *header, unsigned long headerlen,
181 const unsigned char *ct, unsigned long ctlen,
182 unsigned char *pt,
183 unsigned char *tag, unsigned long taglen,
184 int *stat);
185
186 int eax_test(void);
187 #endif /* EAX MODE */
188
189 #ifdef LTC_OCB_MODE
190 typedef struct {
191 unsigned char L[MAXBLOCKSIZE], /* L value */
192 Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
193 Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
194 Lr[MAXBLOCKSIZE], /* L * x^-1 */
195 R[MAXBLOCKSIZE], /* R value */
196 checksum[MAXBLOCKSIZE]; /* current checksum */
197
198 symmetric_key key; /* scheduled key for cipher */
199 unsigned long block_index; /* index # for current block */
200 int cipher, /* cipher idx */
201 block_len; /* length of block */
202 } ocb_state;
203
204 int ocb_init(ocb_state *ocb, int cipher,
205 const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
206
207 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
208 int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
209
210 int ocb_done_encrypt(ocb_state *ocb,
211 const unsigned char *pt, unsigned long ptlen,
212 unsigned char *ct,
213 unsigned char *tag, unsigned long *taglen);
214
215 int ocb_done_decrypt(ocb_state *ocb,
216 const unsigned char *ct, unsigned long ctlen,
217 unsigned char *pt,
218 const unsigned char *tag, unsigned long taglen, int *stat);
219
220 int ocb_encrypt_authenticate_memory(int cipher,
221 const unsigned char *key, unsigned long keylen,
222 const unsigned char *nonce,
223 const unsigned char *pt, unsigned long ptlen,
224 unsigned char *ct,
225 unsigned char *tag, unsigned long *taglen);
226
227 int ocb_decrypt_verify_memory(int cipher,
228 const unsigned char *key, unsigned long keylen,
229 const unsigned char *nonce,
230 const unsigned char *ct, unsigned long ctlen,
231 unsigned char *pt,
232 const unsigned char *tag, unsigned long taglen,
233 int *stat);
234
235 int ocb_test(void);
236
237 /* internal functions */
238 void ocb_shift_xor(ocb_state *ocb, unsigned char *Z);
239 int ocb_ntz(unsigned long x);
240 int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
241 unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode);
242
243 #endif /* LTC_OCB_MODE */
244
245 #ifdef LTC_OCB3_MODE
246 typedef struct {
247 unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */
248 Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */
249 L_dollar[MAXBLOCKSIZE], /* L_$ value */
250 L_star[MAXBLOCKSIZE], /* L_* value */
251 L_[32][MAXBLOCKSIZE], /* L_{i} values */
252 tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */
253 checksum[MAXBLOCKSIZE]; /* current checksum */
254
255 /* AAD related members */
256 unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */
257 aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
258 adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */
259 int adata_buffer_bytes; /* bytes in AAD buffer */
260 unsigned long ablock_index; /* index # for current adata (AAD) block */
261
262 symmetric_key key; /* scheduled key for cipher */
263 unsigned long block_index; /* index # for current data block */
264 int cipher, /* cipher idx */
265 tag_len, /* length of tag */
266 block_len; /* length of block */
267 } ocb3_state;
268
269 int ocb3_init(ocb3_state *ocb, int cipher,
270 const unsigned char *key, unsigned long keylen,
271 const unsigned char *nonce, unsigned long noncelen,
272 unsigned long taglen);
273
274 int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
275 int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
276 int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
277 int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
278 int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen);
279 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen);
280
281 int ocb3_encrypt_authenticate_memory(int cipher,
282 const unsigned char *key, unsigned long keylen,
283 const unsigned char *nonce, unsigned long noncelen,
284 const unsigned char *adata, unsigned long adatalen,
285 const unsigned char *pt, unsigned long ptlen,
286 unsigned char *ct,
287 unsigned char *tag, unsigned long *taglen);
288
289 int ocb3_decrypt_verify_memory(int cipher,
290 const unsigned char *key, unsigned long keylen,
291 const unsigned char *nonce, unsigned long noncelen,
292 const unsigned char *adata, unsigned long adatalen,
293 const unsigned char *ct, unsigned long ctlen,
294 unsigned char *pt,
295 const unsigned char *tag, unsigned long taglen,
296 int *stat);
297
298 int ocb3_test(void);
299
300 #ifdef LTC_SOURCE
301 /* internal helper functions */
302 int ocb3_int_ntz(unsigned long x);
303 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
304 #endif /* LTC_SOURCE */
305
306 #endif /* LTC_OCB3_MODE */
307
308 #ifdef LTC_CCM_MODE
309
310 #define CCM_ENCRYPT LTC_ENCRYPT
311 #define CCM_DECRYPT LTC_DECRYPT
312
313 typedef struct {
314 symmetric_key K;
315 int cipher, /* which cipher */
316 taglen, /* length of the tag */
317 x; /* index in PAD */
318
319 unsigned long L, /* L value */
320 ptlen, /* length that will be enc / dec */
321 current_ptlen, /* current processed length */
322 aadlen, /* length of the aad */
323 current_aadlen, /* length of the currently provided add */
324 noncelen; /* length of the nonce */
325
326 unsigned char PAD[16],
327 ctr[16],
328 CTRPAD[16],
329 CTRlen;
330 } ccm_state;
331
332 int ccm_init(ccm_state *ccm, int cipher,
333 const unsigned char *key, int keylen, int ptlen, int taglen, int aad_len);
334
335 int ccm_reset(ccm_state *ccm);
336
337 int ccm_add_nonce(ccm_state *ccm,
338 const unsigned char *nonce, unsigned long noncelen);
339
340 int ccm_add_aad(ccm_state *ccm,
341 const unsigned char *adata, unsigned long adatalen);
342
343 int ccm_process(ccm_state *ccm,
344 unsigned char *pt, unsigned long ptlen,
345 unsigned char *ct,
346 int direction);
347
348 int ccm_done(ccm_state *ccm,
349 unsigned char *tag, unsigned long *taglen);
350
351 int ccm_memory(int cipher,
352 const unsigned char *key, unsigned long keylen,
353 symmetric_key *uskey,
354 const unsigned char *nonce, unsigned long noncelen,
355 const unsigned char *header, unsigned long headerlen,
356 unsigned char *pt, unsigned long ptlen,
357 unsigned char *ct,
358 unsigned char *tag, unsigned long *taglen,
359 int direction);
360
361 int ccm_test(void);
362
363 #endif /* LTC_CCM_MODE */
364
365 #if defined(LRW_MODE) || defined(LTC_GCM_MODE)
366 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
367 #endif
368
369
370 /* table shared between GCM and LRW */
371 #if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
372 extern const unsigned char gcm_shift_table[];
373 #endif
374
375 #ifdef LTC_GCM_MODE
376
377 #define GCM_ENCRYPT LTC_ENCRYPT
378 #define GCM_DECRYPT LTC_DECRYPT
379
380 #define LTC_GCM_MODE_IV 0
381 #define LTC_GCM_MODE_AAD 1
382 #define LTC_GCM_MODE_TEXT 2
383
384 typedef struct {
385 symmetric_key K;
386 unsigned char H[16], /* multiplier */
387 X[16], /* accumulator */
388 Y[16], /* counter */
389 Y_0[16], /* initial counter */
390 buf[16]; /* buffer for stuff */
391
392 int cipher, /* which cipher */
393 ivmode, /* Which mode is the IV in? */
394 mode, /* mode the GCM code is in */
395 buflen; /* length of data in buf */
396
397 ulong64 totlen, /* 64-bit counter used for IV and AAD */
398 pttotlen; /* 64-bit counter for the PT */
399
400 #ifdef LTC_GCM_TABLES
401 unsigned char PC[16][256][16] /* 16 tables of 8x128 */
402 #ifdef LTC_GCM_TABLES_SSE2
403 __attribute__ ((aligned (16)))
404 #endif
405 ;
406 #endif
407 } gcm_state;
408
409 void gcm_mult_h(gcm_state *gcm, unsigned char *I);
410
411 int gcm_init(gcm_state *gcm, int cipher,
412 const unsigned char *key, int keylen);
413
414 int gcm_reset(gcm_state *gcm);
415
416 int gcm_add_iv(gcm_state *gcm,
417 const unsigned char *IV, unsigned long IVlen);
418
419 int gcm_add_aad(gcm_state *gcm,
420 const unsigned char *adata, unsigned long adatalen);
421
422 int gcm_process(gcm_state *gcm,
423 unsigned char *pt, unsigned long ptlen,
424 unsigned char *ct,
425 int direction);
426
427 int gcm_done(gcm_state *gcm,
428 unsigned char *tag, unsigned long *taglen);
429
430 int gcm_memory( int cipher,
431 const unsigned char *key, unsigned long keylen,
432 const unsigned char *IV, unsigned long IVlen,
433 const unsigned char *adata, unsigned long adatalen,
434 unsigned char *pt, unsigned long ptlen,
435 unsigned char *ct,
436 unsigned char *tag, unsigned long *taglen,
437 int direction);
438 int gcm_test(void);
439
440 #endif /* LTC_GCM_MODE */
441
442148 #ifdef LTC_PELICAN
443149
444150 typedef struct pelican_state
528234
529235 #endif
530236
237 /*
238 * ENC+AUTH modes
239 */
240
241 #ifdef LTC_EAX_MODE
242
243 #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
244 #error LTC_EAX_MODE requires LTC_OMAC and CTR
245 #endif
246
247 typedef struct {
248 unsigned char N[MAXBLOCKSIZE];
249 symmetric_CTR ctr;
250 omac_state headeromac, ctomac;
251 } eax_state;
252
253 int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
254 const unsigned char *nonce, unsigned long noncelen,
255 const unsigned char *header, unsigned long headerlen);
256
257 int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
258 int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
259 int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
260 int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
261
262 int eax_encrypt_authenticate_memory(int cipher,
263 const unsigned char *key, unsigned long keylen,
264 const unsigned char *nonce, unsigned long noncelen,
265 const unsigned char *header, unsigned long headerlen,
266 const unsigned char *pt, unsigned long ptlen,
267 unsigned char *ct,
268 unsigned char *tag, unsigned long *taglen);
269
270 int eax_decrypt_verify_memory(int cipher,
271 const unsigned char *key, unsigned long keylen,
272 const unsigned char *nonce, unsigned long noncelen,
273 const unsigned char *header, unsigned long headerlen,
274 const unsigned char *ct, unsigned long ctlen,
275 unsigned char *pt,
276 unsigned char *tag, unsigned long taglen,
277 int *stat);
278
279 int eax_test(void);
280 #endif /* EAX MODE */
281
282 #ifdef LTC_OCB_MODE
283 typedef struct {
284 unsigned char L[MAXBLOCKSIZE], /* L value */
285 Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
286 Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
287 Lr[MAXBLOCKSIZE], /* L * x^-1 */
288 R[MAXBLOCKSIZE], /* R value */
289 checksum[MAXBLOCKSIZE]; /* current checksum */
290
291 symmetric_key key; /* scheduled key for cipher */
292 unsigned long block_index; /* index # for current block */
293 int cipher, /* cipher idx */
294 block_len; /* length of block */
295 } ocb_state;
296
297 int ocb_init(ocb_state *ocb, int cipher,
298 const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
299
300 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
301 int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
302
303 int ocb_done_encrypt(ocb_state *ocb,
304 const unsigned char *pt, unsigned long ptlen,
305 unsigned char *ct,
306 unsigned char *tag, unsigned long *taglen);
307
308 int ocb_done_decrypt(ocb_state *ocb,
309 const unsigned char *ct, unsigned long ctlen,
310 unsigned char *pt,
311 const unsigned char *tag, unsigned long taglen, int *stat);
312
313 int ocb_encrypt_authenticate_memory(int cipher,
314 const unsigned char *key, unsigned long keylen,
315 const unsigned char *nonce,
316 const unsigned char *pt, unsigned long ptlen,
317 unsigned char *ct,
318 unsigned char *tag, unsigned long *taglen);
319
320 int ocb_decrypt_verify_memory(int cipher,
321 const unsigned char *key, unsigned long keylen,
322 const unsigned char *nonce,
323 const unsigned char *ct, unsigned long ctlen,
324 unsigned char *pt,
325 const unsigned char *tag, unsigned long taglen,
326 int *stat);
327
328 int ocb_test(void);
329
330 /* internal functions */
331 void ocb_shift_xor(ocb_state *ocb, unsigned char *Z);
332 int ocb_ntz(unsigned long x);
333 int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
334 unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode);
335
336 #endif /* LTC_OCB_MODE */
337
338 #ifdef LTC_OCB3_MODE
339 typedef struct {
340 unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */
341 Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */
342 L_dollar[MAXBLOCKSIZE], /* L_$ value */
343 L_star[MAXBLOCKSIZE], /* L_* value */
344 L_[32][MAXBLOCKSIZE], /* L_{i} values */
345 tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */
346 checksum[MAXBLOCKSIZE]; /* current checksum */
347
348 /* AAD related members */
349 unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */
350 aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
351 adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */
352 int adata_buffer_bytes; /* bytes in AAD buffer */
353 unsigned long ablock_index; /* index # for current adata (AAD) block */
354
355 symmetric_key key; /* scheduled key for cipher */
356 unsigned long block_index; /* index # for current data block */
357 int cipher, /* cipher idx */
358 tag_len, /* length of tag */
359 block_len; /* length of block */
360 } ocb3_state;
361
362 int ocb3_init(ocb3_state *ocb, int cipher,
363 const unsigned char *key, unsigned long keylen,
364 const unsigned char *nonce, unsigned long noncelen,
365 unsigned long taglen);
366
367 int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
368 int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
369 int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
370 int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
371 int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen);
372 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen);
373
374 int ocb3_encrypt_authenticate_memory(int cipher,
375 const unsigned char *key, unsigned long keylen,
376 const unsigned char *nonce, unsigned long noncelen,
377 const unsigned char *adata, unsigned long adatalen,
378 const unsigned char *pt, unsigned long ptlen,
379 unsigned char *ct,
380 unsigned char *tag, unsigned long *taglen);
381
382 int ocb3_decrypt_verify_memory(int cipher,
383 const unsigned char *key, unsigned long keylen,
384 const unsigned char *nonce, unsigned long noncelen,
385 const unsigned char *adata, unsigned long adatalen,
386 const unsigned char *ct, unsigned long ctlen,
387 unsigned char *pt,
388 const unsigned char *tag, unsigned long taglen,
389 int *stat);
390
391 int ocb3_test(void);
392
393 #ifdef LTC_SOURCE
394 /* internal helper functions */
395 int ocb3_int_ntz(unsigned long x);
396 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
397 #endif /* LTC_SOURCE */
398
399 #endif /* LTC_OCB3_MODE */
400
401 #ifdef LTC_CCM_MODE
402
403 #define CCM_ENCRYPT LTC_ENCRYPT
404 #define CCM_DECRYPT LTC_DECRYPT
405
406 typedef struct {
407 symmetric_key K;
408 int cipher, /* which cipher */
409 taglen, /* length of the tag */
410 x; /* index in PAD */
411
412 unsigned long L, /* L value */
413 ptlen, /* length that will be enc / dec */
414 current_ptlen, /* current processed length */
415 aadlen, /* length of the aad */
416 current_aadlen, /* length of the currently provided add */
417 noncelen; /* length of the nonce */
418
419 unsigned char PAD[16],
420 ctr[16],
421 CTRPAD[16],
422 CTRlen;
423 } ccm_state;
424
425 int ccm_init(ccm_state *ccm, int cipher,
426 const unsigned char *key, int keylen, int ptlen, int taglen, int aad_len);
427
428 int ccm_reset(ccm_state *ccm);
429
430 int ccm_add_nonce(ccm_state *ccm,
431 const unsigned char *nonce, unsigned long noncelen);
432
433 int ccm_add_aad(ccm_state *ccm,
434 const unsigned char *adata, unsigned long adatalen);
435
436 int ccm_process(ccm_state *ccm,
437 unsigned char *pt, unsigned long ptlen,
438 unsigned char *ct,
439 int direction);
440
441 int ccm_done(ccm_state *ccm,
442 unsigned char *tag, unsigned long *taglen);
443
444 int ccm_memory(int cipher,
445 const unsigned char *key, unsigned long keylen,
446 symmetric_key *uskey,
447 const unsigned char *nonce, unsigned long noncelen,
448 const unsigned char *header, unsigned long headerlen,
449 unsigned char *pt, unsigned long ptlen,
450 unsigned char *ct,
451 unsigned char *tag, unsigned long *taglen,
452 int direction);
453
454 int ccm_test(void);
455
456 #endif /* LTC_CCM_MODE */
457
458 #if defined(LRW_MODE) || defined(LTC_GCM_MODE)
459 void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
460 #endif
461
462
463 /* table shared between GCM and LRW */
464 #if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
465 extern const unsigned char gcm_shift_table[];
466 #endif
467
468 #ifdef LTC_GCM_MODE
469
470 #define GCM_ENCRYPT LTC_ENCRYPT
471 #define GCM_DECRYPT LTC_DECRYPT
472
473 #define LTC_GCM_MODE_IV 0
474 #define LTC_GCM_MODE_AAD 1
475 #define LTC_GCM_MODE_TEXT 2
476
477 typedef struct {
478 symmetric_key K;
479 unsigned char H[16], /* multiplier */
480 X[16], /* accumulator */
481 Y[16], /* counter */
482 Y_0[16], /* initial counter */
483 buf[16]; /* buffer for stuff */
484
485 int cipher, /* which cipher */
486 ivmode, /* Which mode is the IV in? */
487 mode, /* mode the GCM code is in */
488 buflen; /* length of data in buf */
489
490 ulong64 totlen, /* 64-bit counter used for IV and AAD */
491 pttotlen; /* 64-bit counter for the PT */
492
493 #ifdef LTC_GCM_TABLES
494 unsigned char PC[16][256][16] /* 16 tables of 8x128 */
495 #ifdef LTC_GCM_TABLES_SSE2
496 __attribute__ ((aligned (16)))
497 #endif
498 ;
499 #endif
500 } gcm_state;
501
502 void gcm_mult_h(gcm_state *gcm, unsigned char *I);
503
504 int gcm_init(gcm_state *gcm, int cipher,
505 const unsigned char *key, int keylen);
506
507 int gcm_reset(gcm_state *gcm);
508
509 int gcm_add_iv(gcm_state *gcm,
510 const unsigned char *IV, unsigned long IVlen);
511
512 int gcm_add_aad(gcm_state *gcm,
513 const unsigned char *adata, unsigned long adatalen);
514
515 int gcm_process(gcm_state *gcm,
516 unsigned char *pt, unsigned long ptlen,
517 unsigned char *ct,
518 int direction);
519
520 int gcm_done(gcm_state *gcm,
521 unsigned char *tag, unsigned long *taglen);
522
523 int gcm_memory( int cipher,
524 const unsigned char *key, unsigned long keylen,
525 const unsigned char *IV, unsigned long IVlen,
526 const unsigned char *adata, unsigned long adatalen,
527 unsigned char *pt, unsigned long ptlen,
528 unsigned char *ct,
529 unsigned char *tag, unsigned long *taglen,
530 int direction);
531 int gcm_test(void);
532
533 #endif /* LTC_GCM_MODE */
534
531535 #ifdef LTC_CHACHA20POLY1305_MODE
532536
533537 typedef struct {
7171 /* ---- MEM routines ---- */
7272 int mem_neq(const void *a, const void *b, size_t len);
7373 void zeromem(volatile void *dst, size_t len);
74 #ifdef LTC_SOURCE
75 void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz);
76 #endif
7477 void burn_stack(unsigned long len);
7578
7679 const char *error_to_string(int err);
7272 fprintf(stderr, "Testvector #%i of %s failed:\n", which, what);
7373 _print_hex("SHOULD", should, should_len);
7474 _print_hex("IS ", is, is_len);
75 #if LTC_TEST_DBG > 1
76 } else {
77 fprintf(stderr, "Testvector #%i of %s passed!\n", which, what);
78 #endif
7579 }
7680 #else
7781 LTC_UNUSED_PARAM(which);
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10 /**
11 @file copy_or_zeromem.c
12 Either copy or zero a block of memory in constant time, Steffen Jaeckel
13 */
14
15 /**
16 Either copy or zero a block of memory in constant time
17 @param src The source where to read from
18 @param dest The destination where to write to
19 @param len The length of the area to process (octets)
20 @param coz Copy (on 0) Or Zero (> 0)
21 */
22 void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz)
23 {
24 unsigned long y;
25 #ifdef LTC_FAST
26 unsigned long z;
27 LTC_FAST_TYPE fastMask = ~0; /* initialize fastMask at all ones */
28 #endif
29 unsigned char mask = 0xff; /* initialize mask at all ones */
30
31 LTC_ARGCHK(src != NULL);
32 LTC_ARGCHK(dest != NULL);
33
34 if (coz != 0) coz = 1;
35 y = 0;
36 mask *= 1 - coz; /* mask = ( coz ? 0 : 0xff ) */
37 #ifdef LTC_FAST
38 fastMask *= 1 - coz;
39 if (len & ~15) {
40 for (; y < (len & ~15); y += 16) {
41 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
42 *(LTC_FAST_TYPE_PTR_CAST(&dest[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&src[y+z])) & fastMask;
43 }
44 }
45 }
46 #endif
47 for (; y < len; y++) {
48 dest[y] = src[y] & mask;
49 }
50 #ifdef LTC_CLEAN_STACK
51 #ifdef LTC_FAST
52 fastMask = 0;
53 #endif
54 mask = 0;
55 #endif
56 }
57
58 /* ref: $Format:%D$ */
59 /* git commit: $Format:%H$ */
60 /* commit time: $Format:%ai$ */
137137 #if defined(LTC_SOSEMANUK)
138138 " Sosemanuk\n"
139139 #endif
140 #if defined(LTC_RABBIT)
141 " Rabbit\n"
142 #endif
140143 #if defined(LTC_RC4_STREAM)
141144 " RC4\n"
142145 #endif
181181 #endif
182182 #ifdef LTC_SOSEMANUK
183183 _SZ_STRINGIFY_T(sosemanuk_state),
184 #endif
185 #ifdef LTC_RABBIT
186 _SZ_STRINGIFY_T(rabbit_state),
184187 #endif
185188 #ifdef LTC_RC4_STREAM
186189 _SZ_STRINGIFY_T(rc4_state),
4646
4747 /* store header (include bit padding count in length) */
4848 x = 0;
49 y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
49 y = ((inlen + 7) >> 3) + 1;
5050
5151 out[x++] = 0x03;
5252 if (y < 128) {
4848
4949 /* store header (include bit padding count in length) */
5050 x = 0;
51 y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
51 y = ((inlen + 7) >> 3) + 1;
5252
5353 out[x++] = 0x03;
5454 if (y < 128) {
138138 prng->ready = 0;
139139 err = chacha_done(&prng->chacha.s);
140140 LTC_MUTEX_UNLOCK(&prng->lock);
141 LTC_MUTEX_DESTROY(&prng->lock);
141142 return err;
142143 }
143144
317317 zeromem(tmp, sizeof(tmp));
318318 #endif
319319 LTC_MUTEX_UNLOCK(&prng->lock);
320 LTC_MUTEX_DESTROY(&prng->lock);
320321 return err;
321322 }
322323
141141 prng->ready = 0;
142142 err = rc4_stream_done(&prng->rc4.s);
143143 LTC_MUTEX_UNLOCK(&prng->lock);
144 LTC_MUTEX_DESTROY(&prng->lock);
144145 return err;
145146 }
146147
140140 prng->ready = 0;
141141 err = sober128_stream_done(&prng->sober128.s);
142142 LTC_MUTEX_UNLOCK(&prng->lock);
143 LTC_MUTEX_DESTROY(&prng->lock);
143144 return err;
144145 }
145146
261261 err = ctr_done(&prng->yarrow.ctr);
262262
263263 LTC_MUTEX_UNLOCK(&prng->lock);
264 LTC_MUTEX_DESTROY(&prng->lock);
264265 return err;
265266 }
266267
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /******************************************************************************
10 * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
11 * and should run on any conforming C implementation (C90 or later).
12 *
13 * This implementation supports any key length up to 128 bits (16 bytes) and
14 * works in increments of 8-bit bytes. Keys must be submitted as whole bytes
15 * and shorter keys will be right-null-padded to 16 bytes. Likewise, an iv
16 * may be any length up to 8 bytes and will be padded out to 8 bytes.
17 *
18 * The eSTREAM submission was rather picky about the calling sequence of
19 * ECRYPT_process_blocks() and ECRYPT_process_bytes(). That version allowed
20 * calling ECRYPT_process_blocks() multiple times for a multiple of whole
21 * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
22 * were supported correctly. This implementation handles the keystream
23 * differently and rabbit_crypt() may be called as many times as desired,
24 * crypting any number of bytes each time.
25 *
26 * http://www.ecrypt.eu.org/stream/e2-rabbit.html
27 *
28 * NB: One of the test vectors distributed by the eSTREAM site in the file
29 * "rabbit_p3source.zip" is in error. Referring to "test-vectors.txt"
30 * in that ZIP file, the 3rd line in "out1" should be
31 * "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
32 *
33 * Here is the original legal notice accompanying the Rabbit submission
34 * to the EU eSTREAM competition.
35 *---------------------------------------------------------------------------
36 * Copyright (C) Cryptico A/S. All rights reserved.
37 *
38 * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
39 *
40 * This software is developed by Cryptico A/S and/or its suppliers.
41 * All title and intellectual property rights in and to the software,
42 * including but not limited to patent rights and copyrights, are owned
43 * by Cryptico A/S and/or its suppliers.
44 *
45 * The software may be used solely for non-commercial purposes
46 * without the prior written consent of Cryptico A/S. For further
47 * information on licensing terms and conditions please contact
48 * Cryptico A/S at info@cryptico.com
49 *
50 * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
51 * are either trademarks or registered trademarks of Cryptico A/S.
52 *
53 * Cryptico A/S shall not in any way be liable for any use of this
54 * software. The software is provided "as is" without any express or
55 * implied warranty.
56 *---------------------------------------------------------------------------
57 * On October 6, 2008, Rabbit was "released into the public domain and
58 * may be used freely for any purpose."
59 * http://www.ecrypt.eu.org/stream/rabbitpf.html
60 * https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
61 ******************************************************************************/
62
63
64 #include "tomcrypt.h"
65
66 #ifdef LTC_RABBIT
67
68 /* local/private prototypes (NB: rabbit_ctx and rabbit_state are different) */
69 static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x);
70 static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance);
71 static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out);
72
73 /* -------------------------------------------------------------------------- */
74
75 /* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
76 /* the upper 32 bits XOR the lower 32 bits */
77 static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x)
78 {
79 ulong32 a, b, h, l;
80
81 /* Construct high and low argument for squaring */
82 a = x & 0xFFFF;
83 b = x >> 16;
84
85 /* Calculate high and low result of squaring */
86 h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
87 l = x * x;
88
89 /* Return high XOR low */
90 return (ulong32)(h^l);
91 }
92
93 /* -------------------------------------------------------------------------- */
94
95 /* Calculate the next internal state */
96 static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance)
97 {
98 ulong32 g[8], c_old[8], i;
99
100 /* Save old counter values */
101 for (i=0; i<8; i++)
102 c_old[i] = p_instance->c[i];
103
104 /* Calculate new counter values */
105 p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
106 p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
107 p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
108 p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
109 p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
110 p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
111 p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
112 p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
113 p_instance->carry = (p_instance->c[7] < c_old[7]);
114
115 /* Calculate the g-values */
116 for (i=0;i<8;i++)
117 g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
118
119 /* Calculate new state values */
120 p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
121 p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
122 p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
123 p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
124 p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
125 p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
126 p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
127 p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
128 }
129
130 /* ------------------------------------------------------------------------- */
131
132 static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
133 {
134 ulong32 *ptr;
135
136 /* Iterate the work context once */
137 _rabbit_next_state(&(st->work_ctx));
138
139 /* Generate 16 bytes of pseudo-random data */
140 ptr = (ulong32*)&(st->work_ctx.x);
141 STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
142 STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
143 STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
144 STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12);
145 }
146
147 /* -------------------------------------------------------------------------- */
148
149 /* Key setup */
150 int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen)
151 {
152 ulong32 k0, k1, k2, k3, i;
153 unsigned char tmpkey[16] = {0};
154
155 LTC_ARGCHK(st != NULL);
156 LTC_ARGCHK(key != NULL);
157 LTC_ARGCHK(keylen <= 16);
158
159 /* init state */
160 XMEMSET(st, 0, sizeof(rabbit_state));
161
162 /* pad key in tmpkey */
163 XMEMCPY(tmpkey, key, keylen);
164
165 /* Generate four subkeys */
166 LOAD32L(k0, tmpkey+ 0);
167 LOAD32L(k1, tmpkey+ 4);
168 LOAD32L(k2, tmpkey+ 8);
169 LOAD32L(k3, tmpkey+12);
170
171 #ifdef LTC_CLEAN_STACK
172 /* done with tmpkey, wipe it */
173 zeromem(tmpkey, sizeof(tmpkey));
174 #endif
175
176 /* Generate initial state variables */
177 st->master_ctx.x[0] = k0;
178 st->master_ctx.x[2] = k1;
179 st->master_ctx.x[4] = k2;
180 st->master_ctx.x[6] = k3;
181 st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
182 st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
183 st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
184 st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);
185
186 /* Generate initial counter values */
187 st->master_ctx.c[0] = ROLc(k2, 16);
188 st->master_ctx.c[2] = ROLc(k3, 16);
189 st->master_ctx.c[4] = ROLc(k0, 16);
190 st->master_ctx.c[6] = ROLc(k1, 16);
191 st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
192 st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
193 st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
194 st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
195
196 /* Clear carry bit */
197 st->master_ctx.carry = 0;
198
199 /* Iterate the master context four times */
200 for (i=0; i<4; i++)
201 _rabbit_next_state(&(st->master_ctx));
202
203 /* Modify the counters */
204 for (i=0; i<8; i++)
205 st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
206
207 /* Copy master instance to work instance */
208 for (i=0; i<8; i++) {
209 st->work_ctx.x[i] = st->master_ctx.x[i];
210 st->work_ctx.c[i] = st->master_ctx.c[i];
211 }
212 st->work_ctx.carry = st->master_ctx.carry;
213 /* ...and prepare block for crypt() */
214 XMEMSET(&(st->block), 0, sizeof(st->block));
215 st->unused = 0;
216
217 return CRYPT_OK;
218 }
219
220 /* -------------------------------------------------------------------------- */
221
222 /* IV setup */
223 int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
224 {
225 ulong32 i0, i1, i2, i3, i;
226 unsigned char tmpiv[8] = {0};
227
228 LTC_ARGCHK(st != NULL);
229 LTC_ARGCHK(iv != NULL || ivlen == 0);
230 LTC_ARGCHK(ivlen <= 8);
231
232 /* pad iv in tmpiv */
233 if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);
234
235 /* Generate four subvectors */
236 LOAD32L(i0, tmpiv+0);
237 LOAD32L(i2, tmpiv+4);
238 i1 = (i0>>16) | (i2&0xFFFF0000);
239 i3 = (i2<<16) | (i0&0x0000FFFF);
240
241 /* Modify counter values */
242 st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
243 st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
244 st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
245 st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
246 st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
247 st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
248 st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
249 st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;
250
251 /* Copy state variables */
252 for (i=0; i<8; i++)
253 st->work_ctx.x[i] = st->master_ctx.x[i];
254 st->work_ctx.carry = st->master_ctx.carry;
255
256 /* Iterate the work context four times */
257 for (i=0; i<4; i++)
258 _rabbit_next_state(&(st->work_ctx));
259
260 /* reset keystream buffer and unused count */
261 XMEMSET(&(st->block), 0, sizeof(st->block));
262 st->unused = 0;
263
264 return CRYPT_OK;
265 }
266
267 /* ------------------------------------------------------------------------- */
268
269 /* Crypt a chunk of any size (encrypt/decrypt) */
270 int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
271 {
272 unsigned char buf[16];
273 unsigned long i, j;
274
275 if (inlen == 0) return CRYPT_OK; /* nothing to do */
276
277 LTC_ARGCHK(st != NULL);
278 LTC_ARGCHK(in != NULL);
279 LTC_ARGCHK(out != NULL);
280
281 if (st->unused > 0) {
282 j = MIN(st->unused, inlen);
283 for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
284 inlen -= j;
285 if (inlen == 0) return CRYPT_OK;
286 out += j;
287 in += j;
288 }
289 for (;;) {
290 /* gen a block for buf */
291 _rabbit_gen_1_block(st, buf);
292 if (inlen <= 16) {
293 /* XOR and send to out */
294 for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
295 st->unused = 16 - inlen;
296 /* copy remainder to block */
297 for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
298 return CRYPT_OK;
299 } else {
300 /* XOR entire buf and send to out */
301 for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
302 inlen -= 16;
303 out += 16;
304 in += 16;
305 }
306 }
307 }
308
309 /* ------------------------------------------------------------------------- */
310
311 int rabbit_keystream(rabbit_state *st, unsigned char *out, unsigned long outlen)
312 {
313 if (outlen == 0) return CRYPT_OK; /* nothing to do */
314
315 LTC_ARGCHK(out != NULL);
316
317 XMEMSET(out, 0, outlen);
318 return rabbit_crypt(st, out, outlen, out);
319 }
320
321 /* -------------------------------------------------------------------------- */
322
323 int rabbit_done(rabbit_state *st)
324 {
325 LTC_ARGCHK(st != NULL);
326
327 zeromem(st, sizeof(rabbit_state));
328 return CRYPT_OK;
329 }
330
331 /* -------------------------------------------------------------------------- */
332
333 int rabbit_test(void)
334 {
335 #ifndef LTC_TEST
336 return CRYPT_NOP;
337 #else
338 rabbit_state st;
339 int err;
340 unsigned char out[1000] = { 0 };
341 {
342 /* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
343 http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
344 */
345
346 /* --- Test 1 (generate whole blocks) --------------------------------- */
347
348 {
349 unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
350 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
351 unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
352 char pt[64] = { 0 };
353 unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
354 0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
355 0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
356 0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
357 0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
358 0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
359 0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
360 0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
361 unsigned long ptlen = sizeof(pt);
362
363 /* crypt 64 nulls */
364 if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
365 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
366 if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
367 if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
368 }
369
370 /* --- Test 2 (generate unusual number of bytes each time) ------------ */
371
372 {
373 unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
374 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
375 unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
376 char pt[39] = { 0 };
377 unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
378 0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
379 0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
380 0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
381 0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D };
382 unsigned long ptlen = sizeof(pt);
383
384 /* crypt piece by piece (hit at least one 16-byte boundary) */
385 if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
386 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
387 if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
388 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 11, out + 5)) != CRYPT_OK) return err;
389 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
390 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30, 2, out + 30)) != CRYPT_OK) return err;
391 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32, 7, out + 32)) != CRYPT_OK) return err;
392 if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
393 }
394
395 /* --- Test 3 (use non-null data) ------------------------------------- */
396
397 {
398 unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
399 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
400 unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
401 char pt[] = "Kilroy was here, there, and everywhere!";
402 unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8, 0xf9, 0xd6, 0xd6, 0xbd,
403 0xae, 0x59, 0x65, 0xf2, 0x75, 0x58, 0x1a, 0x54,
404 0xea, 0xec, 0x34, 0x9d, 0x8f, 0xb4, 0x6b, 0x60,
405 0x79, 0x1b, 0xea, 0x16, 0xcb, 0xef, 0x46, 0x87,
406 0x60, 0xa6, 0x55, 0x14, 0xff, 0xca, 0xac };
407 unsigned long ptlen = strlen(pt);
408 unsigned char out2[1000] = { 0 };
409 unsigned char nulls[1000] = { 0 };
410
411 /* crypt piece by piece */
412 if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
413 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
414 if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
415 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 29, out + 5)) != CRYPT_OK) return err;
416 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34, 5, out + 34)) != CRYPT_OK) return err;
417 if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
418 /* use 'out' (ciphertext) in the next decryption test */
419
420 /* --- Test 4 (decrypt ciphertext) ------------------------------------ */
421
422 /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
423 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
424 if ((err = rabbit_crypt(&st, out, ptlen, out2)) != CRYPT_OK) return err;
425 if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV4", 1)) return CRYPT_FAIL_TESTVECTOR;
426
427 /* --- Test 5 (wipe state, incl key) ---------------------------------- */
428
429 if ((err = rabbit_done(&st)) != CRYPT_OK) return err;
430 if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV5", 1)) return CRYPT_FAIL_TESTVECTOR;
431
432 }
433
434 return CRYPT_OK;
435 }
436 #endif
437 }
438
439 /* -------------------------------------------------------------------------- */
440
441 #endif
442
443 /* ref: $Format:%D$ */
444 /* git commit: $Format:%H$ */
445 /* commit time: $Format:%ai$ */
193193 /* ======================================================================== */
194194
195195 /*
196 * Key schedule: initialize the key context structure with the provided
197 * secret key. The secret key is an array of 1 to 32 bytes.
196 * Initialize Sosemanuk's state by providing a key. The key is an array of
197 * 1 to 32 bytes.
198198 * @param ss The Sosemanuk state
199199 * @param key Key
200 * @param keylen Length of key
200 * @param keylen Length of key in bytes
201201 * @return CRYPT_OK on success
202202 */
203203 int sosemanuk_setup(sosemanuk_state *ss, unsigned char *key, unsigned long keylen)
330330
331331
332332 /*
333 * Cipher initialization: the cipher internal state is initialized, using
334 * the provided key context and IV. The IV length is up to 16 bytes. If
335 * "ivlen" is 0 (no IV), then the "iv" parameter can be NULL.
333 * Initialization continues by setting the IV. The IV length is up to 16 bytes.
334 * If "ivlen" is 0 (no IV), then the "iv" parameter can be NULL. If multiple
335 * encryptions/decryptions are to be performed with the same key and
336 * sosemanuk_done() has not been called, only sosemanuk_setiv() need be called
337 * to set the state.
336338 * @param ss The Sosemanuk state
337339 * @param iv Initialization vector
338 * @param ivlen Length of iv
340 * @param ivlen Length of iv in bytes
339341 * @return CRYPT_OK on success
340342 */
341343 int sosemanuk_setiv(sosemanuk_state *ss, unsigned char *iv, unsigned long ivlen)
379381 unsigned char ivtmp[16] = {0};
380382
381383 LTC_ARGCHK(ss != NULL);
382 LTC_ARGCHK(ivlen >= 0 && ivlen <= 16);
384 LTC_ARGCHK(ivlen <= 16);
383385 LTC_ARGCHK(iv != NULL || ivlen == 0);
384386
385387 if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen);
447449 /*
448450 * Multiplication by alpha: alpha * x = T32(x << 8) ^ mul_a[x >> 24]
449451 */
450 static ulong32 mul_a[] = {
452 static const ulong32 mul_a[] = {
451453 0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835,
452454 0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679,
453455 0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD,
517519 /*
518520 * Multiplication by 1/alpha: 1/alpha * x = (x >> 8) ^ mul_ia[x & 0xFF]
519521 */
520 static ulong32 mul_ia[] = {
522 static const ulong32 mul_ia[] = {
521523 0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE,
522524 0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998,
523525 0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32,
742744 * reference distinct buffers (no partial overlap is allowed).
743745 * @param ss The Sosemanuk state
744746 * @param in Data in
747 * @param inlen Length of data in bytes
745748 * @param out Data out
746 * @param datalen Length of data
747749 * @return CRYPT_OK on success
748750 */
749751 int sosemanuk_crypt(sosemanuk_state *ss,
750 const unsigned char *in, unsigned long datalen, unsigned char *out)
752 const unsigned char *in, unsigned long inlen, unsigned char *out)
751753 {
752754 LTC_ARGCHK(ss != NULL);
753755 LTC_ARGCHK(in != NULL);
756758 if (ss->ptr < (sizeof(ss->buf))) {
757759 unsigned long rlen = (sizeof(ss->buf)) - ss->ptr;
758760
759 if (rlen > datalen)
760 rlen = datalen;
761 if (rlen > inlen)
762 rlen = inlen;
761763 _xorbuf(ss->buf + ss->ptr, in, out, rlen);
762764 in += rlen;
763765 out += rlen;
764 datalen -= rlen;
766 inlen -= rlen;
765767 ss->ptr += rlen;
766768 }
767 while (datalen > 0) {
769 while (inlen > 0) {
768770 _sosemanuk_internal(ss);
769 if (datalen >= sizeof(ss->buf)) {
771 if (inlen >= sizeof(ss->buf)) {
770772 _xorbuf(ss->buf, in, out, sizeof(ss->buf));
771773 in += sizeof(ss->buf);
772774 out += sizeof(ss->buf);
773 datalen -= sizeof(ss->buf);
775 inlen -= sizeof(ss->buf);
774776 } else {
775 _xorbuf(ss->buf, in, out, datalen);
776 ss->ptr = datalen;
777 datalen = 0;
777 _xorbuf(ss->buf, in, out, inlen);
778 ss->ptr = inlen;
779 inlen = 0;
778780 }
779781 }
780782 return CRYPT_OK;
781783 }
782784
783785
786
784787 /*
785788 * Cipher operation, as a PRNG: the provided output buffer is filled with
786789 * pseudo-random bytes as output from the stream cipher.
787790 * @param ss The Sosemanuk state
788791 * @param out Data out
789 * @param outlen Length of output
792 * @param outlen Length of output in bytes
790793 * @return CRYPT_OK on success
791794 */
792795 int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen)
800803
801804 /*
802805 * Terminate and clear Sosemanuk key context
803 * @param kc The Sosemanuk key context
806 * @param ss The Sosemanuk state
804807 * @return CRYPT_OK on success
805808 */
806809 int sosemanuk_done(sosemanuk_state *ss)
1515 */
1616
1717 static const struct {
18 int code;
19 const char *msg;
18 int code;
19 const char *msg;
2020 } msgs[] = {
21 { MP_OKAY, "Successful" },
22 { MP_MEM, "Out of heap" },
23 { MP_VAL, "Value out of range" }
21 { MP_OKAY, "Successful" },
22 { MP_MEM, "Out of heap" },
23 { MP_VAL, "Value out of range" }
2424 };
2525
2626 /* return a char * string for a given code */
2727 const char *mp_error_to_string(int code)
2828 {
29 int x;
29 size_t x;
3030
3131 /* scan the lookup table for the given message */
32 for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
33 if (msgs[x].code == code) {
34 return msgs[x].msg;
35 }
32 for (x = 0; x < (sizeof(msgs) / sizeof(msgs[0])); x++) {
33 if (msgs[x].code == code) {
34 return msgs[x].msg;
35 }
3636 }
3737
3838 /* generic reply for invalid code */
4141
4242 #endif
4343
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
44 /* ref: $Format:%D$ */
45 /* git commit: $Format:%H$ */
46 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* computes the modular inverse via binary extended euclidean algorithm,
18 * that is c = 1/a mod b
17 /* computes the modular inverse via binary extended euclidean algorithm,
18 * that is c = 1/a mod b
1919 *
20 * Based on slow invmod except this is optimized for the case where b is
20 * Based on slow invmod except this is optimized for the case where b is
2121 * odd as per HAC Note 14.64 on pp. 610
2222 */
23 int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
23 int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
2424 {
25 mp_int x, y, u, v, B, D;
26 int res, neg;
25 mp_int x, y, u, v, B, D;
26 int res, neg;
2727
28 /* 2. [modified] b must be odd */
29 if (mp_iseven (b) == MP_YES) {
30 return MP_VAL;
31 }
28 /* 2. [modified] b must be odd */
29 if (mp_iseven(b) == MP_YES) {
30 return MP_VAL;
31 }
3232
33 /* init all our temps */
34 if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
35 return res;
36 }
33 /* init all our temps */
34 if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
35 return res;
36 }
3737
38 /* x == modulus, y == value to invert */
39 if ((res = mp_copy (b, &x)) != MP_OKAY) {
40 goto LBL_ERR;
41 }
38 /* x == modulus, y == value to invert */
39 if ((res = mp_copy(b, &x)) != MP_OKAY) {
40 goto LBL_ERR;
41 }
4242
43 /* we need y = |a| */
44 if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
45 goto LBL_ERR;
46 }
43 /* we need y = |a| */
44 if ((res = mp_mod(a, b, &y)) != MP_OKAY) {
45 goto LBL_ERR;
46 }
4747
48 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
49 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 mp_set (&D, 1);
48 /* if one of x,y is zero return an error! */
49 if ((mp_iszero(&x) == MP_YES) || (mp_iszero(&y) == MP_YES)) {
50 res = MP_VAL;
51 goto LBL_ERR;
52 }
53
54 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
55 if ((res = mp_copy(&x, &u)) != MP_OKAY) {
56 goto LBL_ERR;
57 }
58 if ((res = mp_copy(&y, &v)) != MP_OKAY) {
59 goto LBL_ERR;
60 }
61 mp_set(&D, 1uL);
5662
5763 top:
58 /* 4. while u is even do */
59 while (mp_iseven (&u) == MP_YES) {
60 /* 4.1 u = u/2 */
61 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
64 /* 4. while u is even do */
65 while (mp_iseven(&u) == MP_YES) {
66 /* 4.1 u = u/2 */
67 if ((res = mp_div_2(&u, &u)) != MP_OKAY) {
68 goto LBL_ERR;
69 }
70 /* 4.2 if B is odd then */
71 if (mp_isodd(&B) == MP_YES) {
72 if ((res = mp_sub(&B, &x, &B)) != MP_OKAY) {
73 goto LBL_ERR;
74 }
75 }
76 /* B = B/2 */
77 if ((res = mp_div_2(&B, &B)) != MP_OKAY) {
78 goto LBL_ERR;
79 }
80 }
81
82 /* 5. while v is even do */
83 while (mp_iseven(&v) == MP_YES) {
84 /* 5.1 v = v/2 */
85 if ((res = mp_div_2(&v, &v)) != MP_OKAY) {
86 goto LBL_ERR;
87 }
88 /* 5.2 if D is odd then */
89 if (mp_isodd(&D) == MP_YES) {
90 /* D = (D-x)/2 */
91 if ((res = mp_sub(&D, &x, &D)) != MP_OKAY) {
92 goto LBL_ERR;
93 }
94 }
95 /* D = D/2 */
96 if ((res = mp_div_2(&D, &D)) != MP_OKAY) {
97 goto LBL_ERR;
98 }
99 }
100
101 /* 6. if u >= v then */
102 if (mp_cmp(&u, &v) != MP_LT) {
103 /* u = u - v, B = B - D */
104 if ((res = mp_sub(&u, &v, &u)) != MP_OKAY) {
105 goto LBL_ERR;
106 }
107
108 if ((res = mp_sub(&B, &D, &B)) != MP_OKAY) {
109 goto LBL_ERR;
110 }
111 } else {
112 /* v - v - u, D = D - B */
113 if ((res = mp_sub(&v, &u, &v)) != MP_OKAY) {
114 goto LBL_ERR;
115 }
116
117 if ((res = mp_sub(&D, &B, &D)) != MP_OKAY) {
118 goto LBL_ERR;
119 }
120 }
121
122 /* if not zero goto step 4 */
123 if (mp_iszero(&u) == MP_NO) {
124 goto top;
125 }
126
127 /* now a = C, b = D, gcd == g*v */
128
129 /* if v != 1 then there is no inverse */
130 if (mp_cmp_d(&v, 1uL) != MP_EQ) {
131 res = MP_VAL;
62132 goto LBL_ERR;
63 }
64 /* 4.2 if B is odd then */
65 if (mp_isodd (&B) == MP_YES) {
66 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
67 goto LBL_ERR;
133 }
134
135 /* b is now the inverse */
136 neg = a->sign;
137 while (D.sign == MP_NEG) {
138 if ((res = mp_add(&D, b, &D)) != MP_OKAY) {
139 goto LBL_ERR;
68140 }
69 }
70 /* B = B/2 */
71 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
72 goto LBL_ERR;
73 }
74 }
141 }
142 mp_exch(&D, c);
143 c->sign = neg;
144 res = MP_OKAY;
75145
76 /* 5. while v is even do */
77 while (mp_iseven (&v) == MP_YES) {
78 /* 5.1 v = v/2 */
79 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
80 goto LBL_ERR;
81 }
82 /* 5.2 if D is odd then */
83 if (mp_isodd (&D) == MP_YES) {
84 /* D = (D-x)/2 */
85 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
86 goto LBL_ERR;
87 }
88 }
89 /* D = D/2 */
90 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
91 goto LBL_ERR;
92 }
93 }
94
95 /* 6. if u >= v then */
96 if (mp_cmp (&u, &v) != MP_LT) {
97 /* u = u - v, B = B - D */
98 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
99 goto LBL_ERR;
100 }
101
102 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
103 goto LBL_ERR;
104 }
105 } else {
106 /* v - v - u, D = D - B */
107 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
108 goto LBL_ERR;
109 }
110
111 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
112 goto LBL_ERR;
113 }
114 }
115
116 /* if not zero goto step 4 */
117 if (mp_iszero (&u) == MP_NO) {
118 goto top;
119 }
120
121 /* now a = C, b = D, gcd == g*v */
122
123 /* if v != 1 then there is no inverse */
124 if (mp_cmp_d (&v, 1) != MP_EQ) {
125 res = MP_VAL;
126 goto LBL_ERR;
127 }
128
129 /* b is now the inverse */
130 neg = a->sign;
131 while (D.sign == MP_NEG) {
132 if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
133 goto LBL_ERR;
134 }
135 }
136 mp_exch (&D, c);
137 c->sign = neg;
138 res = MP_OKAY;
139
140 LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
141 return res;
146 LBL_ERR:
147 mp_clear_multi(&x, &y, &u, &v, &B, &D, NULL);
148 return res;
142149 }
143150 #endif
144151
145 /* $Source$ */
146 /* $Revision$ */
147 /* $Date$ */
152 /* ref: $Format:%D$ */
153 /* git commit: $Format:%H$ */
154 /* commit time: $Format:%ai$ */
2222 *
2323 * Based on Algorithm 14.32 on pp.601 of HAC.
2424 */
25 int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
25 int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
2626 {
27 int ix, res, olduse;
28 mp_word W[MP_WARRAY];
27 int ix, res, olduse;
28 mp_word W[MP_WARRAY];
2929
30 /* get old used count */
31 olduse = x->used;
30 if (x->used > (int)MP_WARRAY) {
31 return MP_VAL;
32 }
3233
33 /* grow a as required */
34 if (x->alloc < (n->used + 1)) {
35 if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
36 return res;
37 }
38 }
34 /* get old used count */
35 olduse = x->used;
3936
40 /* first we have to get the digits of the input into
41 * an array of double precision words W[...]
42 */
43 {
44 mp_word *_W;
45 mp_digit *tmpx;
37 /* grow a as required */
38 if (x->alloc < (n->used + 1)) {
39 if ((res = mp_grow(x, n->used + 1)) != MP_OKAY) {
40 return res;
41 }
42 }
4643
47 /* alias for the W[] array */
48 _W = W;
44 /* first we have to get the digits of the input into
45 * an array of double precision words W[...]
46 */
47 {
48 mp_word *_W;
49 mp_digit *tmpx;
4950
50 /* alias for the digits of x*/
51 tmpx = x->dp;
51 /* alias for the W[] array */
52 _W = W;
5253
53 /* copy the digits of a into W[0..a->used-1] */
54 for (ix = 0; ix < x->used; ix++) {
55 *_W++ = *tmpx++;
56 }
54 /* alias for the digits of x*/
55 tmpx = x->dp;
5756
58 /* zero the high words of W[a->used..m->used*2] */
59 for (; ix < ((n->used * 2) + 1); ix++) {
60 *_W++ = 0;
61 }
62 }
57 /* copy the digits of a into W[0..a->used-1] */
58 for (ix = 0; ix < x->used; ix++) {
59 *_W++ = *tmpx++;
60 }
6361
64 /* now we proceed to zero successive digits
65 * from the least significant upwards
66 */
67 for (ix = 0; ix < n->used; ix++) {
68 /* mu = ai * m' mod b
69 *
70 * We avoid a double precision multiplication (which isn't required)
71 * by casting the value down to a mp_digit. Note this requires
72 * that W[ix-1] have the carry cleared (see after the inner loop)
73 */
74 mp_digit mu;
75 mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
62 /* zero the high words of W[a->used..m->used*2] */
63 for (; ix < ((n->used * 2) + 1); ix++) {
64 *_W++ = 0;
65 }
66 }
7667
77 /* a = a + mu * m * b**i
78 *
79 * This is computed in place and on the fly. The multiplication
80 * by b**i is handled by offseting which columns the results
81 * are added to.
82 *
83 * Note the comba method normally doesn't handle carries in the
84 * inner loop In this case we fix the carry from the previous
85 * column since the Montgomery reduction requires digits of the
86 * result (so far) [see above] to work. This is
87 * handled by fixing up one carry after the inner loop. The
88 * carry fixups are done in order so after these loops the
89 * first m->used words of W[] have the carries fixed
90 */
91 {
92 int iy;
93 mp_digit *tmpn;
94 mp_word *_W;
68 /* now we proceed to zero successive digits
69 * from the least significant upwards
70 */
71 for (ix = 0; ix < n->used; ix++) {
72 /* mu = ai * m' mod b
73 *
74 * We avoid a double precision multiplication (which isn't required)
75 * by casting the value down to a mp_digit. Note this requires
76 * that W[ix-1] have the carry cleared (see after the inner loop)
77 */
78 mp_digit mu;
79 mu = ((W[ix] & MP_MASK) * rho) & MP_MASK;
9580
96 /* alias for the digits of the modulus */
97 tmpn = n->dp;
81 /* a = a + mu * m * b**i
82 *
83 * This is computed in place and on the fly. The multiplication
84 * by b**i is handled by offseting which columns the results
85 * are added to.
86 *
87 * Note the comba method normally doesn't handle carries in the
88 * inner loop In this case we fix the carry from the previous
89 * column since the Montgomery reduction requires digits of the
90 * result (so far) [see above] to work. This is
91 * handled by fixing up one carry after the inner loop. The
92 * carry fixups are done in order so after these loops the
93 * first m->used words of W[] have the carries fixed
94 */
95 {
96 int iy;
97 mp_digit *tmpn;
98 mp_word *_W;
9899
99 /* Alias for the columns set by an offset of ix */
100 _W = W + ix;
100 /* alias for the digits of the modulus */
101 tmpn = n->dp;
101102
102 /* inner loop */
103 for (iy = 0; iy < n->used; iy++) {
104 *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
103 /* Alias for the columns set by an offset of ix */
104 _W = W + ix;
105
106 /* inner loop */
107 for (iy = 0; iy < n->used; iy++) {
108 *_W++ += (mp_word)mu * (mp_word)*tmpn++;
109 }
105110 }
106 }
107111
108 /* now fix carry for next digit, W[ix+1] */
109 W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
110 }
112 /* now fix carry for next digit, W[ix+1] */
113 W[ix + 1] += W[ix] >> (mp_word)DIGIT_BIT;
114 }
111115
112 /* now we have to propagate the carries and
113 * shift the words downward [all those least
114 * significant digits we zeroed].
115 */
116 {
117 mp_digit *tmpx;
118 mp_word *_W, *_W1;
116 /* now we have to propagate the carries and
117 * shift the words downward [all those least
118 * significant digits we zeroed].
119 */
120 {
121 mp_digit *tmpx;
122 mp_word *_W, *_W1;
119123
120 /* nox fix rest of carries */
124 /* nox fix rest of carries */
121125
122 /* alias for current word */
123 _W1 = W + ix;
126 /* alias for current word */
127 _W1 = W + ix;
124128
125 /* alias for next word, where the carry goes */
126 _W = W + ++ix;
129 /* alias for next word, where the carry goes */
130 _W = W + ++ix;
127131
128 for (; ix <= ((n->used * 2) + 1); ix++) {
129 *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
130 }
132 for (; ix <= ((n->used * 2) + 1); ix++) {
133 *_W++ += *_W1++ >> (mp_word)DIGIT_BIT;
134 }
131135
132 /* copy out, A = A/b**n
133 *
134 * The result is A/b**n but instead of converting from an
135 * array of mp_word to mp_digit than calling mp_rshd
136 * we just copy them in the right order
137 */
136 /* copy out, A = A/b**n
137 *
138 * The result is A/b**n but instead of converting from an
139 * array of mp_word to mp_digit than calling mp_rshd
140 * we just copy them in the right order
141 */
138142
139 /* alias for destination word */
140 tmpx = x->dp;
143 /* alias for destination word */
144 tmpx = x->dp;
141145
142 /* alias for shifted double precision result */
143 _W = W + n->used;
146 /* alias for shifted double precision result */
147 _W = W + n->used;
144148
145 for (ix = 0; ix < (n->used + 1); ix++) {
146 *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
147 }
149 for (ix = 0; ix < (n->used + 1); ix++) {
150 *tmpx++ = *_W++ & (mp_word)MP_MASK;
151 }
148152
149 /* zero oldused digits, if the input a was larger than
150 * m->used+1 we'll have to clear the digits
151 */
152 for (; ix < olduse; ix++) {
153 *tmpx++ = 0;
154 }
155 }
153 /* zero oldused digits, if the input a was larger than
154 * m->used+1 we'll have to clear the digits
155 */
156 for (; ix < olduse; ix++) {
157 *tmpx++ = 0;
158 }
159 }
156160
157 /* set the max used and clamp */
158 x->used = n->used + 1;
159 mp_clamp (x);
161 /* set the max used and clamp */
162 x->used = n->used + 1;
163 mp_clamp(x);
160164
161 /* if A >= m then A = A - m */
162 if (mp_cmp_mag (x, n) != MP_LT) {
163 return s_mp_sub (x, n, x);
164 }
165 return MP_OKAY;
165 /* if A >= m then A = A - m */
166 if (mp_cmp_mag(x, n) != MP_LT) {
167 return s_mp_sub(x, n, x);
168 }
169 return MP_OKAY;
166170 }
167171 #endif
168172
169 /* $Source$ */
170 /* $Revision$ */
171 /* $Date$ */
173 /* ref: $Format:%D$ */
174 /* git commit: $Format:%H$ */
175 /* commit time: $Format:%ai$ */
1616
1717 /* Fast (comba) multiplier
1818 *
19 * This is the fast column-array [comba] multiplier. It is
20 * designed to compute the columns of the product first
21 * then handle the carries afterwards. This has the effect
19 * This is the fast column-array [comba] multiplier. It is
20 * designed to compute the columns of the product first
21 * then handle the carries afterwards. This has the effect
2222 * of making the nested loops that compute the columns very
2323 * simple and schedulable on super-scalar processors.
2424 *
25 * This has been modified to produce a variable number of
26 * digits of output so if say only a half-product is required
27 * you don't have to compute the upper half (a feature
25 * This has been modified to produce a variable number of
26 * digits of output so if say only a half-product is required
27 * you don't have to compute the upper half (a feature
2828 * required for fast Barrett reduction).
2929 *
3030 * Based on Algorithm 14.12 on pp.595 of HAC.
3131 *
3232 */
33 int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
33 int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
3434 {
35 int olduse, res, pa, ix, iz;
36 mp_digit W[MP_WARRAY];
37 mp_word _W;
35 int olduse, res, pa, ix, iz;
36 mp_digit W[MP_WARRAY];
37 mp_word _W;
3838
39 /* grow the destination as required */
40 if (c->alloc < digs) {
41 if ((res = mp_grow (c, digs)) != MP_OKAY) {
42 return res;
43 }
44 }
39 /* grow the destination as required */
40 if (c->alloc < digs) {
41 if ((res = mp_grow(c, digs)) != MP_OKAY) {
42 return res;
43 }
44 }
4545
46 /* number of output digits to produce */
47 pa = MIN(digs, a->used + b->used);
46 /* number of output digits to produce */
47 pa = MIN(digs, a->used + b->used);
4848
49 /* clear the carry */
50 _W = 0;
51 for (ix = 0; ix < pa; ix++) {
49 /* clear the carry */
50 _W = 0;
51 for (ix = 0; ix < pa; ix++) {
5252 int tx, ty;
5353 int iy;
5454 mp_digit *tmpx, *tmpy;
6161 tmpx = a->dp + tx;
6262 tmpy = b->dp + ty;
6363
64 /* this is the number of times the loop will iterrate, essentially
64 /* this is the number of times the loop will iterrate, essentially
6565 while (tx++ < a->used && ty-- >= 0) { ... }
6666 */
6767 iy = MIN(a->used-tx, ty+1);
6868
6969 /* execute loop */
7070 for (iz = 0; iz < iy; ++iz) {
71 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
71 _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
7272
7373 }
7474
7575 /* store term */
76 W[ix] = ((mp_digit)_W) & MP_MASK;
76 W[ix] = (mp_digit)_W & MP_MASK;
7777
7878 /* make next carry */
79 _W = _W >> ((mp_word)DIGIT_BIT);
80 }
79 _W = _W >> (mp_word)DIGIT_BIT;
80 }
8181
82 /* setup dest */
83 olduse = c->used;
84 c->used = pa;
82 /* setup dest */
83 olduse = c->used;
84 c->used = pa;
8585
86 {
87 mp_digit *tmpc;
88 tmpc = c->dp;
89 for (ix = 0; ix < (pa + 1); ix++) {
90 /* now extract the previous digit [below the carry] */
91 *tmpc++ = W[ix];
92 }
86 {
87 mp_digit *tmpc;
88 tmpc = c->dp;
89 for (ix = 0; ix < pa; ix++) {
90 /* now extract the previous digit [below the carry] */
91 *tmpc++ = W[ix];
92 }
9393
94 /* clear unused digits [that existed in the old copy of c] */
95 for (; ix < olduse; ix++) {
96 *tmpc++ = 0;
97 }
98 }
99 mp_clamp (c);
100 return MP_OKAY;
94 /* clear unused digits [that existed in the old copy of c] */
95 for (; ix < olduse; ix++) {
96 *tmpc++ = 0;
97 }
98 }
99 mp_clamp(c);
100 return MP_OKAY;
101101 }
102102 #endif
103103
104 /* $Source$ */
105 /* $Revision$ */
106 /* $Date$ */
104 /* ref: $Format:%D$ */
105 /* git commit: $Format:%H$ */
106 /* commit time: $Format:%ai$ */
2323 *
2424 * Based on Algorithm 14.12 on pp.595 of HAC.
2525 */
26 int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
26 int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
2727 {
28 int olduse, res, pa, ix, iz;
29 mp_digit W[MP_WARRAY];
30 mp_word _W;
28 int olduse, res, pa, ix, iz;
29 mp_digit W[MP_WARRAY];
30 mp_word _W;
3131
32 /* grow the destination as required */
33 pa = a->used + b->used;
34 if (c->alloc < pa) {
35 if ((res = mp_grow (c, pa)) != MP_OKAY) {
36 return res;
37 }
38 }
32 /* grow the destination as required */
33 pa = a->used + b->used;
34 if (c->alloc < pa) {
35 if ((res = mp_grow(c, pa)) != MP_OKAY) {
36 return res;
37 }
38 }
3939
40 /* number of output digits to produce */
41 pa = a->used + b->used;
42 _W = 0;
43 for (ix = digs; ix < pa; ix++) {
40 /* number of output digits to produce */
41 pa = a->used + b->used;
42 _W = 0;
43 for (ix = digs; ix < pa; ix++) {
4444 int tx, ty, iy;
4545 mp_digit *tmpx, *tmpy;
4646
5252 tmpx = a->dp + tx;
5353 tmpy = b->dp + ty;
5454
55 /* this is the number of times the loop will iterrate, essentially its
55 /* this is the number of times the loop will iterrate, essentially its
5656 while (tx++ < a->used && ty-- >= 0) { ... }
5757 */
5858 iy = MIN(a->used-tx, ty+1);
5959
6060 /* execute loop */
6161 for (iz = 0; iz < iy; iz++) {
62 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
62 _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
6363 }
6464
6565 /* store term */
66 W[ix] = ((mp_digit)_W) & MP_MASK;
66 W[ix] = (mp_digit)_W & MP_MASK;
6767
6868 /* make next carry */
69 _W = _W >> ((mp_word)DIGIT_BIT);
70 }
71
72 /* setup dest */
73 olduse = c->used;
74 c->used = pa;
69 _W = _W >> (mp_word)DIGIT_BIT;
70 }
7571
76 {
77 mp_digit *tmpc;
72 /* setup dest */
73 olduse = c->used;
74 c->used = pa;
7875
79 tmpc = c->dp + digs;
80 for (ix = digs; ix < pa; ix++) {
81 /* now extract the previous digit [below the carry] */
82 *tmpc++ = W[ix];
83 }
76 {
77 mp_digit *tmpc;
8478
85 /* clear unused digits [that existed in the old copy of c] */
86 for (; ix < olduse; ix++) {
87 *tmpc++ = 0;
88 }
89 }
90 mp_clamp (c);
91 return MP_OKAY;
79 tmpc = c->dp + digs;
80 for (ix = digs; ix < pa; ix++) {
81 /* now extract the previous digit [below the carry] */
82 *tmpc++ = W[ix];
83 }
84
85 /* clear unused digits [that existed in the old copy of c] */
86 for (; ix < olduse; ix++) {
87 *tmpc++ = 0;
88 }
89 }
90 mp_clamp(c);
91 return MP_OKAY;
9292 }
9393 #endif
9494
95 /* $Source$ */
96 /* $Revision$ */
97 /* $Date$ */
95 /* ref: $Format:%D$ */
96 /* git commit: $Format:%H$ */
97 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* the jist of squaring...
18 * you do like mult except the offset of the tmpx [one that
19 * starts closer to zero] can't equal the offset of tmpy.
18 * you do like mult except the offset of the tmpx [one that
19 * starts closer to zero] can't equal the offset of tmpy.
2020 * So basically you set up iy like before then you min it with
21 * (ty-tx) so that it never happens. You double all those
21 * (ty-tx) so that it never happens. You double all those
2222 * you add in the inner loop
2323
2424 After that loop you do the squares and add them in.
2525 */
2626
27 int fast_s_mp_sqr (mp_int * a, mp_int * b)
27 int fast_s_mp_sqr(const mp_int *a, mp_int *b)
2828 {
29 int olduse, res, pa, ix, iz;
30 mp_digit W[MP_WARRAY], *tmpx;
31 mp_word W1;
29 int olduse, res, pa, ix, iz;
30 mp_digit W[MP_WARRAY], *tmpx;
31 mp_word W1;
3232
33 /* grow the destination as required */
34 pa = a->used + a->used;
35 if (b->alloc < pa) {
36 if ((res = mp_grow (b, pa)) != MP_OKAY) {
37 return res;
38 }
39 }
33 /* grow the destination as required */
34 pa = a->used + a->used;
35 if (b->alloc < pa) {
36 if ((res = mp_grow(b, pa)) != MP_OKAY) {
37 return res;
38 }
39 }
4040
41 /* number of output digits to produce */
42 W1 = 0;
43 for (ix = 0; ix < pa; ix++) {
41 /* number of output digits to produce */
42 W1 = 0;
43 for (ix = 0; ix < pa; ix++) {
4444 int tx, ty, iy;
4545 mp_word _W;
4646 mp_digit *tmpy;
6161 */
6262 iy = MIN(a->used-tx, ty+1);
6363
64 /* now for squaring tx can never equal ty
64 /* now for squaring tx can never equal ty
6565 * we halve the distance since they approach at a rate of 2x
6666 * and we have to round because odd cases need to be executed
6767 */
6969
7070 /* execute loop */
7171 for (iz = 0; iz < iy; iz++) {
72 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
72 _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
7373 }
7474
7575 /* double the inner product and add carry */
7676 _W = _W + _W + W1;
7777
7878 /* even columns have the square term in them */
79 if ((ix&1) == 0) {
80 _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
79 if (((unsigned)ix & 1u) == 0u) {
80 _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1];
8181 }
8282
8383 /* store it */
84 W[ix] = (mp_digit)(_W & MP_MASK);
84 W[ix] = _W & MP_MASK;
8585
8686 /* make next carry */
87 W1 = _W >> ((mp_word)DIGIT_BIT);
88 }
87 W1 = _W >> (mp_word)DIGIT_BIT;
88 }
8989
90 /* setup dest */
91 olduse = b->used;
92 b->used = a->used+a->used;
90 /* setup dest */
91 olduse = b->used;
92 b->used = a->used+a->used;
9393
94 {
95 mp_digit *tmpb;
96 tmpb = b->dp;
97 for (ix = 0; ix < pa; ix++) {
98 *tmpb++ = W[ix] & MP_MASK;
99 }
94 {
95 mp_digit *tmpb;
96 tmpb = b->dp;
97 for (ix = 0; ix < pa; ix++) {
98 *tmpb++ = W[ix] & MP_MASK;
99 }
100100
101 /* clear unused digits [that existed in the old copy of c] */
102 for (; ix < olduse; ix++) {
103 *tmpb++ = 0;
104 }
105 }
106 mp_clamp (b);
107 return MP_OKAY;
101 /* clear unused digits [that existed in the old copy of c] */
102 for (; ix < olduse; ix++) {
103 *tmpb++ = 0;
104 }
105 }
106 mp_clamp(b);
107 return MP_OKAY;
108108 }
109109 #endif
110110
111 /* $Source$ */
112 /* $Revision$ */
113 /* $Date$ */
111 /* ref: $Format:%D$ */
112 /* git commit: $Format:%H$ */
113 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* computes a = 2**b
17 /* computes a = 2**b
1818 *
1919 * Simple algorithm which zeroes the int, grows it then just sets one bit
2020 * as required.
2121 */
22 int
23 mp_2expt (mp_int * a, int b)
22 int mp_2expt(mp_int *a, int b)
2423 {
25 int res;
24 int res;
2625
27 /* zero a as per default */
28 mp_zero (a);
26 /* zero a as per default */
27 mp_zero(a);
2928
30 /* grow a to accomodate the single bit */
31 if ((res = mp_grow (a, (b / DIGIT_BIT) + 1)) != MP_OKAY) {
32 return res;
33 }
29 /* grow a to accomodate the single bit */
30 if ((res = mp_grow(a, (b / DIGIT_BIT) + 1)) != MP_OKAY) {
31 return res;
32 }
3433
35 /* set the used count of where the bit will go */
36 a->used = (b / DIGIT_BIT) + 1;
34 /* set the used count of where the bit will go */
35 a->used = (b / DIGIT_BIT) + 1;
3736
38 /* put the single bit in its place */
39 a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
37 /* put the single bit in its place */
38 a->dp[b / DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % DIGIT_BIT);
4039
41 return MP_OKAY;
40 return MP_OKAY;
4241 }
4342 #endif
4443
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
44 /* ref: $Format:%D$ */
45 /* git commit: $Format:%H$ */
46 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* b = |a|
17 /* b = |a|
1818 *
1919 * Simple function copies the input and fixes the sign to positive
2020 */
21 int
22 mp_abs (mp_int * a, mp_int * b)
21 int mp_abs(const mp_int *a, mp_int *b)
2322 {
24 int res;
23 int res;
2524
26 /* copy a to b */
27 if (a != b) {
28 if ((res = mp_copy (a, b)) != MP_OKAY) {
29 return res;
30 }
31 }
25 /* copy a to b */
26 if (a != b) {
27 if ((res = mp_copy(a, b)) != MP_OKAY) {
28 return res;
29 }
30 }
3231
33 /* force the sign of b to positive */
34 b->sign = MP_ZPOS;
32 /* force the sign of b to positive */
33 b->sign = MP_ZPOS;
3534
36 return MP_OKAY;
35 return MP_OKAY;
3736 }
3837 #endif
3938
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
39 /* ref: $Format:%D$ */
40 /* git commit: $Format:%H$ */
41 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* high level addition (handles signs) */
18 int mp_add (mp_int * a, mp_int * b, mp_int * c)
18 int mp_add(const mp_int *a, const mp_int *b, mp_int *c)
1919 {
20 int sa, sb, res;
20 int sa, sb, res;
2121
22 /* get sign of both inputs */
23 sa = a->sign;
24 sb = b->sign;
22 /* get sign of both inputs */
23 sa = a->sign;
24 sb = b->sign;
2525
26 /* handle two cases, not four */
27 if (sa == sb) {
28 /* both positive or both negative */
29 /* add their magnitudes, copy the sign */
30 c->sign = sa;
31 res = s_mp_add (a, b, c);
32 } else {
33 /* one positive, the other negative */
34 /* subtract the one with the greater magnitude from */
35 /* the one of the lesser magnitude. The result gets */
36 /* the sign of the one with the greater magnitude. */
37 if (mp_cmp_mag (a, b) == MP_LT) {
38 c->sign = sb;
39 res = s_mp_sub (b, a, c);
40 } else {
26 /* handle two cases, not four */
27 if (sa == sb) {
28 /* both positive or both negative */
29 /* add their magnitudes, copy the sign */
4130 c->sign = sa;
42 res = s_mp_sub (a, b, c);
43 }
44 }
45 return res;
31 res = s_mp_add(a, b, c);
32 } else {
33 /* one positive, the other negative */
34 /* subtract the one with the greater magnitude from */
35 /* the one of the lesser magnitude. The result gets */
36 /* the sign of the one with the greater magnitude. */
37 if (mp_cmp_mag(a, b) == MP_LT) {
38 c->sign = sb;
39 res = s_mp_sub(b, a, c);
40 } else {
41 c->sign = sa;
42 res = s_mp_sub(a, b, c);
43 }
44 }
45 return res;
4646 }
4747
4848 #endif
4949
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
50 /* ref: $Format:%D$ */
51 /* git commit: $Format:%H$ */
52 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* single digit addition */
18 int
19 mp_add_d (mp_int * a, mp_digit b, mp_int * c)
18 int mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
2019 {
21 int res, ix, oldused;
22 mp_digit *tmpa, *tmpc, mu;
20 int res, ix, oldused;
21 mp_digit *tmpa, *tmpc, mu;
2322
24 /* grow c as required */
25 if (c->alloc < (a->used + 1)) {
26 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27 return res;
28 }
29 }
23 /* grow c as required */
24 if (c->alloc < (a->used + 1)) {
25 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
26 return res;
27 }
28 }
3029
31 /* if a is negative and |a| >= b, call c = |a| - b */
32 if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
33 /* temporarily fix sign of a */
34 a->sign = MP_ZPOS;
30 /* if a is negative and |a| >= b, call c = |a| - b */
31 if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
32 mp_int a_ = *a;
33 /* temporarily fix sign of a */
34 a_.sign = MP_ZPOS;
3535
36 /* c = |a| - b */
37 res = mp_sub_d(a, b, c);
36 /* c = |a| - b */
37 res = mp_sub_d(&a_, b, c);
3838
39 /* fix sign */
40 a->sign = c->sign = MP_NEG;
39 /* fix sign */
40 c->sign = MP_NEG;
4141
42 /* clamp */
43 mp_clamp(c);
42 /* clamp */
43 mp_clamp(c);
4444
45 return res;
46 }
45 return res;
46 }
4747
48 /* old number of used digits in c */
49 oldused = c->used;
48 /* old number of used digits in c */
49 oldused = c->used;
5050
51 /* sign always positive */
52 c->sign = MP_ZPOS;
51 /* source alias */
52 tmpa = a->dp;
5353
54 /* source alias */
55 tmpa = a->dp;
54 /* destination alias */
55 tmpc = c->dp;
5656
57 /* destination alias */
58 tmpc = c->dp;
57 /* if a is positive */
58 if (a->sign == MP_ZPOS) {
59 /* add digit, after this we're propagating
60 * the carry.
61 */
62 *tmpc = *tmpa++ + b;
63 mu = *tmpc >> DIGIT_BIT;
64 *tmpc++ &= MP_MASK;
5965
60 /* if a is positive */
61 if (a->sign == MP_ZPOS) {
62 /* add digit, after this we're propagating
63 * the carry.
64 */
65 *tmpc = *tmpa++ + b;
66 mu = *tmpc >> DIGIT_BIT;
67 *tmpc++ &= MP_MASK;
66 /* now handle rest of the digits */
67 for (ix = 1; ix < a->used; ix++) {
68 *tmpc = *tmpa++ + mu;
69 mu = *tmpc >> DIGIT_BIT;
70 *tmpc++ &= MP_MASK;
71 }
72 /* set final carry */
73 ix++;
74 *tmpc++ = mu;
6875
69 /* now handle rest of the digits */
70 for (ix = 1; ix < a->used; ix++) {
71 *tmpc = *tmpa++ + mu;
72 mu = *tmpc >> DIGIT_BIT;
73 *tmpc++ &= MP_MASK;
74 }
75 /* set final carry */
76 ix++;
77 *tmpc++ = mu;
76 /* setup size */
77 c->used = a->used + 1;
78 } else {
79 /* a was negative and |a| < b */
80 c->used = 1;
7881
79 /* setup size */
80 c->used = a->used + 1;
81 } else {
82 /* a was negative and |a| < b */
83 c->used = 1;
82 /* the result is a single digit */
83 if (a->used == 1) {
84 *tmpc++ = b - a->dp[0];
85 } else {
86 *tmpc++ = b;
87 }
8488
85 /* the result is a single digit */
86 if (a->used == 1) {
87 *tmpc++ = b - a->dp[0];
88 } else {
89 *tmpc++ = b;
90 }
89 /* setup count so the clearing of oldused
90 * can fall through correctly
91 */
92 ix = 1;
93 }
9194
92 /* setup count so the clearing of oldused
93 * can fall through correctly
94 */
95 ix = 1;
96 }
95 /* sign always positive */
96 c->sign = MP_ZPOS;
9797
98 /* now zero to oldused */
99 while (ix++ < oldused) {
100 *tmpc++ = 0;
101 }
102 mp_clamp(c);
98 /* now zero to oldused */
99 while (ix++ < oldused) {
100 *tmpc++ = 0;
101 }
102 mp_clamp(c);
103103
104 return MP_OKAY;
104 return MP_OKAY;
105105 }
106106
107107 #endif
108108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
109 /* ref: $Format:%D$ */
110 /* git commit: $Format:%H$ */
111 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* d = a + b (mod c) */
18 int
19 mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
18 int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
2019 {
21 int res;
22 mp_int t;
20 int res;
21 mp_int t;
2322
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
23 if ((res = mp_init(&t)) != MP_OKAY) {
24 return res;
25 }
2726
28 if ((res = mp_add (a, b, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32 res = mp_mod (&t, c, d);
33 mp_clear (&t);
34 return res;
27 if ((res = mp_add(a, b, &t)) != MP_OKAY) {
28 mp_clear(&t);
29 return res;
30 }
31 res = mp_mod(&t, c, d);
32 mp_clear(&t);
33 return res;
3534 }
3635 #endif
3736
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
37 /* ref: $Format:%D$ */
38 /* git commit: $Format:%H$ */
39 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* AND two ints together */
18 int
19 mp_and (mp_int * a, mp_int * b, mp_int * c)
18 int mp_and(const mp_int *a, const mp_int *b, mp_int *c)
2019 {
21 int res, ix, px;
22 mp_int t, *x;
20 int res, ix, px;
21 mp_int t;
22 const mp_int *x;
2323
24 if (a->used > b->used) {
25 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
24 if (a->used > b->used) {
25 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
3737
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] &= x->dp[ix];
40 }
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] &= x->dp[ix];
40 }
4141
42 /* zero digits above the last from the smallest mp_int */
43 for (; ix < t.used; ix++) {
44 t.dp[ix] = 0;
45 }
42 /* zero digits above the last from the smallest mp_int */
43 for (; ix < t.used; ix++) {
44 t.dp[ix] = 0;
45 }
4646
47 mp_clamp (&t);
48 mp_exch (c, &t);
49 mp_clear (&t);
50 return MP_OKAY;
47 mp_clamp(&t);
48 mp_exch(c, &t);
49 mp_clear(&t);
50 return MP_OKAY;
5151 }
5252 #endif
5353
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
54 /* ref: $Format:%D$ */
55 /* git commit: $Format:%H$ */
56 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* trim unused digits
17 /* trim unused digits
1818 *
1919 * This is used to ensure that leading zero digits are
2020 * trimed and the leading "used" digit will be non-zero
2121 * Typically very fast. Also fixes the sign if there
2222 * are no more leading digits
2323 */
24 void
25 mp_clamp (mp_int * a)
24 void mp_clamp(mp_int *a)
2625 {
27 /* decrease used while the most significant digit is
28 * zero.
29 */
30 while ((a->used > 0) && (a->dp[a->used - 1] == 0)) {
31 --(a->used);
32 }
26 /* decrease used while the most significant digit is
27 * zero.
28 */
29 while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) {
30 --(a->used);
31 }
3332
34 /* reset the sign flag if used == 0 */
35 if (a->used == 0) {
36 a->sign = MP_ZPOS;
37 }
33 /* reset the sign flag if used == 0 */
34 if (a->used == 0) {
35 a->sign = MP_ZPOS;
36 }
3837 }
3938 #endif
4039
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
40 /* ref: $Format:%D$ */
41 /* git commit: $Format:%H$ */
42 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* clear one (frees) */
18 void
19 mp_clear (mp_int * a)
18 void mp_clear(mp_int *a)
2019 {
21 int i;
20 int i;
2221
23 /* only do anything if a hasn't been freed previously */
24 if (a->dp != NULL) {
25 /* first zero the digits */
26 for (i = 0; i < a->used; i++) {
27 a->dp[i] = 0;
28 }
22 /* only do anything if a hasn't been freed previously */
23 if (a->dp != NULL) {
24 /* first zero the digits */
25 for (i = 0; i < a->used; i++) {
26 a->dp[i] = 0;
27 }
2928
30 /* free ram */
31 XFREE(a->dp);
29 /* free ram */
30 XFREE(a->dp);
3231
33 /* reset members to make debugging easier */
34 a->dp = NULL;
35 a->alloc = a->used = 0;
36 a->sign = MP_ZPOS;
37 }
32 /* reset members to make debugging easier */
33 a->dp = NULL;
34 a->alloc = a->used = 0;
35 a->sign = MP_ZPOS;
36 }
3837 }
3938 #endif
4039
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
40 /* ref: $Format:%D$ */
41 /* git commit: $Format:%H$ */
42 /* commit time: $Format:%ai$ */
1515 */
1616 #include <stdarg.h>
1717
18 void mp_clear_multi(mp_int *mp, ...)
18 void mp_clear_multi(mp_int *mp, ...)
1919 {
20 mp_int* next_mp = mp;
21 va_list args;
22 va_start(args, mp);
23 while (next_mp != NULL) {
24 mp_clear(next_mp);
25 next_mp = va_arg(args, mp_int*);
26 }
27 va_end(args);
20 mp_int *next_mp = mp;
21 va_list args;
22 va_start(args, mp);
23 while (next_mp != NULL) {
24 mp_clear(next_mp);
25 next_mp = va_arg(args, mp_int *);
26 }
27 va_end(args);
2828 }
2929 #endif
3030
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
31 /* ref: $Format:%D$ */
32 /* git commit: $Format:%H$ */
33 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* compare two ints (signed)*/
18 int
19 mp_cmp (mp_int * a, mp_int * b)
18 int mp_cmp(const mp_int *a, const mp_int *b)
2019 {
21 /* compare based on sign */
22 if (a->sign != b->sign) {
23 if (a->sign == MP_NEG) {
24 return MP_LT;
25 } else {
26 return MP_GT;
27 }
28 }
29
30 /* compare digits */
31 if (a->sign == MP_NEG) {
32 /* if negative compare opposite direction */
33 return mp_cmp_mag(b, a);
34 } else {
35 return mp_cmp_mag(a, b);
36 }
20 /* compare based on sign */
21 if (a->sign != b->sign) {
22 if (a->sign == MP_NEG) {
23 return MP_LT;
24 } else {
25 return MP_GT;
26 }
27 }
28
29 /* compare digits */
30 if (a->sign == MP_NEG) {
31 /* if negative compare opposite direction */
32 return mp_cmp_mag(b, a);
33 } else {
34 return mp_cmp_mag(a, b);
35 }
3736 }
3837 #endif
3938
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
39 /* ref: $Format:%D$ */
40 /* git commit: $Format:%H$ */
41 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* compare a digit */
18 int mp_cmp_d(mp_int * a, mp_digit b)
18 int mp_cmp_d(const mp_int *a, mp_digit b)
1919 {
20 /* compare based on sign */
21 if (a->sign == MP_NEG) {
22 return MP_LT;
23 }
20 /* compare based on sign */
21 if (a->sign == MP_NEG) {
22 return MP_LT;
23 }
2424
25 /* compare based on magnitude */
26 if (a->used > 1) {
27 return MP_GT;
28 }
25 /* compare based on magnitude */
26 if (a->used > 1) {
27 return MP_GT;
28 }
2929
30 /* compare the only digit of a to b */
31 if (a->dp[0] > b) {
32 return MP_GT;
33 } else if (a->dp[0] < b) {
34 return MP_LT;
35 } else {
36 return MP_EQ;
37 }
30 /* compare the only digit of a to b */
31 if (a->dp[0] > b) {
32 return MP_GT;
33 } else if (a->dp[0] < b) {
34 return MP_LT;
35 } else {
36 return MP_EQ;
37 }
3838 }
3939 #endif
4040
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
41 /* ref: $Format:%D$ */
42 /* git commit: $Format:%H$ */
43 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* compare maginitude of two ints (unsigned) */
18 int mp_cmp_mag (mp_int * a, mp_int * b)
18 int mp_cmp_mag(const mp_int *a, const mp_int *b)
1919 {
20 int n;
21 mp_digit *tmpa, *tmpb;
20 int n;
21 mp_digit *tmpa, *tmpb;
2222
23 /* compare based on # of non-zero digits */
24 if (a->used > b->used) {
25 return MP_GT;
26 }
27
28 if (a->used < b->used) {
29 return MP_LT;
30 }
23 /* compare based on # of non-zero digits */
24 if (a->used > b->used) {
25 return MP_GT;
26 }
3127
32 /* alias for a */
33 tmpa = a->dp + (a->used - 1);
28 if (a->used < b->used) {
29 return MP_LT;
30 }
3431
35 /* alias for b */
36 tmpb = b->dp + (a->used - 1);
32 /* alias for a */
33 tmpa = a->dp + (a->used - 1);
3734
38 /* compare based on digits */
39 for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
40 if (*tmpa > *tmpb) {
41 return MP_GT;
42 }
35 /* alias for b */
36 tmpb = b->dp + (a->used - 1);
4337
44 if (*tmpa < *tmpb) {
45 return MP_LT;
46 }
47 }
48 return MP_EQ;
38 /* compare based on digits */
39 for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
40 if (*tmpa > *tmpb) {
41 return MP_GT;
42 }
43
44 if (*tmpa < *tmpb) {
45 return MP_LT;
46 }
47 }
48 return MP_EQ;
4949 }
5050 #endif
5151
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
52 /* ref: $Format:%D$ */
53 /* git commit: $Format:%H$ */
54 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 static const int lnz[16] = {
17 static const int lnz[16] = {
1818 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
1919 };
2020
2121 /* Counts the number of lsbs which are zero before the first zero bit */
22 int mp_cnt_lsb(mp_int *a)
22 int mp_cnt_lsb(const mp_int *a)
2323 {
2424 int x;
2525 mp_digit q, qq;
3030 }
3131
3232 /* scan lower digits until non-zero */
33 for (x = 0; (x < a->used) && (a->dp[x] == 0); x++) {}
33 for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {}
3434 q = a->dp[x];
3535 x *= DIGIT_BIT;
3636
3737 /* now scan this digit until a 1 is found */
38 if ((q & 1) == 0) {
38 if ((q & 1u) == 0u) {
3939 do {
40 qq = q & 15;
40 qq = q & 15u;
4141 x += lnz[qq];
4242 q >>= 4;
43 } while (qq == 0);
43 } while (qq == 0u);
4444 }
4545 return x;
4646 }
4747
4848 #endif
4949
50 /* $Source$ */
51 /* $Revision$ */
52 /* $Date$ */
50 /* ref: $Format:%D$ */
51 /* git commit: $Format:%H$ */
52 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* copy, b = a */
18 int
19 mp_copy (mp_int * a, mp_int * b)
18 int mp_copy(const mp_int *a, mp_int *b)
2019 {
21 int res, n;
20 int res, n;
2221
23 /* if dst == src do nothing */
24 if (a == b) {
25 return MP_OKAY;
26 }
22 /* if dst == src do nothing */
23 if (a == b) {
24 return MP_OKAY;
25 }
2726
28 /* grow dest */
29 if (b->alloc < a->used) {
30 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
31 return res;
32 }
33 }
27 /* grow dest */
28 if (b->alloc < a->used) {
29 if ((res = mp_grow(b, a->used)) != MP_OKAY) {
30 return res;
31 }
32 }
3433
35 /* zero b and copy the parameters over */
36 {
37 mp_digit *tmpa, *tmpb;
34 /* zero b and copy the parameters over */
35 {
36 mp_digit *tmpa, *tmpb;
3837
39 /* pointer aliases */
38 /* pointer aliases */
4039
41 /* source */
42 tmpa = a->dp;
40 /* source */
41 tmpa = a->dp;
4342
44 /* destination */
45 tmpb = b->dp;
43 /* destination */
44 tmpb = b->dp;
4645
47 /* copy all the digits */
48 for (n = 0; n < a->used; n++) {
49 *tmpb++ = *tmpa++;
50 }
46 /* copy all the digits */
47 for (n = 0; n < a->used; n++) {
48 *tmpb++ = *tmpa++;
49 }
5150
52 /* clear high digits */
53 for (; n < b->used; n++) {
54 *tmpb++ = 0;
55 }
56 }
51 /* clear high digits */
52 for (; n < b->used; n++) {
53 *tmpb++ = 0;
54 }
55 }
5756
58 /* copy used count and sign */
59 b->used = a->used;
60 b->sign = a->sign;
61 return MP_OKAY;
57 /* copy used count and sign */
58 b->used = a->used;
59 b->sign = a->sign;
60 return MP_OKAY;
6261 }
6362 #endif
6463
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
64 /* ref: $Format:%D$ */
65 /* git commit: $Format:%H$ */
66 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* returns the number of bits in an int */
18 int
19 mp_count_bits (mp_int * a)
18 int mp_count_bits(const mp_int *a)
2019 {
21 int r;
22 mp_digit q;
20 int r;
21 mp_digit q;
2322
24 /* shortcut */
25 if (a->used == 0) {
26 return 0;
27 }
23 /* shortcut */
24 if (a->used == 0) {
25 return 0;
26 }
2827
29 /* get number of digits and add that */
30 r = (a->used - 1) * DIGIT_BIT;
31
32 /* take the last digit and count the bits in it */
33 q = a->dp[a->used - 1];
34 while (q > ((mp_digit) 0)) {
35 ++r;
36 q >>= ((mp_digit) 1);
37 }
38 return r;
28 /* get number of digits and add that */
29 r = (a->used - 1) * DIGIT_BIT;
30
31 /* take the last digit and count the bits in it */
32 q = a->dp[a->used - 1];
33 while (q > (mp_digit)0) {
34 ++r;
35 q >>= (mp_digit)1;
36 }
37 return r;
3938 }
4039 #endif
4140
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
41 /* ref: $Format:%D$ */
42 /* git commit: $Format:%H$ */
43 /* commit time: $Format:%ai$ */
1717 #ifdef BN_MP_DIV_SMALL
1818
1919 /* slower bit-bang division... also smaller */
20 int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
20 int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
2121 {
2222 mp_int ta, tb, tq, q;
2323 int res, n, n2;
2424
25 /* is divisor zero ? */
26 if (mp_iszero (b) == MP_YES) {
27 return MP_VAL;
28 }
29
30 /* if a < b then q=0, r = a */
31 if (mp_cmp_mag (a, b) == MP_LT) {
32 if (d != NULL) {
33 res = mp_copy (a, d);
34 } else {
35 res = MP_OKAY;
36 }
37 if (c != NULL) {
38 mp_zero (c);
39 }
40 return res;
41 }
42
43 /* init our temps */
44 if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
45 return res;
46 }
47
48
49 mp_set(&tq, 1);
50 n = mp_count_bits(a) - mp_count_bits(b);
51 if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
52 ((res = mp_abs(b, &tb)) != MP_OKAY) ||
53 ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
54 ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
25 /* is divisor zero ? */
26 if (mp_iszero(b) == MP_YES) {
27 return MP_VAL;
28 }
29
30 /* if a < b then q=0, r = a */
31 if (mp_cmp_mag(a, b) == MP_LT) {
32 if (d != NULL) {
33 res = mp_copy(a, d);
34 } else {
35 res = MP_OKAY;
36 }
37 if (c != NULL) {
38 mp_zero(c);
39 }
40 return res;
41 }
42
43 /* init our temps */
44 if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
45 return res;
46 }
47
48
49 mp_set(&tq, 1uL);
50 n = mp_count_bits(a) - mp_count_bits(b);
51 if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
52 ((res = mp_abs(b, &tb)) != MP_OKAY) ||
53 ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
54 ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
5555 goto LBL_ERR;
56 }
57
58 while (n-- >= 0) {
59 if (mp_cmp(&tb, &ta) != MP_GT) {
60 if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
61 ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
62 goto LBL_ERR;
63 }
64 }
65 if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
66 ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
67 goto LBL_ERR;
68 }
69 }
70
71 /* now q == quotient and ta == remainder */
72 n = a->sign;
73 n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
74 if (c != NULL) {
75 mp_exch(c, &q);
76 c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
77 }
78 if (d != NULL) {
79 mp_exch(d, &ta);
80 d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
81 }
56 }
57
58 while (n-- >= 0) {
59 if (mp_cmp(&tb, &ta) != MP_GT) {
60 if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
61 ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
62 goto LBL_ERR;
63 }
64 }
65 if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
66 ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
67 goto LBL_ERR;
68 }
69 }
70
71 /* now q == quotient and ta == remainder */
72 n = a->sign;
73 n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
74 if (c != NULL) {
75 mp_exch(c, &q);
76 c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
77 }
78 if (d != NULL) {
79 mp_exch(d, &ta);
80 d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
81 }
8282 LBL_ERR:
8383 mp_clear_multi(&ta, &tb, &tq, &q, NULL);
8484 return res;
9999 * The overall algorithm is as described as
100100 * 14.20 from HAC but fixed to treat these cases.
101101 */
102 int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
102 int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
103103 {
104 mp_int q, x, y, t1, t2;
105 int res, n, t, i, norm, neg;
106
107 /* is divisor zero ? */
108 if (mp_iszero (b) == MP_YES) {
109 return MP_VAL;
110 }
111
112 /* if a < b then q=0, r = a */
113 if (mp_cmp_mag (a, b) == MP_LT) {
114 if (d != NULL) {
115 res = mp_copy (a, d);
116 } else {
117 res = MP_OKAY;
118 }
119 if (c != NULL) {
120 mp_zero (c);
121 }
122 return res;
123 }
124
125 if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
126 return res;
127 }
128 q.used = a->used + 2;
129
130 if ((res = mp_init (&t1)) != MP_OKAY) {
131 goto LBL_Q;
132 }
133
134 if ((res = mp_init (&t2)) != MP_OKAY) {
135 goto LBL_T1;
136 }
137
138 if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
139 goto LBL_T2;
140 }
141
142 if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
143 goto LBL_X;
144 }
145
146 /* fix the sign */
147 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
148 x.sign = y.sign = MP_ZPOS;
149
150 /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
151 norm = mp_count_bits(&y) % DIGIT_BIT;
152 if (norm < (int)(DIGIT_BIT-1)) {
153 norm = (DIGIT_BIT-1) - norm;
154 if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
155 goto LBL_Y;
156 }
157 if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
158 goto LBL_Y;
159 }
160 } else {
161 norm = 0;
162 }
163
164 /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
165 n = x.used - 1;
166 t = y.used - 1;
167
168 /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
169 if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
170 goto LBL_Y;
171 }
172
173 while (mp_cmp (&x, &y) != MP_LT) {
174 ++(q.dp[n - t]);
175 if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
104 mp_int q, x, y, t1, t2;
105 int res, n, t, i, norm, neg;
106
107 /* is divisor zero ? */
108 if (mp_iszero(b) == MP_YES) {
109 return MP_VAL;
110 }
111
112 /* if a < b then q=0, r = a */
113 if (mp_cmp_mag(a, b) == MP_LT) {
114 if (d != NULL) {
115 res = mp_copy(a, d);
116 } else {
117 res = MP_OKAY;
118 }
119 if (c != NULL) {
120 mp_zero(c);
121 }
122 return res;
123 }
124
125 if ((res = mp_init_size(&q, a->used + 2)) != MP_OKAY) {
126 return res;
127 }
128 q.used = a->used + 2;
129
130 if ((res = mp_init(&t1)) != MP_OKAY) {
131 goto LBL_Q;
132 }
133
134 if ((res = mp_init(&t2)) != MP_OKAY) {
135 goto LBL_T1;
136 }
137
138 if ((res = mp_init_copy(&x, a)) != MP_OKAY) {
139 goto LBL_T2;
140 }
141
142 if ((res = mp_init_copy(&y, b)) != MP_OKAY) {
143 goto LBL_X;
144 }
145
146 /* fix the sign */
147 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
148 x.sign = y.sign = MP_ZPOS;
149
150 /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
151 norm = mp_count_bits(&y) % DIGIT_BIT;
152 if (norm < (DIGIT_BIT - 1)) {
153 norm = (DIGIT_BIT - 1) - norm;
154 if ((res = mp_mul_2d(&x, norm, &x)) != MP_OKAY) {
155 goto LBL_Y;
156 }
157 if ((res = mp_mul_2d(&y, norm, &y)) != MP_OKAY) {
158 goto LBL_Y;
159 }
160 } else {
161 norm = 0;
162 }
163
164 /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
165 n = x.used - 1;
166 t = y.used - 1;
167
168 /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
169 if ((res = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
176170 goto LBL_Y;
177 }
178 }
179
180 /* reset y by shifting it back down */
181 mp_rshd (&y, n - t);
182
183 /* step 3. for i from n down to (t + 1) */
184 for (i = n; i >= (t + 1); i--) {
185 if (i > x.used) {
186 continue;
187 }
188
189 /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
190 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
191 if (x.dp[i] == y.dp[t]) {
192 q.dp[(i - t) - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
193 } else {
194 mp_word tmp;
195 tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
196 tmp |= ((mp_word) x.dp[i - 1]);
197 tmp /= ((mp_word) y.dp[t]);
198 if (tmp > (mp_word) MP_MASK) {
199 tmp = MP_MASK;
200 }
201 q.dp[(i - t) - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
202 }
203
204 /* while (q{i-t-1} * (yt * b + y{t-1})) >
205 xi * b**2 + xi-1 * b + xi-2
206
207 do q{i-t-1} -= 1;
171 }
172
173 while (mp_cmp(&x, &y) != MP_LT) {
174 ++(q.dp[n - t]);
175 if ((res = mp_sub(&x, &y, &x)) != MP_OKAY) {
176 goto LBL_Y;
177 }
178 }
179
180 /* reset y by shifting it back down */
181 mp_rshd(&y, n - t);
182
183 /* step 3. for i from n down to (t + 1) */
184 for (i = n; i >= (t + 1); i--) {
185 if (i > x.used) {
186 continue;
187 }
188
189 /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
190 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
191 if (x.dp[i] == y.dp[t]) {
192 q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)DIGIT_BIT) - (mp_digit)1;
193 } else {
194 mp_word tmp;
195 tmp = (mp_word)x.dp[i] << (mp_word)DIGIT_BIT;
196 tmp |= (mp_word)x.dp[i - 1];
197 tmp /= (mp_word)y.dp[t];
198 if (tmp > (mp_word)MP_MASK) {
199 tmp = MP_MASK;
200 }
201 q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)MP_MASK);
202 }
203
204 /* while (q{i-t-1} * (yt * b + y{t-1})) >
205 xi * b**2 + xi-1 * b + xi-2
206
207 do q{i-t-1} -= 1;
208 */
209 q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1uL) & (mp_digit)MP_MASK;
210 do {
211 q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & (mp_digit)MP_MASK;
212
213 /* find left hand */
214 mp_zero(&t1);
215 t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1];
216 t1.dp[1] = y.dp[t];
217 t1.used = 2;
218 if ((res = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
219 goto LBL_Y;
220 }
221
222 /* find right hand */
223 t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2];
224 t2.dp[1] = ((i - 1) < 0) ? 0u : x.dp[i - 1];
225 t2.dp[2] = x.dp[i];
226 t2.used = 3;
227 } while (mp_cmp_mag(&t1, &t2) == MP_GT);
228
229 /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
230 if ((res = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
231 goto LBL_Y;
232 }
233
234 if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
235 goto LBL_Y;
236 }
237
238 if ((res = mp_sub(&x, &t1, &x)) != MP_OKAY) {
239 goto LBL_Y;
240 }
241
242 /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
243 if (x.sign == MP_NEG) {
244 if ((res = mp_copy(&y, &t1)) != MP_OKAY) {
245 goto LBL_Y;
246 }
247 if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
248 goto LBL_Y;
249 }
250 if ((res = mp_add(&x, &t1, &x)) != MP_OKAY) {
251 goto LBL_Y;
252 }
253
254 q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK;
255 }
256 }
257
258 /* now q is the quotient and x is the remainder
259 * [which we have to normalize]
208260 */
209 q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1) & MP_MASK;
210 do {
211 q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1) & MP_MASK;
212
213 /* find left hand */
214 mp_zero (&t1);
215 t1.dp[0] = ((t - 1) < 0) ? 0 : y.dp[t - 1];
216 t1.dp[1] = y.dp[t];
217 t1.used = 2;
218 if ((res = mp_mul_d (&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
219 goto LBL_Y;
220 }
221
222 /* find right hand */
223 t2.dp[0] = ((i - 2) < 0) ? 0 : x.dp[i - 2];
224 t2.dp[1] = ((i - 1) < 0) ? 0 : x.dp[i - 1];
225 t2.dp[2] = x.dp[i];
226 t2.used = 3;
227 } while (mp_cmp_mag(&t1, &t2) == MP_GT);
228
229 /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
230 if ((res = mp_mul_d (&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
231 goto LBL_Y;
232 }
233
234 if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) {
235 goto LBL_Y;
236 }
237
238 if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
239 goto LBL_Y;
240 }
241
242 /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
243 if (x.sign == MP_NEG) {
244 if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
245 goto LBL_Y;
246 }
247 if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) {
248 goto LBL_Y;
249 }
250 if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
251 goto LBL_Y;
252 }
253
254 q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1UL) & MP_MASK;
255 }
256 }
257
258 /* now q is the quotient and x is the remainder
259 * [which we have to normalize]
260 */
261
262 /* get sign before writing to c */
263 x.sign = (x.used == 0) ? MP_ZPOS : a->sign;
264
265 if (c != NULL) {
266 mp_clamp (&q);
267 mp_exch (&q, c);
268 c->sign = neg;
269 }
270
271 if (d != NULL) {
272 if ((res = mp_div_2d (&x, norm, &x, NULL)) != MP_OKAY) {
273 goto LBL_Y;
274 }
275 mp_exch (&x, d);
276 }
277
278 res = MP_OKAY;
279
280 LBL_Y:mp_clear (&y);
281 LBL_X:mp_clear (&x);
282 LBL_T2:mp_clear (&t2);
283 LBL_T1:mp_clear (&t1);
284 LBL_Q:mp_clear (&q);
285 return res;
261
262 /* get sign before writing to c */
263 x.sign = (x.used == 0) ? MP_ZPOS : a->sign;
264
265 if (c != NULL) {
266 mp_clamp(&q);
267 mp_exch(&q, c);
268 c->sign = neg;
269 }
270
271 if (d != NULL) {
272 if ((res = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) {
273 goto LBL_Y;
274 }
275 mp_exch(&x, d);
276 }
277
278 res = MP_OKAY;
279
280 LBL_Y:
281 mp_clear(&y);
282 LBL_X:
283 mp_clear(&x);
284 LBL_T2:
285 mp_clear(&t2);
286 LBL_T1:
287 mp_clear(&t1);
288 LBL_Q:
289 mp_clear(&q);
290 return res;
286291 }
287292
288293 #endif
289294
290295 #endif
291296
292 /* $Source$ */
293 /* $Revision$ */
294 /* $Date$ */
297 /* ref: $Format:%D$ */
298 /* git commit: $Format:%H$ */
299 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* b = a/2 */
18 int mp_div_2(mp_int * a, mp_int * b)
18 int mp_div_2(const mp_int *a, mp_int *b)
1919 {
20 int x, res, oldused;
20 int x, res, oldused;
2121
22 /* copy */
23 if (b->alloc < a->used) {
24 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
25 return res;
26 }
27 }
22 /* copy */
23 if (b->alloc < a->used) {
24 if ((res = mp_grow(b, a->used)) != MP_OKAY) {
25 return res;
26 }
27 }
2828
29 oldused = b->used;
30 b->used = a->used;
31 {
32 mp_digit r, rr, *tmpa, *tmpb;
29 oldused = b->used;
30 b->used = a->used;
31 {
32 mp_digit r, rr, *tmpa, *tmpb;
3333
34 /* source alias */
35 tmpa = a->dp + b->used - 1;
34 /* source alias */
35 tmpa = a->dp + b->used - 1;
3636
37 /* dest alias */
38 tmpb = b->dp + b->used - 1;
37 /* dest alias */
38 tmpb = b->dp + b->used - 1;
3939
40 /* carry */
41 r = 0;
42 for (x = b->used - 1; x >= 0; x--) {
43 /* get the carry for the next iteration */
44 rr = *tmpa & 1;
40 /* carry */
41 r = 0;
42 for (x = b->used - 1; x >= 0; x--) {
43 /* get the carry for the next iteration */
44 rr = *tmpa & 1u;
4545
46 /* shift the current digit, add in carry and store */
47 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
46 /* shift the current digit, add in carry and store */
47 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
4848
49 /* forward carry to next iteration */
50 r = rr;
51 }
49 /* forward carry to next iteration */
50 r = rr;
51 }
5252
53 /* zero excess digits */
54 tmpb = b->dp + b->used;
55 for (x = b->used; x < oldused; x++) {
56 *tmpb++ = 0;
57 }
58 }
59 b->sign = a->sign;
60 mp_clamp (b);
61 return MP_OKAY;
53 /* zero excess digits */
54 tmpb = b->dp + b->used;
55 for (x = b->used; x < oldused; x++) {
56 *tmpb++ = 0;
57 }
58 }
59 b->sign = a->sign;
60 mp_clamp(b);
61 return MP_OKAY;
6262 }
6363 #endif
6464
65 /* $Source$ */
66 /* $Revision$ */
67 /* $Date$ */
65 /* ref: $Format:%D$ */
66 /* git commit: $Format:%H$ */
67 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
18 int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
18 int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
1919 {
20 mp_digit D, r, rr;
21 int x, res;
22 mp_int t;
20 mp_digit D, r, rr;
21 int x, res;
2322
23 /* if the shift count is <= 0 then we do no work */
24 if (b <= 0) {
25 res = mp_copy(a, c);
26 if (d != NULL) {
27 mp_zero(d);
28 }
29 return res;
30 }
2431
25 /* if the shift count is <= 0 then we do no work */
26 if (b <= 0) {
27 res = mp_copy (a, c);
28 if (d != NULL) {
29 mp_zero (d);
30 }
31 return res;
32 }
32 /* copy */
33 if ((res = mp_copy(a, c)) != MP_OKAY) {
34 return res;
35 }
36 /* 'a' should not be used after here - it might be the same as d */
3337
34 if ((res = mp_init (&t)) != MP_OKAY) {
35 return res;
36 }
38 /* get the remainder */
39 if (d != NULL) {
40 if ((res = mp_mod_2d(a, b, d)) != MP_OKAY) {
41 return res;
42 }
43 }
3744
38 /* get the remainder */
39 if (d != NULL) {
40 if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
41 mp_clear (&t);
42 return res;
43 }
44 }
45 /* shift by as many digits in the bit count */
46 if (b >= DIGIT_BIT) {
47 mp_rshd(c, b / DIGIT_BIT);
48 }
4549
46 /* copy */
47 if ((res = mp_copy (a, c)) != MP_OKAY) {
48 mp_clear (&t);
49 return res;
50 }
50 /* shift any bit count < DIGIT_BIT */
51 D = (mp_digit)(b % DIGIT_BIT);
52 if (D != 0u) {
53 mp_digit *tmpc, mask, shift;
5154
52 /* shift by as many digits in the bit count */
53 if (b >= (int)DIGIT_BIT) {
54 mp_rshd (c, b / DIGIT_BIT);
55 }
55 /* mask */
56 mask = ((mp_digit)1 << D) - 1uL;
5657
57 /* shift any bit count < DIGIT_BIT */
58 D = (mp_digit) (b % DIGIT_BIT);
59 if (D != 0) {
60 mp_digit *tmpc, mask, shift;
58 /* shift for lsb */
59 shift = (mp_digit)DIGIT_BIT - D;
6160
62 /* mask */
63 mask = (((mp_digit)1) << D) - 1;
61 /* alias */
62 tmpc = c->dp + (c->used - 1);
6463
65 /* shift for lsb */
66 shift = DIGIT_BIT - D;
64 /* carry */
65 r = 0;
66 for (x = c->used - 1; x >= 0; x--) {
67 /* get the lower bits of this word in a temp */
68 rr = *tmpc & mask;
6769
68 /* alias */
69 tmpc = c->dp + (c->used - 1);
70 /* shift the current word and mix in the carry bits from the previous word */
71 *tmpc = (*tmpc >> D) | (r << shift);
72 --tmpc;
7073
71 /* carry */
72 r = 0;
73 for (x = c->used - 1; x >= 0; x--) {
74 /* get the lower bits of this word in a temp */
75 rr = *tmpc & mask;
76
77 /* shift the current word and mix in the carry bits from the previous word */
78 *tmpc = (*tmpc >> D) | (r << shift);
79 --tmpc;
80
81 /* set the carry to the carry bits of the current word found above */
82 r = rr;
83 }
84 }
85 mp_clamp (c);
86 if (d != NULL) {
87 mp_exch (&t, d);
88 }
89 mp_clear (&t);
90 return MP_OKAY;
74 /* set the carry to the carry bits of the current word found above */
75 r = rr;
76 }
77 }
78 mp_clamp(c);
79 return MP_OKAY;
9180 }
9281 #endif
9382
94 /* $Source$ */
95 /* $Revision$ */
96 /* $Date$ */
83 /* ref: $Format:%D$ */
84 /* git commit: $Format:%H$ */
85 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* divide by three (based on routine from MPI and the GMP manual) */
18 int
19 mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
18 int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d)
2019 {
21 mp_int q;
22 mp_word w, t;
23 mp_digit b;
24 int res, ix;
25
26 /* b = 2**DIGIT_BIT / 3 */
27 b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
20 mp_int q;
21 mp_word w, t;
22 mp_digit b;
23 int res, ix;
2824
29 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
30 return res;
31 }
32
33 q.used = a->used;
34 q.sign = a->sign;
35 w = 0;
36 for (ix = a->used - 1; ix >= 0; ix--) {
37 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
25 /* b = 2**DIGIT_BIT / 3 */
26 b = ((mp_word)1 << (mp_word)DIGIT_BIT) / (mp_word)3;
3827
39 if (w >= 3) {
40 /* multiply w by [1/3] */
41 t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
28 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
29 return res;
30 }
4231
43 /* now subtract 3 * [w/3] from w, to get the remainder */
44 w -= t+t+t;
32 q.used = a->used;
33 q.sign = a->sign;
34 w = 0;
35 for (ix = a->used - 1; ix >= 0; ix--) {
36 w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix];
4537
46 /* fixup the remainder as required since
47 * the optimization is not exact.
48 */
49 while (w >= 3) {
50 t += 1;
51 w -= 3;
52 }
38 if (w >= 3u) {
39 /* multiply w by [1/3] */
40 t = (w * (mp_word)b) >> (mp_word)DIGIT_BIT;
41
42 /* now subtract 3 * [w/3] from w, to get the remainder */
43 w -= t+t+t;
44
45 /* fixup the remainder as required since
46 * the optimization is not exact.
47 */
48 while (w >= 3u) {
49 t += 1u;
50 w -= 3u;
51 }
5352 } else {
54 t = 0;
53 t = 0;
5554 }
5655 q.dp[ix] = (mp_digit)t;
57 }
56 }
5857
59 /* [optional] store the remainder */
60 if (d != NULL) {
61 *d = (mp_digit)w;
62 }
58 /* [optional] store the remainder */
59 if (d != NULL) {
60 *d = (mp_digit)w;
61 }
6362
64 /* [optional] store the quotient */
65 if (c != NULL) {
66 mp_clamp(&q);
67 mp_exch(&q, c);
68 }
69 mp_clear(&q);
70
71 return res;
63 /* [optional] store the quotient */
64 if (c != NULL) {
65 mp_clamp(&q);
66 mp_exch(&q, c);
67 }
68 mp_clear(&q);
69
70 return res;
7271 }
7372
7473 #endif
7574
76 /* $Source$ */
77 /* $Revision$ */
78 /* $Date$ */
75 /* ref: $Format:%D$ */
76 /* git commit: $Format:%H$ */
77 /* commit time: $Format:%ai$ */
1919 int x;
2020
2121 /* fast return if no power of two */
22 if ((b == 0) || ((b & (b-1)) != 0)) {
22 if ((b == 0u) || ((b & (b-1u)) != 0u)) {
2323 return 0;
2424 }
2525
2626 for (x = 0; x < DIGIT_BIT; x++) {
27 if (b == (((mp_digit)1)<<x)) {
27 if (b == ((mp_digit)1<<(mp_digit)x)) {
2828 *p = x;
2929 return 1;
3030 }
3333 }
3434
3535 /* single digit division (based on routine from MPI) */
36 int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
36 int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d)
3737 {
38 mp_int q;
39 mp_word w;
40 mp_digit t;
41 int res, ix;
38 mp_int q;
39 mp_word w;
40 mp_digit t;
41 int res, ix;
4242
43 /* cannot divide by zero */
44 if (b == 0) {
45 return MP_VAL;
46 }
43 /* cannot divide by zero */
44 if (b == 0u) {
45 return MP_VAL;
46 }
4747
48 /* quick outs */
49 if ((b == 1) || (mp_iszero(a) == MP_YES)) {
50 if (d != NULL) {
51 *d = 0;
52 }
53 if (c != NULL) {
54 return mp_copy(a, c);
55 }
56 return MP_OKAY;
57 }
48 /* quick outs */
49 if ((b == 1u) || (mp_iszero(a) == MP_YES)) {
50 if (d != NULL) {
51 *d = 0;
52 }
53 if (c != NULL) {
54 return mp_copy(a, c);
55 }
56 return MP_OKAY;
57 }
5858
59 /* power of two ? */
60 if (s_is_power_of_two(b, &ix) == 1) {
61 if (d != NULL) {
62 *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
63 }
64 if (c != NULL) {
65 return mp_div_2d(a, ix, c, NULL);
66 }
67 return MP_OKAY;
68 }
59 /* power of two ? */
60 if (s_is_power_of_two(b, &ix) == 1) {
61 if (d != NULL) {
62 *d = a->dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL);
63 }
64 if (c != NULL) {
65 return mp_div_2d(a, ix, c, NULL);
66 }
67 return MP_OKAY;
68 }
6969
7070 #ifdef BN_MP_DIV_3_C
71 /* three? */
72 if (b == 3) {
73 return mp_div_3(a, c, d);
74 }
71 /* three? */
72 if (b == 3u) {
73 return mp_div_3(a, c, d);
74 }
7575 #endif
7676
77 /* no easy answer [c'est la vie]. Just division */
78 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
79 return res;
80 }
81
82 q.used = a->used;
83 q.sign = a->sign;
84 w = 0;
85 for (ix = a->used - 1; ix >= 0; ix--) {
86 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
87
88 if (w >= b) {
89 t = (mp_digit)(w / b);
90 w -= ((mp_word)t) * ((mp_word)b);
77 /* no easy answer [c'est la vie]. Just division */
78 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
79 return res;
80 }
81
82 q.used = a->used;
83 q.sign = a->sign;
84 w = 0;
85 for (ix = a->used - 1; ix >= 0; ix--) {
86 w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix];
87
88 if (w >= b) {
89 t = (mp_digit)(w / b);
90 w -= (mp_word)t * (mp_word)b;
9191 } else {
92 t = 0;
92 t = 0;
9393 }
94 q.dp[ix] = (mp_digit)t;
95 }
96
97 if (d != NULL) {
98 *d = (mp_digit)w;
99 }
100
101 if (c != NULL) {
102 mp_clamp(&q);
103 mp_exch(&q, c);
104 }
105 mp_clear(&q);
106
107 return res;
94 q.dp[ix] = t;
95 }
96
97 if (d != NULL) {
98 *d = (mp_digit)w;
99 }
100
101 if (c != NULL) {
102 mp_clamp(&q);
103 mp_exch(&q, c);
104 }
105 mp_clear(&q);
106
107 return res;
108108 }
109109
110110 #endif
111111
112 /* $Source$ */
113 /* $Revision$ */
114 /* $Date$ */
112 /* ref: $Format:%D$ */
113 /* git commit: $Format:%H$ */
114 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* determines if a number is a valid DR modulus */
18 int mp_dr_is_modulus(mp_int *a)
18 int mp_dr_is_modulus(const mp_int *a)
1919 {
2020 int ix;
2121
2828 * but the first digit must be equal to -1 (mod b).
2929 */
3030 for (ix = 1; ix < a->used; ix++) {
31 if (a->dp[ix] != MP_MASK) {
32 return 0;
33 }
31 if (a->dp[ix] != MP_MASK) {
32 return 0;
33 }
3434 }
3535 return 1;
3636 }
3737
3838 #endif
3939
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
40 /* ref: $Format:%D$ */
41 /* git commit: $Format:%H$ */
42 /* commit time: $Format:%ai$ */
2828 *
2929 * Input x must be in the range 0 <= x <= (n-1)**2
3030 */
31 int
32 mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
31 int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k)
3332 {
34 int err, i, m;
35 mp_word r;
36 mp_digit mu, *tmpx1, *tmpx2;
33 int err, i, m;
34 mp_word r;
35 mp_digit mu, *tmpx1, *tmpx2;
3736
38 /* m = digits in modulus */
39 m = n->used;
37 /* m = digits in modulus */
38 m = n->used;
4039
41 /* ensure that "x" has at least 2m digits */
42 if (x->alloc < (m + m)) {
43 if ((err = mp_grow (x, m + m)) != MP_OKAY) {
44 return err;
45 }
46 }
40 /* ensure that "x" has at least 2m digits */
41 if (x->alloc < (m + m)) {
42 if ((err = mp_grow(x, m + m)) != MP_OKAY) {
43 return err;
44 }
45 }
4746
48 /* top of loop, this is where the code resumes if
49 * another reduction pass is required.
50 */
47 /* top of loop, this is where the code resumes if
48 * another reduction pass is required.
49 */
5150 top:
52 /* aliases for digits */
53 /* alias for lower half of x */
54 tmpx1 = x->dp;
51 /* aliases for digits */
52 /* alias for lower half of x */
53 tmpx1 = x->dp;
5554
56 /* alias for upper half of x, or x/B**m */
57 tmpx2 = x->dp + m;
55 /* alias for upper half of x, or x/B**m */
56 tmpx2 = x->dp + m;
5857
59 /* set carry to zero */
60 mu = 0;
58 /* set carry to zero */
59 mu = 0;
6160
62 /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
63 for (i = 0; i < m; i++) {
64 r = (((mp_word)*tmpx2++) * (mp_word)k) + *tmpx1 + mu;
61 /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
62 for (i = 0; i < m; i++) {
63 r = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu;
6564 *tmpx1++ = (mp_digit)(r & MP_MASK);
6665 mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
67 }
66 }
6867
69 /* set final carry */
70 *tmpx1++ = mu;
68 /* set final carry */
69 *tmpx1++ = mu;
7170
72 /* zero words above m */
73 for (i = m + 1; i < x->used; i++) {
71 /* zero words above m */
72 for (i = m + 1; i < x->used; i++) {
7473 *tmpx1++ = 0;
75 }
74 }
7675
77 /* clamp, sub and return */
78 mp_clamp (x);
76 /* clamp, sub and return */
77 mp_clamp(x);
7978
80 /* if x >= n then subtract and reduce again
81 * Each successive "recursion" makes the input smaller and smaller.
82 */
83 if (mp_cmp_mag (x, n) != MP_LT) {
84 if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
85 return err;
86 }
87 goto top;
88 }
89 return MP_OKAY;
79 /* if x >= n then subtract and reduce again
80 * Each successive "recursion" makes the input smaller and smaller.
81 */
82 if (mp_cmp_mag(x, n) != MP_LT) {
83 if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
84 return err;
85 }
86 goto top;
87 }
88 return MP_OKAY;
9089 }
9190 #endif
9291
93 /* $Source$ */
94 /* $Revision$ */
95 /* $Date$ */
92 /* ref: $Format:%D$ */
93 /* git commit: $Format:%H$ */
94 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* determines the setup value */
18 void mp_dr_setup(mp_int *a, mp_digit *d)
18 void mp_dr_setup(const mp_int *a, mp_digit *d)
1919 {
2020 /* the casts are required if DIGIT_BIT is one less than
2121 * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
2222 */
23 *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
24 ((mp_word)a->dp[0]));
23 *d = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - (mp_word)a->dp[0]);
2524 }
2625
2726 #endif
2827
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
28 /* ref: $Format:%D$ */
29 /* git commit: $Format:%H$ */
30 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* swap the elements of two integers, for cases where you can't simply swap the
17 /* swap the elements of two integers, for cases where you can't simply swap the
1818 * mp_int pointers around
1919 */
20 void
21 mp_exch (mp_int * a, mp_int * b)
20 void mp_exch(mp_int *a, mp_int *b)
2221 {
23 mp_int t;
22 mp_int t;
2423
25 t = *a;
26 *a = *b;
27 *b = t;
24 t = *a;
25 *a = *b;
26 *b = t;
2827 }
2928 #endif
3029
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
30 /* ref: $Format:%D$ */
31 /* git commit: $Format:%H$ */
32 /* commit time: $Format:%ai$ */
1717 /* based on gmp's mpz_export.
1818 * see http://gmplib.org/manual/Integer-Import-and-Export.html
1919 */
20 int mp_export(void* rop, size_t* countp, int order, size_t size,
21 int endian, size_t nails, mp_int* op) {
22 int result;
23 size_t odd_nails, nail_bytes, i, j, bits, count;
24 unsigned char odd_nail_mask;
20 int mp_export(void *rop, size_t *countp, int order, size_t size,
21 int endian, size_t nails, const mp_int *op)
22 {
23 int result;
24 size_t odd_nails, nail_bytes, i, j, bits, count;
25 unsigned char odd_nail_mask;
2526
26 mp_int t;
27 mp_int t;
2728
28 if ((result = mp_init_copy(&t, op)) != MP_OKAY) {
29 return result;
30 }
29 if ((result = mp_init_copy(&t, op)) != MP_OKAY) {
30 return result;
31 }
3132
32 if (endian == 0) {
33 union {
34 unsigned int i;
35 char c[4];
36 } lint;
37 lint.i = 0x01020304;
38
39 endian = (lint.c[0] == 4) ? -1 : 1;
40 }
33 if (endian == 0) {
34 union {
35 unsigned int i;
36 char c[4];
37 } lint;
38 lint.i = 0x01020304;
4139
42 odd_nails = (nails % 8);
43 odd_nail_mask = 0xff;
44 for (i = 0; i < odd_nails; ++i) {
45 odd_nail_mask ^= (1 << (7 - i));
46 }
47 nail_bytes = nails / 8;
40 endian = (lint.c[0] == '\x04') ? -1 : 1;
41 }
4842
49 bits = mp_count_bits(&t);
50 count = (bits / ((size * 8) - nails)) + (((bits % ((size * 8) - nails)) != 0) ? 1 : 0);
43 odd_nails = (nails % 8u);
44 odd_nail_mask = 0xff;
45 for (i = 0; i < odd_nails; ++i) {
46 odd_nail_mask ^= (unsigned char)(1u << (7u - i));
47 }
48 nail_bytes = nails / 8u;
5149
52 for (i = 0; i < count; ++i) {
53 for (j = 0; j < size; ++j) {
54 unsigned char* byte = (
55 (unsigned char*)rop +
56 (((order == -1) ? i : ((count - 1) - i)) * size) +
57 ((endian == -1) ? j : ((size - 1) - j))
58 );
50 bits = (size_t)mp_count_bits(&t);
51 count = (bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u);
5952
60 if (j >= (size - nail_bytes)) {
61 *byte = 0;
62 continue;
63 }
53 for (i = 0; i < count; ++i) {
54 for (j = 0; j < size; ++j) {
55 unsigned char *byte = (unsigned char *)rop +
56 (((order == -1) ? i : ((count - 1u) - i)) * size) +
57 ((endian == -1) ? j : ((size - 1u) - j));
6458
65 *byte = (unsigned char)((j == ((size - nail_bytes) - 1)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFF));
59 if (j >= (size - nail_bytes)) {
60 *byte = 0;
61 continue;
62 }
6663
67 if ((result = mp_div_2d(&t, (int)((j == ((size - nail_bytes) - 1)) ? (8 - odd_nails) : 8), &t, NULL)) != MP_OKAY) {
68 mp_clear(&t);
69 return result;
70 }
71 }
72 }
64 *byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL));
7365
74 mp_clear(&t);
66 if ((result = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) {
67 mp_clear(&t);
68 return result;
69 }
70 }
71 }
7572
76 if (countp != NULL) {
77 *countp = count;
78 }
73 mp_clear(&t);
7974
80 return MP_OKAY;
75 if (countp != NULL) {
76 *countp = count;
77 }
78
79 return MP_OKAY;
8180 }
8281
8382 #endif
8483
85 /* $Source$ */
86 /* $Revision$ */
87 /* $Date$ */
84 /* ref: $Format:%D$ */
85 /* git commit: $Format:%H$ */
86 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* wrapper function for mp_expt_d_ex() */
18 int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
18 int mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
1919 {
20 return mp_expt_d_ex(a, b, c, 0);
20 return mp_expt_d_ex(a, b, c, 0);
2121 }
2222
2323 #endif
2424
25 /* $Source$ */
26 /* $Revision$ */
27 /* $Date$ */
25 /* ref: $Format:%D$ */
26 /* git commit: $Format:%H$ */
27 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* calculate c = a**b using a square-multiply algorithm */
18 int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast)
18 int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
1919 {
20 int res;
21 unsigned int x;
20 int res;
21 unsigned int x;
2222
23 mp_int g;
23 mp_int g;
2424
25 if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
26 return res;
27 }
25 if ((res = mp_init_copy(&g, a)) != MP_OKAY) {
26 return res;
27 }
2828
29 /* set initial result */
30 mp_set (c, 1);
29 /* set initial result */
30 mp_set(c, 1uL);
3131
32 if (fast != 0) {
33 while (b > 0) {
34 /* if the bit is set multiply */
35 if ((b & 1) != 0) {
36 if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
37 mp_clear (&g);
38 return res;
39 }
32 if (fast != 0) {
33 while (b > 0u) {
34 /* if the bit is set multiply */
35 if ((b & 1u) != 0u) {
36 if ((res = mp_mul(c, &g, c)) != MP_OKAY) {
37 mp_clear(&g);
38 return res;
39 }
40 }
41
42 /* square */
43 if (b > 1u) {
44 if ((res = mp_sqr(&g, &g)) != MP_OKAY) {
45 mp_clear(&g);
46 return res;
47 }
48 }
49
50 /* shift to next bit */
51 b >>= 1;
4052 }
53 } else {
54 for (x = 0; x < (unsigned)DIGIT_BIT; x++) {
55 /* square */
56 if ((res = mp_sqr(c, c)) != MP_OKAY) {
57 mp_clear(&g);
58 return res;
59 }
4160
42 /* square */
43 if (b > 1) {
44 if ((res = mp_sqr (&g, &g)) != MP_OKAY) {
45 mp_clear (&g);
46 return res;
47 }
61 /* if the bit is set multiply */
62 if ((b & ((mp_digit)1 << (DIGIT_BIT - 1))) != 0u) {
63 if ((res = mp_mul(c, &g, c)) != MP_OKAY) {
64 mp_clear(&g);
65 return res;
66 }
67 }
68
69 /* shift to next bit */
70 b <<= 1;
4871 }
72 } /* if ... else */
4973
50 /* shift to next bit */
51 b >>= 1;
52 }
53 }
54 else {
55 for (x = 0; x < DIGIT_BIT; x++) {
56 /* square */
57 if ((res = mp_sqr (c, c)) != MP_OKAY) {
58 mp_clear (&g);
59 return res;
60 }
61
62 /* if the bit is set multiply */
63 if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
64 if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
65 mp_clear (&g);
66 return res;
67 }
68 }
69
70 /* shift to next bit */
71 b <<= 1;
72 }
73 } /* if ... else */
74
75 mp_clear (&g);
76 return MP_OKAY;
74 mp_clear(&g);
75 return MP_OKAY;
7776 }
7877 #endif
7978
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
79 /* ref: $Format:%D$ */
80 /* git commit: $Format:%H$ */
81 /* commit time: $Format:%ai$ */
2020 * embedded in the normal function but that wasted alot of stack space
2121 * for nothing (since 99% of the time the Montgomery code would be called)
2222 */
23 int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
23 int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)
2424 {
25 int dr;
25 int dr;
2626
27 /* modulus P must be positive */
28 if (P->sign == MP_NEG) {
29 return MP_VAL;
30 }
27 /* modulus P must be positive */
28 if (P->sign == MP_NEG) {
29 return MP_VAL;
30 }
3131
32 /* if exponent X is negative we have to recurse */
33 if (X->sign == MP_NEG) {
32 /* if exponent X is negative we have to recurse */
33 if (X->sign == MP_NEG) {
3434 #ifdef BN_MP_INVMOD_C
35 mp_int tmpG, tmpX;
36 int err;
35 mp_int tmpG, tmpX;
36 int err;
3737
38 /* first compute 1/G mod P */
39 if ((err = mp_init(&tmpG)) != MP_OKAY) {
40 return err;
41 }
42 if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
43 mp_clear(&tmpG);
44 return err;
45 }
38 /* first compute 1/G mod P */
39 if ((err = mp_init(&tmpG)) != MP_OKAY) {
40 return err;
41 }
42 if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
43 mp_clear(&tmpG);
44 return err;
45 }
4646
47 /* now get |X| */
48 if ((err = mp_init(&tmpX)) != MP_OKAY) {
49 mp_clear(&tmpG);
50 return err;
51 }
52 if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
53 mp_clear_multi(&tmpG, &tmpX, NULL);
54 return err;
55 }
47 /* now get |X| */
48 if ((err = mp_init(&tmpX)) != MP_OKAY) {
49 mp_clear(&tmpG);
50 return err;
51 }
52 if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
53 mp_clear_multi(&tmpG, &tmpX, NULL);
54 return err;
55 }
5656
57 /* and now compute (1/G)**|X| instead of G**X [X < 0] */
58 err = mp_exptmod(&tmpG, &tmpX, P, Y);
59 mp_clear_multi(&tmpG, &tmpX, NULL);
60 return err;
61 #else
62 /* no invmod */
63 return MP_VAL;
57 /* and now compute (1/G)**|X| instead of G**X [X < 0] */
58 err = mp_exptmod(&tmpG, &tmpX, P, Y);
59 mp_clear_multi(&tmpG, &tmpX, NULL);
60 return err;
61 #else
62 /* no invmod */
63 return MP_VAL;
6464 #endif
65 }
65 }
6666
67 /* modified diminished radix reduction */
67 /* modified diminished radix reduction */
6868 #if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
69 if (mp_reduce_is_2k_l(P) == MP_YES) {
70 return s_mp_exptmod(G, X, P, Y, 1);
71 }
69 if (mp_reduce_is_2k_l(P) == MP_YES) {
70 return s_mp_exptmod(G, X, P, Y, 1);
71 }
7272 #endif
7373
7474 #ifdef BN_MP_DR_IS_MODULUS_C
75 /* is it a DR modulus? */
76 dr = mp_dr_is_modulus(P);
75 /* is it a DR modulus? */
76 dr = mp_dr_is_modulus(P);
7777 #else
78 /* default to no */
79 dr = 0;
78 /* default to no */
79 dr = 0;
8080 #endif
8181
8282 #ifdef BN_MP_REDUCE_IS_2K_C
83 /* if not, is it a unrestricted DR modulus? */
84 if (dr == 0) {
85 dr = mp_reduce_is_2k(P) << 1;
86 }
83 /* if not, is it a unrestricted DR modulus? */
84 if (dr == 0) {
85 dr = mp_reduce_is_2k(P) << 1;
86 }
8787 #endif
88
89 /* if the modulus is odd or dr != 0 use the montgomery method */
88
89 /* if the modulus is odd or dr != 0 use the montgomery method */
9090 #ifdef BN_MP_EXPTMOD_FAST_C
91 if ((mp_isodd (P) == MP_YES) || (dr != 0)) {
92 return mp_exptmod_fast (G, X, P, Y, dr);
93 } else {
91 if ((mp_isodd(P) == MP_YES) || (dr != 0)) {
92 return mp_exptmod_fast(G, X, P, Y, dr);
93 } else {
9494 #endif
9595 #ifdef BN_S_MP_EXPTMOD_C
96 /* otherwise use the generic Barrett reduction technique */
97 return s_mp_exptmod (G, X, P, Y, 0);
96 /* otherwise use the generic Barrett reduction technique */
97 return s_mp_exptmod(G, X, P, Y, 0);
9898 #else
99 /* no exptmod for evens */
100 return MP_VAL;
99 /* no exptmod for evens */
100 return MP_VAL;
101101 #endif
102102 #ifdef BN_MP_EXPTMOD_FAST_C
103 }
103 }
104104 #endif
105105 }
106106
107107 #endif
108108
109 /* $Source$ */
110 /* $Revision$ */
111 /* $Date$ */
109 /* ref: $Format:%D$ */
110 /* git commit: $Format:%H$ */
111 /* commit time: $Format:%ai$ */
2323 */
2424
2525 #ifdef MP_LOW_MEM
26 #define TAB_SIZE 32
27 #else
28 #define TAB_SIZE 256
29 #endif
30
31 int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
26 # define TAB_SIZE 32
27 #else
28 # define TAB_SIZE 256
29 #endif
30
31 int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
3232 {
33 mp_int M[TAB_SIZE], res;
34 mp_digit buf, mp;
35 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
36
37 /* use a pointer to the reduction algorithm. This allows us to use
38 * one of many reduction algorithms without modding the guts of
39 * the code with if statements everywhere.
40 */
41 int (*redux)(mp_int*,mp_int*,mp_digit);
42
43 /* find window size */
44 x = mp_count_bits (X);
45 if (x <= 7) {
46 winsize = 2;
47 } else if (x <= 36) {
48 winsize = 3;
49 } else if (x <= 140) {
50 winsize = 4;
51 } else if (x <= 450) {
52 winsize = 5;
53 } else if (x <= 1303) {
54 winsize = 6;
55 } else if (x <= 3529) {
56 winsize = 7;
57 } else {
58 winsize = 8;
59 }
33 mp_int M[TAB_SIZE], res;
34 mp_digit buf, mp;
35 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
36
37 /* use a pointer to the reduction algorithm. This allows us to use
38 * one of many reduction algorithms without modding the guts of
39 * the code with if statements everywhere.
40 */
41 int (*redux)(mp_int *x, const mp_int *n, mp_digit rho);
42
43 /* find window size */
44 x = mp_count_bits(X);
45 if (x <= 7) {
46 winsize = 2;
47 } else if (x <= 36) {
48 winsize = 3;
49 } else if (x <= 140) {
50 winsize = 4;
51 } else if (x <= 450) {
52 winsize = 5;
53 } else if (x <= 1303) {
54 winsize = 6;
55 } else if (x <= 3529) {
56 winsize = 7;
57 } else {
58 winsize = 8;
59 }
6060
6161 #ifdef MP_LOW_MEM
62 if (winsize > 5) {
63 winsize = 5;
64 }
65 #endif
66
67 /* init M array */
68 /* init first cell */
69 if ((err = mp_init(&M[1])) != MP_OKAY) {
70 return err;
71 }
72
73 /* now init the second half of the array */
74 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
75 if ((err = mp_init(&M[x])) != MP_OKAY) {
76 for (y = 1<<(winsize-1); y < x; y++) {
77 mp_clear (&M[y]);
78 }
79 mp_clear(&M[1]);
62 if (winsize > 5) {
63 winsize = 5;
64 }
65 #endif
66
67 /* init M array */
68 /* init first cell */
69 if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {
8070 return err;
81 }
82 }
83
84 /* determine and setup reduction code */
85 if (redmode == 0) {
86 #ifdef BN_MP_MONTGOMERY_SETUP_C
87 /* now setup montgomery */
88 if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
89 goto LBL_M;
90 }
91 #else
92 err = MP_VAL;
93 goto LBL_M;
94 #endif
95
96 /* automatically pick the comba one if available (saves quite a few calls/ifs) */
71 }
72
73 /* now init the second half of the array */
74 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
75 if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {
76 for (y = 1<<(winsize-1); y < x; y++) {
77 mp_clear(&M[y]);
78 }
79 mp_clear(&M[1]);
80 return err;
81 }
82 }
83
84 /* determine and setup reduction code */
85 if (redmode == 0) {
86 #ifdef BN_MP_MONTGOMERY_SETUP_C
87 /* now setup montgomery */
88 if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {
89 goto LBL_M;
90 }
91 #else
92 err = MP_VAL;
93 goto LBL_M;
94 #endif
95
96 /* automatically pick the comba one if available (saves quite a few calls/ifs) */
9797 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
98 if ((((P->used * 2) + 1) < MP_WARRAY) &&
98 if ((((P->used * 2) + 1) < (int)MP_WARRAY) &&
9999 (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
100 redux = fast_mp_montgomery_reduce;
101 } else
102 #endif
103 {
100 redux = fast_mp_montgomery_reduce;
101 } else
102 #endif
103 {
104104 #ifdef BN_MP_MONTGOMERY_REDUCE_C
105 /* use slower baseline Montgomery method */
106 redux = mp_montgomery_reduce;
107 #else
108 err = MP_VAL;
109 goto LBL_M;
110 #endif
111 }
112 } else if (redmode == 1) {
105 /* use slower baseline Montgomery method */
106 redux = mp_montgomery_reduce;
107 #else
108 err = MP_VAL;
109 goto LBL_M;
110 #endif
111 }
112 } else if (redmode == 1) {
113113 #if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
114 /* setup DR reduction for moduli of the form B**k - b */
115 mp_dr_setup(P, &mp);
116 redux = mp_dr_reduce;
117 #else
118 err = MP_VAL;
119 goto LBL_M;
120 #endif
121 } else {
114 /* setup DR reduction for moduli of the form B**k - b */
115 mp_dr_setup(P, &mp);
116 redux = mp_dr_reduce;
117 #else
118 err = MP_VAL;
119 goto LBL_M;
120 #endif
121 } else {
122122 #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
123 /* setup DR reduction for moduli of the form 2**k - b */
124 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
125 goto LBL_M;
126 }
127 redux = mp_reduce_2k;
128 #else
129 err = MP_VAL;
130 goto LBL_M;
131 #endif
132 }
133
134 /* setup result */
135 if ((err = mp_init (&res)) != MP_OKAY) {
136 goto LBL_M;
137 }
138
139 /* create M table
140 *
141
142 *
143 * The first half of the table is not computed though accept for M[0] and M[1]
144 */
145
146 if (redmode == 0) {
123 /* setup DR reduction for moduli of the form 2**k - b */
124 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
125 goto LBL_M;
126 }
127 redux = mp_reduce_2k;
128 #else
129 err = MP_VAL;
130 goto LBL_M;
131 #endif
132 }
133
134 /* setup result */
135 if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY) {
136 goto LBL_M;
137 }
138
139 /* create M table
140 *
141
142 *
143 * The first half of the table is not computed though accept for M[0] and M[1]
144 */
145
146 if (redmode == 0) {
147147 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
148 /* now we need R mod m */
149 if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
150 goto LBL_RES;
151 }
152 #else
153 err = MP_VAL;
154 goto LBL_RES;
155 #endif
156
157 /* now set M[1] to G * R mod m */
158 if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
159 goto LBL_RES;
160 }
161 } else {
162 mp_set(&res, 1);
163 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
164 goto LBL_RES;
165 }
166 }
167
168 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
169 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
170 goto LBL_RES;
171 }
172
173 for (x = 0; x < (winsize - 1); x++) {
174 if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
148 /* now we need R mod m */
149 if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) {
150 goto LBL_RES;
151 }
152
153 /* now set M[1] to G * R mod m */
154 if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) {
155 goto LBL_RES;
156 }
157 #else
158 err = MP_VAL;
175159 goto LBL_RES;
176 }
177 if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
160 #endif
161 } else {
162 mp_set(&res, 1uL);
163 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
164 goto LBL_RES;
165 }
166 }
167
168 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
169 if ((err = mp_copy(&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
178170 goto LBL_RES;
179 }
180 }
181
182 /* create upper table */
183 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
184 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
185 goto LBL_RES;
186 }
187 if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
188 goto LBL_RES;
189 }
190 }
191
192 /* set initial mode and bit cnt */
193 mode = 0;
194 bitcnt = 1;
195 buf = 0;
196 digidx = X->used - 1;
197 bitcpy = 0;
198 bitbuf = 0;
199
200 for (;;) {
201 /* grab next digit as required */
202 if (--bitcnt == 0) {
203 /* if digidx == -1 we are out of digits so break */
204 if (digidx == -1) {
205 break;
206 }
207 /* read next digit and reset bitcnt */
208 buf = X->dp[digidx--];
209 bitcnt = (int)DIGIT_BIT;
210 }
211
212 /* grab the next msb from the exponent */
213 y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
214 buf <<= (mp_digit)1;
215
216 /* if the bit is zero and mode == 0 then we ignore it
217 * These represent the leading zero bits before the first 1 bit
218 * in the exponent. Technically this opt is not required but it
219 * does lower the # of trivial squaring/reductions used
220 */
221 if ((mode == 0) && (y == 0)) {
222 continue;
223 }
224
225 /* if the bit is zero and mode == 1 then we square */
226 if ((mode == 1) && (y == 0)) {
227 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
228 goto LBL_RES;
229 }
230 if ((err = redux (&res, P, mp)) != MP_OKAY) {
231 goto LBL_RES;
232 }
233 continue;
234 }
235
236 /* else we add it to the window */
237 bitbuf |= (y << (winsize - ++bitcpy));
238 mode = 2;
239
240 if (bitcpy == winsize) {
241 /* ok window is filled so square as required and multiply */
242 /* square first */
243 for (x = 0; x < winsize; x++) {
244 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
245 goto LBL_RES;
246 }
247 if ((err = redux (&res, P, mp)) != MP_OKAY) {
248 goto LBL_RES;
249 }
250 }
251
252 /* then multiply */
253 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
254 goto LBL_RES;
255 }
256 if ((err = redux (&res, P, mp)) != MP_OKAY) {
257 goto LBL_RES;
258 }
259
260 /* empty window and reset */
261 bitcpy = 0;
262 bitbuf = 0;
263 mode = 1;
264 }
265 }
266
267 /* if bits remain then square/multiply */
268 if ((mode == 2) && (bitcpy > 0)) {
269 /* square then multiply if the bit is set */
270 for (x = 0; x < bitcpy; x++) {
271 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
272 goto LBL_RES;
273 }
274 if ((err = redux (&res, P, mp)) != MP_OKAY) {
275 goto LBL_RES;
276 }
277
278 /* get next bit of the window */
279 bitbuf <<= 1;
280 if ((bitbuf & (1 << winsize)) != 0) {
281 /* then multiply */
282 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
283 goto LBL_RES;
284 }
285 if ((err = redux (&res, P, mp)) != MP_OKAY) {
286 goto LBL_RES;
287 }
288 }
289 }
290 }
291
292 if (redmode == 0) {
293 /* fixup result if Montgomery reduction is used
294 * recall that any value in a Montgomery system is
295 * actually multiplied by R mod n. So we have
296 * to reduce one more time to cancel out the factor
297 * of R.
298 */
299 if ((err = redux(&res, P, mp)) != MP_OKAY) {
300 goto LBL_RES;
301 }
302 }
303
304 /* swap res with Y */
305 mp_exch (&res, Y);
306 err = MP_OKAY;
307 LBL_RES:mp_clear (&res);
171 }
172
173 for (x = 0; x < (winsize - 1); x++) {
174 if ((err = mp_sqr(&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
175 goto LBL_RES;
176 }
177 if ((err = redux(&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
178 goto LBL_RES;
179 }
180 }
181
182 /* create upper table */
183 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
184 if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
185 goto LBL_RES;
186 }
187 if ((err = redux(&M[x], P, mp)) != MP_OKAY) {
188 goto LBL_RES;
189 }
190 }
191
192 /* set initial mode and bit cnt */
193 mode = 0;
194 bitcnt = 1;
195 buf = 0;
196 digidx = X->used - 1;
197 bitcpy = 0;
198 bitbuf = 0;
199
200 for (;;) {
201 /* grab next digit as required */
202 if (--bitcnt == 0) {
203 /* if digidx == -1 we are out of digits so break */
204 if (digidx == -1) {
205 break;
206 }
207 /* read next digit and reset bitcnt */
208 buf = X->dp[digidx--];
209 bitcnt = (int)DIGIT_BIT;
210 }
211
212 /* grab the next msb from the exponent */
213 y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
214 buf <<= (mp_digit)1;
215
216 /* if the bit is zero and mode == 0 then we ignore it
217 * These represent the leading zero bits before the first 1 bit
218 * in the exponent. Technically this opt is not required but it
219 * does lower the # of trivial squaring/reductions used
220 */
221 if ((mode == 0) && (y == 0)) {
222 continue;
223 }
224
225 /* if the bit is zero and mode == 1 then we square */
226 if ((mode == 1) && (y == 0)) {
227 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
228 goto LBL_RES;
229 }
230 if ((err = redux(&res, P, mp)) != MP_OKAY) {
231 goto LBL_RES;
232 }
233 continue;
234 }
235
236 /* else we add it to the window */
237 bitbuf |= (y << (winsize - ++bitcpy));
238 mode = 2;
239
240 if (bitcpy == winsize) {
241 /* ok window is filled so square as required and multiply */
242 /* square first */
243 for (x = 0; x < winsize; x++) {
244 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
245 goto LBL_RES;
246 }
247 if ((err = redux(&res, P, mp)) != MP_OKAY) {
248 goto LBL_RES;
249 }
250 }
251
252 /* then multiply */
253 if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) {
254 goto LBL_RES;
255 }
256 if ((err = redux(&res, P, mp)) != MP_OKAY) {
257 goto LBL_RES;
258 }
259
260 /* empty window and reset */
261 bitcpy = 0;
262 bitbuf = 0;
263 mode = 1;
264 }
265 }
266
267 /* if bits remain then square/multiply */
268 if ((mode == 2) && (bitcpy > 0)) {
269 /* square then multiply if the bit is set */
270 for (x = 0; x < bitcpy; x++) {
271 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
272 goto LBL_RES;
273 }
274 if ((err = redux(&res, P, mp)) != MP_OKAY) {
275 goto LBL_RES;
276 }
277
278 /* get next bit of the window */
279 bitbuf <<= 1;
280 if ((bitbuf & (1 << winsize)) != 0) {
281 /* then multiply */
282 if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) {
283 goto LBL_RES;
284 }
285 if ((err = redux(&res, P, mp)) != MP_OKAY) {
286 goto LBL_RES;
287 }
288 }
289 }
290 }
291
292 if (redmode == 0) {
293 /* fixup result if Montgomery reduction is used
294 * recall that any value in a Montgomery system is
295 * actually multiplied by R mod n. So we have
296 * to reduce one more time to cancel out the factor
297 * of R.
298 */
299 if ((err = redux(&res, P, mp)) != MP_OKAY) {
300 goto LBL_RES;
301 }
302 }
303
304 /* swap res with Y */
305 mp_exch(&res, Y);
306 err = MP_OKAY;
307 LBL_RES:
308 mp_clear(&res);
308309 LBL_M:
309 mp_clear(&M[1]);
310 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
311 mp_clear (&M[x]);
312 }
313 return err;
310 mp_clear(&M[1]);
311 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
312 mp_clear(&M[x]);
313 }
314 return err;
314315 }
315316 #endif
316317
317318
318 /* $Source$ */
319 /* $Revision$ */
320 /* $Date$ */
319 /* ref: $Format:%D$ */
320 /* git commit: $Format:%H$ */
321 /* commit time: $Format:%ai$ */
1717 /* Extended euclidean algorithm of (a, b) produces
1818 a*u1 + b*u2 = u3
1919 */
20 int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
20 int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
2121 {
22 mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
22 mp_int u1, u2, u3, v1, v2, v3, t1, t2, t3, q, tmp;
2323 int err;
2424
2525 if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
2727 }
2828
2929 /* initialize, (u1,u2,u3) = (1,0,a) */
30 mp_set(&u1, 1);
31 if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
30 mp_set(&u1, 1uL);
31 if ((err = mp_copy(a, &u3)) != MP_OKAY) {
32 goto LBL_ERR;
33 }
3234
3335 /* initialize, (v1,v2,v3) = (0,1,b) */
34 mp_set(&v2, 1);
35 if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
36 mp_set(&v2, 1uL);
37 if ((err = mp_copy(b, &v3)) != MP_OKAY) {
38 goto LBL_ERR;
39 }
3640
3741 /* loop while v3 != 0 */
3842 while (mp_iszero(&v3) == MP_NO) {
39 /* q = u3/v3 */
40 if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
43 /* q = u3/v3 */
44 if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) {
45 goto LBL_ERR;
46 }
4147
42 /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
43 if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
44 if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
45 if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
46 if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
47 if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
48 if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
48 /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
49 if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) {
56 goto LBL_ERR;
57 }
58 if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) {
59 goto LBL_ERR;
60 }
61 if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) {
62 goto LBL_ERR;
63 }
64 if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) {
65 goto LBL_ERR;
66 }
4967
50 /* (u1,u2,u3) = (v1,v2,v3) */
51 if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
52 if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
53 if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
68 /* (u1,u2,u3) = (v1,v2,v3) */
69 if ((err = mp_copy(&v1, &u1)) != MP_OKAY) {
70 goto LBL_ERR;
71 }
72 if ((err = mp_copy(&v2, &u2)) != MP_OKAY) {
73 goto LBL_ERR;
74 }
75 if ((err = mp_copy(&v3, &u3)) != MP_OKAY) {
76 goto LBL_ERR;
77 }
5478
55 /* (v1,v2,v3) = (t1,t2,t3) */
56 if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
57 if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
58 if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
79 /* (v1,v2,v3) = (t1,t2,t3) */
80 if ((err = mp_copy(&t1, &v1)) != MP_OKAY) {
81 goto LBL_ERR;
82 }
83 if ((err = mp_copy(&t2, &v2)) != MP_OKAY) {
84 goto LBL_ERR;
85 }
86 if ((err = mp_copy(&t3, &v3)) != MP_OKAY) {
87 goto LBL_ERR;
88 }
5989 }
6090
6191 /* make sure U3 >= 0 */
6292 if (u3.sign == MP_NEG) {
63 if ((err = mp_neg(&u1, &u1)) != MP_OKAY) { goto _ERR; }
64 if ((err = mp_neg(&u2, &u2)) != MP_OKAY) { goto _ERR; }
65 if ((err = mp_neg(&u3, &u3)) != MP_OKAY) { goto _ERR; }
93 if ((err = mp_neg(&u1, &u1)) != MP_OKAY) {
94 goto LBL_ERR;
95 }
96 if ((err = mp_neg(&u2, &u2)) != MP_OKAY) {
97 goto LBL_ERR;
98 }
99 if ((err = mp_neg(&u3, &u3)) != MP_OKAY) {
100 goto LBL_ERR;
101 }
66102 }
67103
68104 /* copy result out */
69 if (U1 != NULL) { mp_exch(U1, &u1); }
70 if (U2 != NULL) { mp_exch(U2, &u2); }
71 if (U3 != NULL) { mp_exch(U3, &u3); }
105 if (U1 != NULL) {
106 mp_exch(U1, &u1);
107 }
108 if (U2 != NULL) {
109 mp_exch(U2, &u2);
110 }
111 if (U3 != NULL) {
112 mp_exch(U3, &u3);
113 }
72114
73115 err = MP_OKAY;
74 _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
116 LBL_ERR:
117 mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
75118 return err;
76119 }
77120 #endif
78121
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
122 /* ref: $Format:%D$ */
123 /* git commit: $Format:%H$ */
124 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 #ifndef LTM_NO_FILE
1718 /* read a bigint from a file stream in ASCII */
1819 int mp_fread(mp_int *a, int radix, FILE *stream)
1920 {
2021 int err, ch, neg, y;
21
22 unsigned pos;
23
2224 /* clear a */
2325 mp_zero(a);
24
26
2527 /* if first digit is - then set negative */
2628 ch = fgetc(stream);
27 if (ch == '-') {
29 if (ch == (int)'-') {
2830 neg = MP_NEG;
2931 ch = fgetc(stream);
3032 } else {
3133 neg = MP_ZPOS;
3234 }
33
35
3436 for (;;) {
35 /* find y in the radix map */
36 for (y = 0; y < radix; y++) {
37 if (mp_s_rmap[y] == ch) {
38 break;
39 }
40 }
41 if (y == radix) {
37 pos = (unsigned)(ch - (int)'(');
38 if (mp_s_rmap_reverse_sz < pos) {
4239 break;
4340 }
44
41
42 y = (int)mp_s_rmap_reverse[pos];
43
44 if ((y == 0xff) || (y >= radix)) {
45 break;
46 }
47
4548 /* shift up and add */
46 if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
49 if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
4750 return err;
4851 }
49 if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
52 if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
5053 return err;
5154 }
52
55
5356 ch = fgetc(stream);
5457 }
55 if (mp_cmp_d(a, 0) != MP_EQ) {
58 if (mp_cmp_d(a, 0uL) != MP_EQ) {
5659 a->sign = neg;
5760 }
58
61
5962 return MP_OKAY;
6063 }
64 #endif
6165
6266 #endif
6367
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
68 /* ref: $Format:%D$ */
69 /* git commit: $Format:%H$ */
70 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 int mp_fwrite(mp_int *a, int radix, FILE *stream)
17 #ifndef LTM_NO_FILE
18 int mp_fwrite(const mp_int *a, int radix, FILE *stream)
1819 {
1920 char *buf;
2021 int err, len, x;
21
22
2223 if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
2324 return err;
2425 }
2526
26 buf = OPT_CAST(char) XMALLOC (len);
27 buf = OPT_CAST(char) XMALLOC((size_t)len);
2728 if (buf == NULL) {
2829 return MP_MEM;
2930 }
30
31
3132 if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
32 XFREE (buf);
33 XFREE(buf);
3334 return err;
3435 }
35
36
3637 for (x = 0; x < len; x++) {
37 if (fputc(buf[x], stream) == EOF) {
38 XFREE (buf);
39 return MP_VAL;
40 }
38 if (fputc((int)buf[x], stream) == EOF) {
39 XFREE(buf);
40 return MP_VAL;
41 }
4142 }
42
43 XFREE (buf);
43
44 XFREE(buf);
4445 return MP_OKAY;
4546 }
47 #endif
4648
4749 #endif
4850
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
51 /* ref: $Format:%D$ */
52 /* git commit: $Format:%H$ */
53 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* Greatest Common Divisor using the binary method */
18 int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
18 int mp_gcd(const mp_int *a, const mp_int *b, mp_int *c)
1919 {
20 mp_int u, v;
21 int k, u_lsb, v_lsb, res;
20 mp_int u, v;
21 int k, u_lsb, v_lsb, res;
2222
23 /* either zero than gcd is the largest */
24 if (mp_iszero (a) == MP_YES) {
25 return mp_abs (b, c);
26 }
27 if (mp_iszero (b) == MP_YES) {
28 return mp_abs (a, c);
29 }
23 /* either zero than gcd is the largest */
24 if (mp_iszero(a) == MP_YES) {
25 return mp_abs(b, c);
26 }
27 if (mp_iszero(b) == MP_YES) {
28 return mp_abs(a, c);
29 }
3030
31 /* get copies of a and b we can modify */
32 if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
33 return res;
34 }
31 /* get copies of a and b we can modify */
32 if ((res = mp_init_copy(&u, a)) != MP_OKAY) {
33 return res;
34 }
3535
36 if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
37 goto LBL_U;
38 }
36 if ((res = mp_init_copy(&v, b)) != MP_OKAY) {
37 goto LBL_U;
38 }
3939
40 /* must be positive for the remainder of the algorithm */
41 u.sign = v.sign = MP_ZPOS;
40 /* must be positive for the remainder of the algorithm */
41 u.sign = v.sign = MP_ZPOS;
4242
43 /* B1. Find the common power of two for u and v */
44 u_lsb = mp_cnt_lsb(&u);
45 v_lsb = mp_cnt_lsb(&v);
46 k = MIN(u_lsb, v_lsb);
43 /* B1. Find the common power of two for u and v */
44 u_lsb = mp_cnt_lsb(&u);
45 v_lsb = mp_cnt_lsb(&v);
46 k = MIN(u_lsb, v_lsb);
4747
48 if (k > 0) {
49 /* divide the power of two out */
50 if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
51 goto LBL_V;
52 }
48 if (k > 0) {
49 /* divide the power of two out */
50 if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
51 goto LBL_V;
52 }
5353
54 if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
55 goto LBL_V;
56 }
57 }
54 if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
55 goto LBL_V;
56 }
57 }
5858
59 /* divide any remaining factors of two out */
60 if (u_lsb != k) {
61 if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
62 goto LBL_V;
63 }
64 }
59 /* divide any remaining factors of two out */
60 if (u_lsb != k) {
61 if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
62 goto LBL_V;
63 }
64 }
6565
66 if (v_lsb != k) {
67 if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
68 goto LBL_V;
69 }
70 }
66 if (v_lsb != k) {
67 if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
68 goto LBL_V;
69 }
70 }
7171
72 while (mp_iszero(&v) == MP_NO) {
73 /* make sure v is the largest */
74 if (mp_cmp_mag(&u, &v) == MP_GT) {
75 /* swap u and v to make sure v is >= u */
76 mp_exch(&u, &v);
77 }
78
79 /* subtract smallest from largest */
80 if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
81 goto LBL_V;
82 }
83
84 /* Divide out all factors of two */
85 if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
86 goto LBL_V;
87 }
88 }
72 while (mp_iszero(&v) == MP_NO) {
73 /* make sure v is the largest */
74 if (mp_cmp_mag(&u, &v) == MP_GT) {
75 /* swap u and v to make sure v is >= u */
76 mp_exch(&u, &v);
77 }
8978
90 /* multiply by 2**k which we divided out at the beginning */
91 if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
92 goto LBL_V;
93 }
94 c->sign = MP_ZPOS;
95 res = MP_OKAY;
96 LBL_V:mp_clear (&u);
97 LBL_U:mp_clear (&v);
98 return res;
79 /* subtract smallest from largest */
80 if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
81 goto LBL_V;
82 }
83
84 /* Divide out all factors of two */
85 if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
86 goto LBL_V;
87 }
88 }
89
90 /* multiply by 2**k which we divided out at the beginning */
91 if ((res = mp_mul_2d(&u, k, c)) != MP_OKAY) {
92 goto LBL_V;
93 }
94 c->sign = MP_ZPOS;
95 res = MP_OKAY;
96 LBL_V:
97 mp_clear(&u);
98 LBL_U:
99 mp_clear(&v);
100 return res;
99101 }
100102 #endif
101103
102 /* $Source$ */
103 /* $Revision$ */
104 /* $Date$ */
104 /* ref: $Format:%D$ */
105 /* git commit: $Format:%H$ */
106 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* get the lower 32-bits of an mp_int */
18 unsigned long mp_get_int(mp_int * a)
18 unsigned long mp_get_int(const mp_int *a)
1919 {
20 int i;
21 mp_uint64 res;
20 int i;
21 mp_min_u32 res;
2222
23 if (a->used == 0) {
24 return 0;
25 }
23 if (a->used == 0) {
24 return 0;
25 }
2626
27 /* get number of digits of the lsb we have to read */
28 i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
27 /* get number of digits of the lsb we have to read */
28 i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
2929
30 /* get most significant digit of result */
31 res = DIGIT(a,i);
30 /* get most significant digit of result */
31 res = DIGIT(a, i);
3232
33 while (--i >= 0) {
34 res = (res << DIGIT_BIT) | DIGIT(a,i);
35 }
33 while (--i >= 0) {
34 res = (res << DIGIT_BIT) | DIGIT(a, i);
35 }
3636
37 /* force result to 32-bits always so it is consistent on non 32-bit platforms */
38 return (unsigned long)(res & 0xFFFFFFFFUL);
37 /* force result to 32-bits always so it is consistent on non 32-bit platforms */
38 return res & 0xFFFFFFFFUL;
3939 }
4040 #endif
4141
42 /* $Source$ */
43 /* $Revision$ */
44 /* $Date$ */
42 /* ref: $Format:%D$ */
43 /* git commit: $Format:%H$ */
44 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* get the lower unsigned long of an mp_int, platform dependent */
18 unsigned long mp_get_long(mp_int * a)
18 unsigned long mp_get_long(const mp_int *a)
1919 {
20 int i;
21 unsigned long res;
20 int i;
21 unsigned long res;
2222
23 if (a->used == 0) {
24 return 0;
25 }
23 if (a->used == 0) {
24 return 0;
25 }
2626
27 /* get number of digits of the lsb we have to read */
28 i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
27 /* get number of digits of the lsb we have to read */
28 i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
2929
30 /* get most significant digit of result */
31 res = DIGIT(a,i);
30 /* get most significant digit of result */
31 res = DIGIT(a, i);
3232
3333 #if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32)
34 while (--i >= 0) {
35 res = (res << DIGIT_BIT) | DIGIT(a,i);
36 }
34 while (--i >= 0) {
35 res = (res << DIGIT_BIT) | DIGIT(a, i);
36 }
3737 #endif
38 return res;
38 return res;
3939 }
4040 #endif
1515 */
1616
1717 /* get the lower unsigned long long of an mp_int, platform dependent */
18 unsigned long long mp_get_long_long (mp_int * a)
18 uint64_t mp_get_long_long(const mp_int *a)
1919 {
20 int i;
21 unsigned long long res;
20 int i;
21 uint64_t res;
2222
23 if (a->used == 0) {
24 return 0;
25 }
23 if (a->used == 0) {
24 return 0;
25 }
2626
27 /* get number of digits of the lsb we have to read */
28 i = MIN(a->used,(int)(((sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
27 /* get number of digits of the lsb we have to read */
28 i = MIN(a->used, ((((int)sizeof(uint64_t) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
2929
30 /* get most significant digit of result */
31 res = DIGIT(a,i);
30 /* get most significant digit of result */
31 res = DIGIT(a, i);
3232
3333 #if DIGIT_BIT < 64
34 while (--i >= 0) {
35 res = (res << DIGIT_BIT) | DIGIT(a,i);
36 }
34 while (--i >= 0) {
35 res = (res << DIGIT_BIT) | DIGIT(a, i);
36 }
3737 #endif
38 return res;
38 return res;
3939 }
4040 #endif
1515 */
1616
1717 /* grow as required */
18 int mp_grow (mp_int * a, int size)
18 int mp_grow(mp_int *a, int size)
1919 {
20 int i;
21 mp_digit *tmp;
20 int i;
21 mp_digit *tmp;
2222
23 /* if the alloc size is smaller alloc more ram */
24 if (a->alloc < size) {
25 /* ensure there are always at least MP_PREC digits extra on top */
26 size += (MP_PREC * 2) - (size % MP_PREC);
23 /* if the alloc size is smaller alloc more ram */
24 if (a->alloc < size) {
25 /* ensure there are always at least MP_PREC digits extra on top */
26 size += (MP_PREC * 2) - (size % MP_PREC);
2727
28 /* reallocate the array a->dp
29 *
30 * We store the return in a temporary variable
31 * in case the operation failed we don't want
32 * to overwrite the dp member of a.
33 */
34 tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
35 if (tmp == NULL) {
36 /* reallocation failed but "a" is still valid [can be freed] */
37 return MP_MEM;
38 }
28 /* reallocate the array a->dp
29 *
30 * We store the return in a temporary variable
31 * in case the operation failed we don't want
32 * to overwrite the dp member of a.
33 */
34 tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * (size_t)size);
35 if (tmp == NULL) {
36 /* reallocation failed but "a" is still valid [can be freed] */
37 return MP_MEM;
38 }
3939
40 /* reallocation succeeded so set a->dp */
41 a->dp = tmp;
40 /* reallocation succeeded so set a->dp */
41 a->dp = tmp;
4242
43 /* zero excess digits */
44 i = a->alloc;
45 a->alloc = size;
46 for (; i < a->alloc; i++) {
47 a->dp[i] = 0;
48 }
49 }
50 return MP_OKAY;
43 /* zero excess digits */
44 i = a->alloc;
45 a->alloc = size;
46 for (; i < a->alloc; i++) {
47 a->dp[i] = 0;
48 }
49 }
50 return MP_OKAY;
5151 }
5252 #endif
5353
54 /* $Source$ */
55 /* $Revision$ */
56 /* $Date$ */
54 /* ref: $Format:%D$ */
55 /* git commit: $Format:%H$ */
56 /* commit time: $Format:%ai$ */
1717 /* based on gmp's mpz_import.
1818 * see http://gmplib.org/manual/Integer-Import-and-Export.html
1919 */
20 int mp_import(mp_int* rop, size_t count, int order, size_t size,
21 int endian, size_t nails, const void* op) {
22 int result;
23 size_t odd_nails, nail_bytes, i, j;
24 unsigned char odd_nail_mask;
20 int mp_import(mp_int *rop, size_t count, int order, size_t size,
21 int endian, size_t nails, const void *op)
22 {
23 int result;
24 size_t odd_nails, nail_bytes, i, j;
25 unsigned char odd_nail_mask;
2526
26 mp_zero(rop);
27 mp_zero(rop);
2728
28 if (endian == 0) {
29 union {
30 unsigned int i;
31 char c[4];
32 } lint;
33 lint.i = 0x01020304;
34
35 endian = (lint.c[0] == 4) ? -1 : 1;
36 }
29 if (endian == 0) {
30 union {
31 unsigned int i;
32 char c[4];
33 } lint;
34 lint.i = 0x01020304;
3735
38 odd_nails = (nails % 8);
39 odd_nail_mask = 0xff;
40 for (i = 0; i < odd_nails; ++i) {
41 odd_nail_mask ^= (1 << (7 - i));
42 }
43 nail_bytes = nails / 8;
36 endian = (lint.c[0] == '\x04') ? -1 : 1;
37 }
4438
45 for (i = 0; i < count; ++i) {
46 for (j = 0; j < (size - nail_bytes); ++j) {
47 unsigned char byte = *(
48 (unsigned char*)op +
49 (((order == 1) ? i : ((count - 1) - i)) * size) +
50 ((endian == 1) ? (j + nail_bytes) : (((size - 1) - j) - nail_bytes))
51 );
39 odd_nails = (nails % 8u);
40 odd_nail_mask = 0xff;
41 for (i = 0; i < odd_nails; ++i) {
42 odd_nail_mask ^= (unsigned char)(1u << (7u - i));
43 }
44 nail_bytes = nails / 8u;
5245
53 if (
54 (result = mp_mul_2d(rop, (int)((j == 0) ? (8 - odd_nails) : 8), rop)) != MP_OKAY) {
55 return result;
56 }
46 for (i = 0; i < count; ++i) {
47 for (j = 0; j < (size - nail_bytes); ++j) {
48 unsigned char byte = *((unsigned char *)op +
49 (((order == 1) ? i : ((count - 1u) - i)) * size) +
50 ((endian == 1) ? (j + nail_bytes) : (((size - 1u) - j) - nail_bytes)));
5751
58 rop->dp[0] |= (j == 0) ? (byte & odd_nail_mask) : byte;
59 rop->used += 1;
60 }
61 }
52 if ((result = mp_mul_2d(rop, (j == 0u) ? (int)(8u - odd_nails) : 8, rop)) != MP_OKAY) {
53 return result;
54 }
6255
63 mp_clamp(rop);
56 rop->dp[0] |= (j == 0u) ? (mp_digit)(byte & odd_nail_mask) : (mp_digit)byte;
57 rop->used += 1;
58 }
59 }
6460
65 return MP_OKAY;
61 mp_clamp(rop);
62
63 return MP_OKAY;
6664 }
6765
6866 #endif
6967
70 /* $Source$ */
71 /* $Revision$ */
72 /* $Date$ */
68 /* ref: $Format:%D$ */
69 /* git commit: $Format:%H$ */
70 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* init a new mp_int */
18 int mp_init (mp_int * a)
18 int mp_init(mp_int *a)
1919 {
20 int i;
20 int i;
2121
22 /* allocate memory required and clear it */
23 a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
24 if (a->dp == NULL) {
25 return MP_MEM;
26 }
22 /* allocate memory required and clear it */
23 a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * (size_t)MP_PREC);
24 if (a->dp == NULL) {
25 return MP_MEM;
26 }
2727
28 /* set the digits to zero */
29 for (i = 0; i < MP_PREC; i++) {
28 /* set the digits to zero */
29 for (i = 0; i < MP_PREC; i++) {
3030 a->dp[i] = 0;
31 }
31 }
3232
33 /* set the used to zero, allocated digits to the default precision
34 * and sign to positive */
35 a->used = 0;
36 a->alloc = MP_PREC;
37 a->sign = MP_ZPOS;
33 /* set the used to zero, allocated digits to the default precision
34 * and sign to positive */
35 a->used = 0;
36 a->alloc = MP_PREC;
37 a->sign = MP_ZPOS;
3838
39 return MP_OKAY;
39 return MP_OKAY;
4040 }
4141 #endif
4242
43 /* $Source$ */
44 /* $Revision$ */
45 /* $Date$ */
43 /* ref: $Format:%D$ */
44 /* git commit: $Format:%H$ */
45 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* creates "a" then copies b into it */
18 int mp_init_copy (mp_int * a, mp_int * b)
18 int mp_init_copy(mp_int *a, const mp_int *b)
1919 {
20 int res;
20 int res;
2121
22 if ((res = mp_init_size (a, b->used)) != MP_OKAY) {
23 return res;
24 }
25 return mp_copy (b, a);
22 if ((res = mp_init_size(a, b->used)) != MP_OKAY) {
23 return res;
24 }
25
26 if ((res = mp_copy(b, a)) != MP_OKAY) {
27 mp_clear(a);
28 }
29
30 return res;
2631 }
2732 #endif
2833
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
34 /* ref: $Format:%D$ */
35 /* git commit: $Format:%H$ */
36 /* commit time: $Format:%ai$ */
1515 */
1616 #include <stdarg.h>
1717
18 int mp_init_multi(mp_int *mp, ...)
18 int mp_init_multi(mp_int *mp, ...)
1919 {
20 mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
21 int n = 0; /* Number of ok inits */
22 mp_int* cur_arg = mp;
23 va_list args;
20 mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
21 int n = 0; /* Number of ok inits */
22 mp_int *cur_arg = mp;
23 va_list args;
2424
25 va_start(args, mp); /* init args to next argument from caller */
26 while (cur_arg != NULL) {
27 if (mp_init(cur_arg) != MP_OKAY) {
28 /* Oops - error! Back-track and mp_clear what we already
29 succeeded in init-ing, then return error.
30 */
31 va_list clean_args;
32
33 /* end the current list */
34 va_end(args);
35
36 /* now start cleaning up */
37 cur_arg = mp;
38 va_start(clean_args, mp);
39 while (n-- != 0) {
40 mp_clear(cur_arg);
41 cur_arg = va_arg(clean_args, mp_int*);
42 }
43 va_end(clean_args);
44 res = MP_MEM;
45 break;
46 }
47 n++;
48 cur_arg = va_arg(args, mp_int*);
49 }
50 va_end(args);
51 return res; /* Assumed ok, if error flagged above. */
25 va_start(args, mp); /* init args to next argument from caller */
26 while (cur_arg != NULL) {
27 if (mp_init(cur_arg) != MP_OKAY) {
28 /* Oops - error! Back-track and mp_clear what we already
29 succeeded in init-ing, then return error.
30 */
31 va_list clean_args;
32
33 /* now start cleaning up */
34 cur_arg = mp;
35 va_start(clean_args, mp);
36 while (n-- != 0) {
37 mp_clear(cur_arg);
38 cur_arg = va_arg(clean_args, mp_int *);
39 }
40 va_end(clean_args);
41 res = MP_MEM;
42 break;
43 }
44 n++;
45 cur_arg = va_arg(args, mp_int *);
46 }
47 va_end(args);
48 return res; /* Assumed ok, if error flagged above. */
5249 }
5350
5451 #endif
5552
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
53 /* ref: $Format:%D$ */
54 /* git commit: $Format:%H$ */
55 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* initialize and set a digit */
18 int mp_init_set (mp_int * a, mp_digit b)
18 int mp_init_set(mp_int *a, mp_digit b)
1919 {
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 mp_set(a, b);
25 return err;
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 mp_set(a, b);
25 return err;
2626 }
2727 #endif
2828
29 /* $Source$ */
30 /* $Revision$ */
31 /* $Date$ */
29 /* ref: $Format:%D$ */
30 /* git commit: $Format:%H$ */
31 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* initialize and set a digit */
18 int mp_init_set_int (mp_int * a, unsigned long b)
18 int mp_init_set_int(mp_int *a, unsigned long b)
1919 {
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 return mp_set_int(a, b);
20 int err;
21 if ((err = mp_init(a)) != MP_OKAY) {
22 return err;
23 }
24 return mp_set_int(a, b);
2525 }
2626 #endif
2727
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
28 /* ref: $Format:%D$ */
29 /* git commit: $Format:%H$ */
30 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* init an mp_init for a given size */
18 int mp_init_size (mp_int * a, int size)
18 int mp_init_size(mp_int *a, int size)
1919 {
20 int x;
20 int x;
2121
22 /* pad size so there are always extra digits */
23 size += (MP_PREC * 2) - (size % MP_PREC);
24
25 /* alloc mem */
26 a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
27 if (a->dp == NULL) {
28 return MP_MEM;
29 }
22 /* pad size so there are always extra digits */
23 size += (MP_PREC * 2) - (size % MP_PREC);
3024
31 /* set the members */
32 a->used = 0;
33 a->alloc = size;
34 a->sign = MP_ZPOS;
25 /* alloc mem */
26 a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * (size_t)size);
27 if (a->dp == NULL) {
28 return MP_MEM;
29 }
3530
36 /* zero the digits */
37 for (x = 0; x < size; x++) {
31 /* set the members */
32 a->used = 0;
33 a->alloc = size;
34 a->sign = MP_ZPOS;
35
36 /* zero the digits */
37 for (x = 0; x < size; x++) {
3838 a->dp[x] = 0;
39 }
39 }
4040
41 return MP_OKAY;
41 return MP_OKAY;
4242 }
4343 #endif
4444
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
45 /* ref: $Format:%D$ */
46 /* git commit: $Format:%H$ */
47 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* hac 14.61, pp608 */
18 int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
18 int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
1919 {
20 /* b cannot be negative */
21 if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) {
22 return MP_VAL;
23 }
20 /* b cannot be negative and has to be >1 */
21 if ((b->sign == MP_NEG) || (mp_cmp_d(b, 1uL) != MP_GT)) {
22 return MP_VAL;
23 }
2424
2525 #ifdef BN_FAST_MP_INVMOD_C
26 /* if the modulus is odd and >1 we can use a faster routine instead */
27 if ((mp_isodd (b) == MP_YES) && (mp_cmp_d (b, 1) != MP_EQ)) {
28 return fast_mp_invmod (a, b, c);
29 }
26 /* if the modulus is odd we can use a faster routine instead */
27 if ((mp_isodd(b) == MP_YES)) {
28 return fast_mp_invmod(a, b, c);
29 }
3030 #endif
3131
3232 #ifdef BN_MP_INVMOD_SLOW_C
33 return mp_invmod_slow(a, b, c);
33 return mp_invmod_slow(a, b, c);
3434 #else
35 return MP_VAL;
35 return MP_VAL;
3636 #endif
3737 }
3838 #endif
3939
40 /* $Source$ */
41 /* $Revision$ */
42 /* $Date$ */
40 /* ref: $Format:%D$ */
41 /* git commit: $Format:%H$ */
42 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* hac 14.61, pp608 */
18 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
18 int mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c)
1919 {
20 mp_int x, y, u, v, A, B, C, D;
21 int res;
20 mp_int x, y, u, v, A, B, C, D;
21 int res;
2222
23 /* b cannot be negative */
24 if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) {
25 return MP_VAL;
26 }
23 /* b cannot be negative */
24 if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) {
25 return MP_VAL;
26 }
2727
28 /* init temps */
29 if ((res = mp_init_multi(&x, &y, &u, &v,
30 &A, &B, &C, &D, NULL)) != MP_OKAY) {
31 return res;
32 }
28 /* init temps */
29 if ((res = mp_init_multi(&x, &y, &u, &v,
30 &A, &B, &C, &D, NULL)) != MP_OKAY) {
31 return res;
32 }
3333
34 /* x = a, y = b */
35 if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
34 /* x = a, y = b */
35 if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
3636 goto LBL_ERR;
37 }
38 if ((res = mp_copy (b, &y)) != MP_OKAY) {
39 goto LBL_ERR;
40 }
37 }
38 if ((res = mp_copy(b, &y)) != MP_OKAY) {
39 goto LBL_ERR;
40 }
4141
42 /* 2. [modified] if x,y are both even then return an error! */
43 if ((mp_iseven (&x) == MP_YES) && (mp_iseven (&y) == MP_YES)) {
44 res = MP_VAL;
45 goto LBL_ERR;
46 }
42 /* 2. [modified] if x,y are both even then return an error! */
43 if ((mp_iseven(&x) == MP_YES) && (mp_iseven(&y) == MP_YES)) {
44 res = MP_VAL;
45 goto LBL_ERR;
46 }
4747
48 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
49 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 mp_set (&A, 1);
56 mp_set (&D, 1);
48 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
49 if ((res = mp_copy(&x, &u)) != MP_OKAY) {
50 goto LBL_ERR;
51 }
52 if ((res = mp_copy(&y, &v)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 mp_set(&A, 1uL);
56 mp_set(&D, 1uL);
5757
5858 top:
59 /* 4. while u is even do */
60 while (mp_iseven (&u) == MP_YES) {
61 /* 4.1 u = u/2 */
62 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
63 goto LBL_ERR;
64 }
65 /* 4.2 if A or B is odd then */
66 if ((mp_isodd (&A) == MP_YES) || (mp_isodd (&B) == MP_YES)) {
67 /* A = (A+y)/2, B = (B-x)/2 */
68 if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
59 /* 4. while u is even do */
60 while (mp_iseven(&u) == MP_YES) {
61 /* 4.1 u = u/2 */
62 if ((res = mp_div_2(&u, &u)) != MP_OKAY) {
6963 goto LBL_ERR;
7064 }
71 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
65 /* 4.2 if A or B is odd then */
66 if ((mp_isodd(&A) == MP_YES) || (mp_isodd(&B) == MP_YES)) {
67 /* A = (A+y)/2, B = (B-x)/2 */
68 if ((res = mp_add(&A, &y, &A)) != MP_OKAY) {
69 goto LBL_ERR;
70 }
71 if ((res = mp_sub(&B, &x, &B)) != MP_OKAY) {
72 goto LBL_ERR;
73 }
74 }
75 /* A = A/2, B = B/2 */
76 if ((res = mp_div_2(&A, &A)) != MP_OKAY) {
7277 goto LBL_ERR;
7378 }
74 }
75 /* A = A/2, B = B/2 */
76 if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
77 goto LBL_ERR;
78 }
79 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
80 goto LBL_ERR;
81 }
82 }
83
84 /* 5. while v is even do */
85 while (mp_iseven (&v) == MP_YES) {
86 /* 5.1 v = v/2 */
87 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
88 goto LBL_ERR;
89 }
90 /* 5.2 if C or D is odd then */
91 if ((mp_isodd (&C) == MP_YES) || (mp_isodd (&D) == MP_YES)) {
92 /* C = (C+y)/2, D = (D-x)/2 */
93 if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
79 if ((res = mp_div_2(&B, &B)) != MP_OKAY) {
9480 goto LBL_ERR;
9581 }
96 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
82 }
83
84 /* 5. while v is even do */
85 while (mp_iseven(&v) == MP_YES) {
86 /* 5.1 v = v/2 */
87 if ((res = mp_div_2(&v, &v)) != MP_OKAY) {
9788 goto LBL_ERR;
9889 }
99 }
100 /* C = C/2, D = D/2 */
101 if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
90 /* 5.2 if C or D is odd then */
91 if ((mp_isodd(&C) == MP_YES) || (mp_isodd(&D) == MP_YES)) {
92 /* C = (C+y)/2, D = (D-x)/2 */
93 if ((res = mp_add(&C, &y, &C)) != MP_OKAY) {
94 goto LBL_ERR;
95 }
96 if ((res = mp_sub(&D, &x, &D)) != MP_OKAY) {
97 goto LBL_ERR;
98 }
99 }
100 /* C = C/2, D = D/2 */
101 if ((res = mp_div_2(&C, &C)) != MP_OKAY) {
102 goto LBL_ERR;
103 }
104 if ((res = mp_div_2(&D, &D)) != MP_OKAY) {
105 goto LBL_ERR;
106 }
107 }
108
109 /* 6. if u >= v then */
110 if (mp_cmp(&u, &v) != MP_LT) {
111 /* u = u - v, A = A - C, B = B - D */
112 if ((res = mp_sub(&u, &v, &u)) != MP_OKAY) {
113 goto LBL_ERR;
114 }
115
116 if ((res = mp_sub(&A, &C, &A)) != MP_OKAY) {
117 goto LBL_ERR;
118 }
119
120 if ((res = mp_sub(&B, &D, &B)) != MP_OKAY) {
121 goto LBL_ERR;
122 }
123 } else {
124 /* v - v - u, C = C - A, D = D - B */
125 if ((res = mp_sub(&v, &u, &v)) != MP_OKAY) {
126 goto LBL_ERR;
127 }
128
129 if ((res = mp_sub(&C, &A, &C)) != MP_OKAY) {
130 goto LBL_ERR;
131 }
132
133 if ((res = mp_sub(&D, &B, &D)) != MP_OKAY) {
134 goto LBL_ERR;
135 }
136 }
137
138 /* if not zero goto step 4 */
139 if (mp_iszero(&u) == MP_NO)
140 goto top;
141
142 /* now a = C, b = D, gcd == g*v */
143
144 /* if v != 1 then there is no inverse */
145 if (mp_cmp_d(&v, 1uL) != MP_EQ) {
146 res = MP_VAL;
102147 goto LBL_ERR;
103 }
104 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
105 goto LBL_ERR;
106 }
107 }
148 }
108149
109 /* 6. if u >= v then */
110 if (mp_cmp (&u, &v) != MP_LT) {
111 /* u = u - v, A = A - C, B = B - D */
112 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
113 goto LBL_ERR;
114 }
115
116 if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
117 goto LBL_ERR;
118 }
119
120 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
121 goto LBL_ERR;
122 }
123 } else {
124 /* v - v - u, C = C - A, D = D - B */
125 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
126 goto LBL_ERR;
127 }
128
129 if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
130 goto LBL_ERR;
131 }
132
133 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
134 goto LBL_ERR;
135 }
136 }
137
138 /* if not zero goto step 4 */
139 if (mp_iszero (&u) == MP_NO)
140 goto top;
141
142 /* now a = C, b = D, gcd == g*v */
143
144 /* if v != 1 then there is no inverse */
145 if (mp_cmp_d (&v, 1) != MP_EQ) {
146 res = MP_VAL;
147 goto LBL_ERR;
148 }
149
150 /* if its too low */
151 while (mp_cmp_d(&C, 0) == MP_LT) {
150 /* if its too low */
151 while (mp_cmp_d(&C, 0uL) == MP_LT) {
152152 if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
153153 goto LBL_ERR;
154154 }
155 }
156
157 /* too big */
158 while (mp_cmp_mag(&C, b) != MP_LT) {
155 }
156
157 /* too big */
158 while (mp_cmp_mag(&C, b) != MP_LT) {
159159 if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
160160 goto LBL_ERR;
161161 }
162 }
163
164 /* C is now the inverse */
165 mp_exch (&C, c);
166 res = MP_OKAY;
167 LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
168 return res;
162 }
163
164 /* C is now the inverse */
165 mp_exch(&C, c);
166 res = MP_OKAY;
167 LBL_ERR:
168 mp_clear_multi(&x, &y, &u, &v, &A, &B, &C, &D, NULL);
169 return res;
169170 }
170171 #endif
171172
172 /* $Source$ */
173 /* $Revision$ */
174 /* $Date$ */
173 /* ref: $Format:%D$ */
174 /* git commit: $Format:%H$ */
175 /* commit time: $Format:%ai$ */
1616
1717 /* Check if remainders are possible squares - fast exclude non-squares */
1818 static const char rem_128[128] = {
19 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
20 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
21 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
22 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
23 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
24 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
25 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
26 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
19 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
20 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
21 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
22 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
23 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
24 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
25 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
26 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
2727 };
2828
2929 static const char rem_105[105] = {
30 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
31 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
32 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
33 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
34 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
35 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
36 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
30 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
31 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
32 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
33 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
34 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
35 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
36 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
3737 };
3838
3939 /* Store non-zero to ret if arg is square, and zero if not */
40 int mp_is_square(mp_int *arg,int *ret)
40 int mp_is_square(const mp_int *arg, int *ret)
4141 {
42 int res;
43 mp_digit c;
44 mp_int t;
45 unsigned long r;
42 int res;
43 mp_digit c;
44 mp_int t;
45 unsigned long r;
4646
47 /* Default to Non-square :) */
48 *ret = MP_NO;
47 /* Default to Non-square :) */
48 *ret = MP_NO;
4949
50 if (arg->sign == MP_NEG) {
51 return MP_VAL;
52 }
50 if (arg->sign == MP_NEG) {
51 return MP_VAL;
52 }
5353
54 /* digits used? (TSD) */
55 if (arg->used == 0) {
56 return MP_OKAY;
57 }
54 /* digits used? (TSD) */
55 if (arg->used == 0) {
56 return MP_OKAY;
57 }
5858
59 /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
60 if (rem_128[127 & DIGIT(arg,0)] == 1) {
61 return MP_OKAY;
62 }
59 /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
60 if (rem_128[127u & DIGIT(arg, 0)] == (char)1) {
61 return MP_OKAY;
62 }
6363
64 /* Next check mod 105 (3*5*7) */
65 if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
66 return res;
67 }
68 if (rem_105[c] == 1) {
69 return MP_OKAY;
70 }
64 /* Next check mod 105 (3*5*7) */
65 if ((res = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) {
66 return res;
67 }
68 if (rem_105[c] == (char)1) {
69 return MP_OKAY;
70 }
7171
7272
73 if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
74 return res;
75 }
76 if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
77 goto ERR;
78 }
79 r = mp_get_int(&t);
80 /* Check for other prime modules, note it's not an ERROR but we must
81 * free "t" so the easiest way is to goto ERR. We know that res
82 * is already equal to MP_OKAY from the mp_mod call
83 */
84 if (((1L<<(r%11)) & 0x5C4L) != 0L) goto ERR;
85 if (((1L<<(r%13)) & 0x9E4L) != 0L) goto ERR;
86 if (((1L<<(r%17)) & 0x5CE8L) != 0L) goto ERR;
87 if (((1L<<(r%19)) & 0x4F50CL) != 0L) goto ERR;
88 if (((1L<<(r%23)) & 0x7ACCA0L) != 0L) goto ERR;
89 if (((1L<<(r%29)) & 0xC2EDD0CL) != 0L) goto ERR;
90 if (((1L<<(r%31)) & 0x6DE2B848L) != 0L) goto ERR;
73 if ((res = mp_init_set_int(&t, 11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
74 return res;
75 }
76 if ((res = mp_mod(arg, &t, &t)) != MP_OKAY) {
77 goto ERR;
78 }
79 r = mp_get_int(&t);
80 /* Check for other prime modules, note it's not an ERROR but we must
81 * free "t" so the easiest way is to goto ERR. We know that res
82 * is already equal to MP_OKAY from the mp_mod call
83 */
84 if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL) goto ERR;
85 if (((1uL<<(r%13uL)) & 0x9E4uL) != 0uL) goto ERR;
86 if (((1uL<<(r%17uL)) & 0x5CE8uL) != 0uL) goto ERR;
87 if (((1uL<<(r%19uL)) & 0x4F50CuL) != 0uL) goto ERR;
88 if (((1uL<<(r%23uL)) & 0x7ACCA0uL) != 0uL) goto ERR;
89 if (((1uL<<(r%29uL)) & 0xC2EDD0CuL) != 0uL) goto ERR;
90 if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL) goto ERR;
9191
92 /* Final check - is sqr(sqrt(arg)) == arg ? */
93 if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
94 goto ERR;
95 }
96 if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
97 goto ERR;
98 }
92 /* Final check - is sqr(sqrt(arg)) == arg ? */
93 if ((res = mp_sqrt(arg, &t)) != MP_OKAY) {
94 goto ERR;
95 }
96 if ((res = mp_sqr(&t, &t)) != MP_OKAY) {
97 goto ERR;
98 }
9999
100 *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
101 ERR:mp_clear(&t);
102 return res;
100 *ret = (mp_cmp_mag(&t, arg) == MP_EQ) ? MP_YES : MP_NO;
101 ERR:
102 mp_clear(&t);
103 return res;
103104 }
104105 #endif
105106
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
107 /* ref: $Format:%D$ */
108 /* git commit: $Format:%H$ */
109 /* commit time: $Format:%ai$ */
1919 * HAC is wrong here, as the special case of (0 | 1) is not
2020 * handled correctly.
2121 */
22 int mp_jacobi (mp_int * a, mp_int * n, int *c)
22 int mp_jacobi(const mp_int *a, const mp_int *n, int *c)
2323 {
24 mp_int a1, p1;
25 int k, s, r, res;
26 mp_digit residue;
24 mp_int a1, p1;
25 int k, s, r, res;
26 mp_digit residue;
2727
28 /* if a < 0 return MP_VAL */
29 if (mp_isneg(a) == MP_YES) {
30 return MP_VAL;
31 }
28 /* if a < 0 return MP_VAL */
29 if (mp_isneg(a) == MP_YES) {
30 return MP_VAL;
31 }
3232
33 /* if n <= 0 return MP_VAL */
34 if (mp_cmp_d(n, 0) != MP_GT) {
35 return MP_VAL;
36 }
33 /* if n <= 0 return MP_VAL */
34 if (mp_cmp_d(n, 0uL) != MP_GT) {
35 return MP_VAL;
36 }
3737
38 /* step 1. handle case of a == 0 */
39 if (mp_iszero (a) == MP_YES) {
40 /* special case of a == 0 and n == 1 */
41 if (mp_cmp_d (n, 1) == MP_EQ) {
42 *c = 1;
43 } else {
44 *c = 0;
45 }
46 return MP_OKAY;
47 }
38 /* step 1. handle case of a == 0 */
39 if (mp_iszero(a) == MP_YES) {
40 /* special case of a == 0 and n == 1 */
41 if (mp_cmp_d(n, 1uL) == MP_EQ) {
42 *c = 1;
43 } else {
44 *c = 0;
45 }
46 return MP_OKAY;
47 }
4848
49 /* step 2. if a == 1, return 1 */
50 if (mp_cmp_d (a, 1) == MP_EQ) {
51 *c = 1;
52 return MP_OKAY;
53 }
49 /* step 2. if a == 1, return 1 */
50 if (mp_cmp_d(a, 1uL) == MP_EQ) {
51 *c = 1;
52 return MP_OKAY;
53 }
5454
55 /* default */
56 s = 0;
55 /* default */
56 s = 0;
5757
58 /* step 3. write a = a1 * 2**k */
59 if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
60 return res;
61 }
58 /* step 3. write a = a1 * 2**k */
59 if ((res = mp_init_copy(&a1, a)) != MP_OKAY) {
60 return res;
61 }
6262
63 if ((res = mp_init (&p1)) != MP_OKAY) {
64 goto LBL_A1;
65 }
63 if ((res = mp_init(&p1)) != MP_OKAY) {
64 goto LBL_A1;
65 }
6666
67 /* divide out larger power of two */
68 k = mp_cnt_lsb(&a1);
69 if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
70 goto LBL_P1;
71 }
67 /* divide out larger power of two */
68 k = mp_cnt_lsb(&a1);
69 if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
70 goto LBL_P1;
71 }
7272
73 /* step 4. if e is even set s=1 */
74 if ((k & 1) == 0) {
75 s = 1;
76 } else {
77 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
78 residue = n->dp[0] & 7;
73 /* step 4. if e is even set s=1 */
74 if (((unsigned)k & 1u) == 0u) {
75 s = 1;
76 } else {
77 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
78 residue = n->dp[0] & 7u;
7979
80 if ((residue == 1) || (residue == 7)) {
81 s = 1;
82 } else if ((residue == 3) || (residue == 5)) {
83 s = -1;
84 }
85 }
80 if ((residue == 1u) || (residue == 7u)) {
81 s = 1;
82 } else if ((residue == 3u) || (residue == 5u)) {
83 s = -1;
84 }
85 }
8686
87 /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
88 if ( ((n->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
89 s = -s;
90 }
87 /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
88 if (((n->dp[0] & 3u) == 3u) && ((a1.dp[0] & 3u) == 3u)) {
89 s = -s;
90 }
9191
92 /* if a1 == 1 we're done */
93 if (mp_cmp_d (&a1, 1) == MP_EQ) {
94 *c = s;
95 } else {
96 /* n1 = n mod a1 */
97 if ((res = mp_mod (n, &a1, &p1)) != MP_OKAY) {
98 goto LBL_P1;
99 }
100 if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
101 goto LBL_P1;
102 }
103 *c = s * r;
104 }
92 /* if a1 == 1 we're done */
93 if (mp_cmp_d(&a1, 1uL) == MP_EQ) {
94 *c = s;
95 } else {
96 /* n1 = n mod a1 */
97 if ((res = mp_mod(n, &a1, &p1)) != MP_OKAY) {
98 goto LBL_P1;
99 }
100 if ((res = mp_jacobi(&p1, &a1, &r)) != MP_OKAY) {
101 goto LBL_P1;
102 }
103 *c = s * r;
104 }
105105
106 /* done */
107 res = MP_OKAY;
108 LBL_P1:mp_clear (&p1);
109 LBL_A1:mp_clear (&a1);
110 return res;
106 /* done */
107 res = MP_OKAY;
108 LBL_P1:
109 mp_clear(&p1);
110 LBL_A1:
111 mp_clear(&a1);
112 return res;
111113 }
112114 #endif
113115
114 /* $Source$ */
115 /* $Revision$ */
116 /* $Date$ */
116 /* ref: $Format:%D$ */
117 /* git commit: $Format:%H$ */
118 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* c = |a| * |b| using Karatsuba Multiplication using
17 /* c = |a| * |b| using Karatsuba Multiplication using
1818 * three half size multiplications
1919 *
20 * Let B represent the radix [e.g. 2**DIGIT_BIT] and
21 * let n represent half of the number of digits in
20 * Let B represent the radix [e.g. 2**DIGIT_BIT] and
21 * let n represent half of the number of digits in
2222 * the min(a,b)
2323 *
2424 * a = a1 * B**n + a0
2525 * b = b1 * B**n + b0
2626 *
27 * Then, a * b =>
27 * Then, a * b =>
2828 a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
2929 *
30 * Note that a1b1 and a0b0 are used twice and only need to be
31 * computed once. So in total three half size (half # of
32 * digit) multiplications are performed, a0b0, a1b1 and
30 * Note that a1b1 and a0b0 are used twice and only need to be
31 * computed once. So in total three half size (half # of
32 * digit) multiplications are performed, a0b0, a1b1 and
3333 * (a1+b1)(a0+b0)
3434 *
3535 * Note that a multiplication of half the digits requires
36 * 1/4th the number of single precision multiplications so in
37 * total after one call 25% of the single precision multiplications
38 * are saved. Note also that the call to mp_mul can end up back
39 * in this function if the a0, a1, b0, or b1 are above the threshold.
40 * This is known as divide-and-conquer and leads to the famous
41 * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
42 * the standard O(N**2) that the baseline/comba methods use.
43 * Generally though the overhead of this method doesn't pay off
36 * 1/4th the number of single precision multiplications so in
37 * total after one call 25% of the single precision multiplications
38 * are saved. Note also that the call to mp_mul can end up back
39 * in this function if the a0, a1, b0, or b1 are above the threshold.
40 * This is known as divide-and-conquer and leads to the famous
41 * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
42 * the standard O(N**2) that the baseline/comba methods use.
43 * Generally though the overhead of this method doesn't pay off
4444 * until a certain size (N ~ 80) is reached.
4545 */
46 int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
46 int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c)
4747 {
48 mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
49 int B, err;
48 mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
49 int B, err;
5050
51 /* default the return code to an error */
52 err = MP_MEM;
51 /* default the return code to an error */
52 err = MP_MEM;
5353
54 /* min # of digits */
55 B = MIN (a->used, b->used);
54 /* min # of digits */
55 B = MIN(a->used, b->used);
5656
57 /* now divide in two */
58 B = B >> 1;
57 /* now divide in two */
58 B = B >> 1;
5959
60 /* init copy all the temps */
61 if (mp_init_size (&x0, B) != MP_OKAY)
62 goto ERR;
63 if (mp_init_size (&x1, a->used - B) != MP_OKAY)
64 goto X0;
65 if (mp_init_size (&y0, B) != MP_OKAY)
66 goto X1;
67 if (mp_init_size (&y1, b->used - B) != MP_OKAY)
68 goto Y0;
60 /* init copy all the temps */
61 if (mp_init_size(&x0, B) != MP_OKAY)
62 goto ERR;
63 if (mp_init_size(&x1, a->used - B) != MP_OKAY)
64 goto X0;
65 if (mp_init_size(&y0, B) != MP_OKAY)
66 goto X1;
67 if (mp_init_size(&y1, b->used - B) != MP_OKAY)
68 goto Y0;
6969
70 /* init temps */
71 if (mp_init_size (&t1, B * 2) != MP_OKAY)
72 goto Y1;
73 if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
74 goto T1;
75 if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
76 goto X0Y0;
70 /* init temps */
71 if (mp_init_size(&t1, B * 2) != MP_OKAY)
72 goto Y1;
73 if (mp_init_size(&x0y0, B * 2) != MP_OKAY)
74 goto T1;
75 if (mp_init_size(&x1y1, B * 2) != MP_OKAY)
76 goto X0Y0;
7777
78 /* now shift the digits */
79 x0.used = y0.used = B;
80 x1.used = a->used - B;
81 y1.used = b->used - B;
78 /* now shift the digits */
79 x0.used = y0.used = B;
80 x1.used = a->used - B;
81 y1.used = b->used - B;
8282
83 {
84 int x;
85 mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
83 {
84 int x;
85 mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
8686
87 /* we copy the digits directly instead of using higher level functions
88 * since we also need to shift the digits
89 */
90 tmpa = a->dp;
91 tmpb = b->dp;
87 /* we copy the digits directly instead of using higher level functions
88 * since we also need to shift the digits
89 */
90 tmpa = a->dp;
91 tmpb = b->dp;
9292
93 tmpx = x0.dp;
94 tmpy = y0.dp;
95 for (x = 0; x < B; x++) {
96 *tmpx++ = *tmpa++;
97 *tmpy++ = *tmpb++;
98 }
93 tmpx = x0.dp;
94 tmpy = y0.dp;
95 for (x = 0; x < B; x++) {
96 *tmpx++ = *tmpa++;
97 *tmpy++ = *tmpb++;
98 }
9999
100 tmpx = x1.dp;
101 for (x = B; x < a->used; x++) {
102 *tmpx++ = *tmpa++;
103 }
100 tmpx = x1.dp;
101 for (x = B; x < a->used; x++) {
102 *tmpx++ = *tmpa++;
103 }
104104
105 tmpy = y1.dp;
106 for (x = B; x < b->used; x++) {
107 *tmpy++ = *tmpb++;
108 }
109 }
105 tmpy = y1.dp;
106 for (x = B; x < b->used; x++) {
107 *tmpy++ = *tmpb++;
108 }
109 }
110110
111 /* only need to clamp the lower words since by definition the
112 * upper words x1/y1 must have a known number of digits
113 */
114 mp_clamp (&x0);
115 mp_clamp (&y0);
111 /* only need to clamp the lower words since by definition the
112 * upper words x1/y1 must have a known number of digits
113 */
114 mp_clamp(&x0);
115 mp_clamp(&y0);
116116
117 /* now calc the products x0y0 and x1y1 */
118 /* after this x0 is no longer required, free temp [x0==t2]! */
119 if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
120 goto X1Y1; /* x0y0 = x0*y0 */
121 if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
122 goto X1Y1; /* x1y1 = x1*y1 */
117 /* now calc the products x0y0 and x1y1 */
118 /* after this x0 is no longer required, free temp [x0==t2]! */
119 if (mp_mul(&x0, &y0, &x0y0) != MP_OKAY)
120 goto X1Y1; /* x0y0 = x0*y0 */
121 if (mp_mul(&x1, &y1, &x1y1) != MP_OKAY)
122 goto X1Y1; /* x1y1 = x1*y1 */
123123
124 /* now calc x1+x0 and y1+y0 */
125 if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
126 goto X1Y1; /* t1 = x1 - x0 */
127 if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
128 goto X1Y1; /* t2 = y1 - y0 */
129 if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
130 goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
124 /* now calc x1+x0 and y1+y0 */
125 if (s_mp_add(&x1, &x0, &t1) != MP_OKAY)
126 goto X1Y1; /* t1 = x1 - x0 */
127 if (s_mp_add(&y1, &y0, &x0) != MP_OKAY)
128 goto X1Y1; /* t2 = y1 - y0 */
129 if (mp_mul(&t1, &x0, &t1) != MP_OKAY)
130 goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
131131
132 /* add x0y0 */
133 if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
134 goto X1Y1; /* t2 = x0y0 + x1y1 */
135 if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
136 goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
132 /* add x0y0 */
133 if (mp_add(&x0y0, &x1y1, &x0) != MP_OKAY)
134 goto X1Y1; /* t2 = x0y0 + x1y1 */
135 if (s_mp_sub(&t1, &x0, &t1) != MP_OKAY)
136 goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
137137
138 /* shift by B */
139 if (mp_lshd (&t1, B) != MP_OKAY)
140 goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
141 if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
142 goto X1Y1; /* x1y1 = x1y1 << 2*B */
138 /* shift by B */
139 if (mp_lshd(&t1, B) != MP_OKAY)
140 goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
141 if (mp_lshd(&x1y1, B * 2) != MP_OKAY)
142 goto X1Y1; /* x1y1 = x1y1 << 2*B */
143143
144 if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
145 goto X1Y1; /* t1 = x0y0 + t1 */
146 if (mp_add (&t1, &x1y1, c) != MP_OKAY)
147 goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
144 if (mp_add(&x0y0, &t1, &t1) != MP_OKAY)
145 goto X1Y1; /* t1 = x0y0 + t1 */
146 if (mp_add(&t1, &x1y1, c) != MP_OKAY)
147 goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
148148
149 /* Algorithm succeeded set the return code to MP_OKAY */
150 err = MP_OKAY;
149 /* Algorithm succeeded set the return code to MP_OKAY */
150 err = MP_OKAY;
151151
152 X1Y1:mp_clear (&x1y1);
153 X0Y0:mp_clear (&x0y0);
154 T1:mp_clear (&t1);
155 Y1:mp_clear (&y1);
156 Y0:mp_clear (&y0);
157 X1:mp_clear (&x1);
158 X0:mp_clear (&x0);
152 X1Y1:
153 mp_clear(&x1y1);
154 X0Y0:
155 mp_clear(&x0y0);
156 T1:
157 mp_clear(&t1);
158 Y1:
159 mp_clear(&y1);
160 Y0:
161 mp_clear(&y0);
162 X1:
163 mp_clear(&x1);
164 X0:
165 mp_clear(&x0);
159166 ERR:
160 return err;
167 return err;
161168 }
162169 #endif
163170
164 /* $Source$ */
165 /* $Revision$ */
166 /* $Date$ */
171 /* ref: $Format:%D$ */
172 /* git commit: $Format:%H$ */
173 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* Karatsuba squaring, computes b = a*a using three
17 /* Karatsuba squaring, computes b = a*a using three
1818 * half size squarings
1919 *
20 * See comments of karatsuba_mul for details. It
21 * is essentially the same algorithm but merely
20 * See comments of karatsuba_mul for details. It
21 * is essentially the same algorithm but merely
2222 * tuned to perform recursive squarings.
2323 */
24 int mp_karatsuba_sqr (mp_int * a, mp_int * b)
24 int mp_karatsuba_sqr(const mp_int *a, mp_int *b)
2525 {
26 mp_int x0, x1, t1, t2, x0x0, x1x1;
27 int B, err;
26 mp_int x0, x1, t1, t2, x0x0, x1x1;
27 int B, err;
2828
29 err = MP_MEM;
29 err = MP_MEM;
3030
31 /* min # of digits */
32 B = a->used;
31 /* min # of digits */
32 B = a->used;
3333
34 /* now divide in two */
35 B = B >> 1;
34 /* now divide in two */
35 B = B >> 1;
3636
37 /* init copy all the temps */
38 if (mp_init_size (&x0, B) != MP_OKAY)
39 goto ERR;
40 if (mp_init_size (&x1, a->used - B) != MP_OKAY)
41 goto X0;
37 /* init copy all the temps */
38 if (mp_init_size(&x0, B) != MP_OKAY)
39 goto ERR;
40 if (mp_init_size(&x1, a->used - B) != MP_OKAY)
41 goto X0;
4242
43 /* init temps */
44 if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
45 goto X1;
46 if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
47 goto T1;
48 if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
49 goto T2;
50 if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
51 goto X0X0;
43 /* init temps */
44 if (mp_init_size(&t1, a->used * 2) != MP_OKAY)
45 goto X1;
46 if (mp_init_size(&t2, a->used * 2) != MP_OKAY)
47 goto T1;
48 if (mp_init_size(&x0x0, B * 2) != MP_OKAY)
49 goto T2;
50 if (mp_init_size(&x1x1, (a->used - B) * 2) != MP_OKAY)
51 goto X0X0;
5252
53 {
54 int x;
55 mp_digit *dst, *src;
53 {
54 int x;
55 mp_digit *dst, *src;
5656
57 src = a->dp;
57 src = a->dp;
5858
59 /* now shift the digits */
60 dst = x0.dp;
61 for (x = 0; x < B; x++) {
62 *dst++ = *src++;
63 }
59 /* now shift the digits */
60 dst = x0.dp;
61 for (x = 0; x < B; x++) {
62 *dst++ = *src++;
63 }
6464
65 dst = x1.dp;
66 for (x = B; x < a->used; x++) {
67 *dst++ = *src++;
68 }
69 }
65 dst = x1.dp;
66 for (x = B; x < a->used; x++) {
67 *dst++ = *src++;
68 }
69 }
7070
71 x0.used = B;
72 x1.used = a->used - B;
71 x0.used = B;
72 x1.used = a->used - B;
7373
74 mp_clamp (&x0);
74 mp_clamp(&x0);
7575
76 /* now calc the products x0*x0 and x1*x1 */
77 if (mp_sqr (&x0, &x0x0) != MP_OKAY)
78 goto X1X1; /* x0x0 = x0*x0 */
79 if (mp_sqr (&x1, &x1x1) != MP_OKAY)
80 goto X1X1; /* x1x1 = x1*x1 */
76 /* now calc the products x0*x0 and x1*x1 */
77 if (mp_sqr(&x0, &x0x0) != MP_OKAY)
78 goto X1X1; /* x0x0 = x0*x0 */
79 if (mp_sqr(&x1, &x1x1) != MP_OKAY)
80 goto X1X1; /* x1x1 = x1*x1 */
8181
82 /* now calc (x1+x0)**2 */
83 if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
84 goto X1X1; /* t1 = x1 - x0 */
85 if (mp_sqr (&t1, &t1) != MP_OKAY)
86 goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
82 /* now calc (x1+x0)**2 */
83 if (s_mp_add(&x1, &x0, &t1) != MP_OKAY)
84 goto X1X1; /* t1 = x1 - x0 */
85 if (mp_sqr(&t1, &t1) != MP_OKAY)
86 goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
8787
88 /* add x0y0 */
89 if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
90 goto X1X1; /* t2 = x0x0 + x1x1 */
91 if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
92 goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
88 /* add x0y0 */
89 if (s_mp_add(&x0x0, &x1x1, &t2) != MP_OKAY)
90 goto X1X1; /* t2 = x0x0 + x1x1 */
91 if (s_mp_sub(&t1, &t2, &t1) != MP_OKAY)
92 goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
9393
94 /* shift by B */
95 if (mp_lshd (&t1, B) != MP_OKAY)
96 goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
97 if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
98 goto X1X1; /* x1x1 = x1x1 << 2*B */
94 /* shift by B */
95 if (mp_lshd(&t1, B) != MP_OKAY)
96 goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
97 if (mp_lshd(&x1x1, B * 2) != MP_OKAY)
98 goto X1X1; /* x1x1 = x1x1 << 2*B */
9999
100 if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
101 goto X1X1; /* t1 = x0x0 + t1 */
102 if (mp_add (&t1, &x1x1, b) != MP_OKAY)
103 goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
100 if (mp_add(&x0x0, &t1, &t1) != MP_OKAY)
101 goto X1X1; /* t1 = x0x0 + t1 */
102 if (mp_add(&t1, &x1x1, b) != MP_OKAY)
103 goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
104104
105 err = MP_OKAY;
105 err = MP_OKAY;
106106
107 X1X1:mp_clear (&x1x1);
108 X0X0:mp_clear (&x0x0);
109 T2:mp_clear (&t2);
110 T1:mp_clear (&t1);
111 X1:mp_clear (&x1);
112 X0:mp_clear (&x0);
107 X1X1:
108 mp_clear(&x1x1);
109 X0X0:
110 mp_clear(&x0x0);
111 T2:
112 mp_clear(&t2);
113 T1:
114 mp_clear(&t1);
115 X1:
116 mp_clear(&x1);
117 X0:
118 mp_clear(&x0);
113119 ERR:
114 return err;
120 return err;
115121 }
116122 #endif
117123
118 /* $Source$ */
119 /* $Revision$ */
120 /* $Date$ */
124 /* ref: $Format:%D$ */
125 /* git commit: $Format:%H$ */
126 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* computes least common multiple as |a*b|/(a, b) */
18 int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
18 int mp_lcm(const mp_int *a, const mp_int *b, mp_int *c)
1919 {
20 int res;
21 mp_int t1, t2;
20 int res;
21 mp_int t1, t2;
2222
2323
24 if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
25 return res;
26 }
24 if ((res = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) {
25 return res;
26 }
2727
28 /* t1 = get the GCD of the two inputs */
29 if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
30 goto LBL_T;
31 }
28 /* t1 = get the GCD of the two inputs */
29 if ((res = mp_gcd(a, b, &t1)) != MP_OKAY) {
30 goto LBL_T;
31 }
3232
33 /* divide the smallest by the GCD */
34 if (mp_cmp_mag(a, b) == MP_LT) {
35 /* store quotient in t2 such that t2 * b is the LCM */
36 if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
37 goto LBL_T;
38 }
39 res = mp_mul(b, &t2, c);
40 } else {
41 /* store quotient in t2 such that t2 * a is the LCM */
42 if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
43 goto LBL_T;
44 }
45 res = mp_mul(a, &t2, c);
46 }
33 /* divide the smallest by the GCD */
34 if (mp_cmp_mag(a, b) == MP_LT) {
35 /* store quotient in t2 such that t2 * b is the LCM */
36 if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
37 goto LBL_T;
38 }
39 res = mp_mul(b, &t2, c);
40 } else {
41 /* store quotient in t2 such that t2 * a is the LCM */
42 if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
43 goto LBL_T;
44 }
45 res = mp_mul(a, &t2, c);
46 }
4747
48 /* fix the sign to positive */
49 c->sign = MP_ZPOS;
48 /* fix the sign to positive */
49 c->sign = MP_ZPOS;
5050
5151 LBL_T:
52 mp_clear_multi (&t1, &t2, NULL);
53 return res;
52 mp_clear_multi(&t1, &t2, NULL);
53 return res;
5454 }
5555 #endif
5656
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
57 /* ref: $Format:%D$ */
58 /* git commit: $Format:%H$ */
59 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* shift left a certain amount of digits */
18 int mp_lshd (mp_int * a, int b)
18 int mp_lshd(mp_int *a, int b)
1919 {
20 int x, res;
20 int x, res;
2121
22 /* if its less than zero return */
23 if (b <= 0) {
24 return MP_OKAY;
25 }
22 /* if its less than zero return */
23 if (b <= 0) {
24 return MP_OKAY;
25 }
26 /* no need to shift 0 around */
27 if (mp_iszero(a) == MP_YES) {
28 return MP_OKAY;
29 }
2630
27 /* grow to fit the new digits */
28 if (a->alloc < (a->used + b)) {
29 if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
30 return res;
31 }
32 }
31 /* grow to fit the new digits */
32 if (a->alloc < (a->used + b)) {
33 if ((res = mp_grow(a, a->used + b)) != MP_OKAY) {
34 return res;
35 }
36 }
3337
34 {
35 mp_digit *top, *bottom;
38 {
39 mp_digit *top, *bottom;
3640
37 /* increment the used by the shift amount then copy upwards */
38 a->used += b;
41 /* increment the used by the shift amount then copy upwards */
42 a->used += b;
3943
40 /* top */
41 top = a->dp + a->used - 1;
44 /* top */
45 top = a->dp + a->used - 1;
4246
43 /* base */
44 bottom = (a->dp + a->used - 1) - b;
47 /* base */
48 bottom = (a->dp + a->used - 1) - b;
4549
46 /* much like mp_rshd this is implemented using a sliding window
47 * except the window goes the otherway around. Copying from
48 * the bottom to the top. see bn_mp_rshd.c for more info.
49 */
50 for (x = a->used - 1; x >= b; x--) {
51 *top-- = *bottom--;
52 }
50 /* much like mp_rshd this is implemented using a sliding window
51 * except the window goes the otherway around. Copying from
52 * the bottom to the top. see bn_mp_rshd.c for more info.
53 */
54 for (x = a->used - 1; x >= b; x--) {
55 *top-- = *bottom--;
56 }
5357
54 /* zero the lower digits */
55 top = a->dp;
56 for (x = 0; x < b; x++) {
57 *top++ = 0;
58 }
59 }
60 return MP_OKAY;
58 /* zero the lower digits */
59 top = a->dp;
60 for (x = 0; x < b; x++) {
61 *top++ = 0;
62 }
63 }
64 return MP_OKAY;
6165 }
6266 #endif
6367
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
68 /* ref: $Format:%D$ */
69 /* git commit: $Format:%H$ */
70 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */
18 int
19 mp_mod (mp_int * a, mp_int * b, mp_int * c)
18 int mp_mod(const mp_int *a, const mp_int *b, mp_int *c)
2019 {
21 mp_int t;
22 int res;
20 mp_int t;
21 int res;
2322
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
23 if ((res = mp_init_size(&t, b->used)) != MP_OKAY) {
24 return res;
25 }
2726
28 if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
27 if ((res = mp_div(a, b, NULL, &t)) != MP_OKAY) {
28 mp_clear(&t);
29 return res;
30 }
3231
33 if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) {
34 res = MP_OKAY;
35 mp_exch (&t, c);
36 } else {
37 res = mp_add (b, &t, c);
38 }
32 if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) {
33 res = MP_OKAY;
34 mp_exch(&t, c);
35 } else {
36 res = mp_add(b, &t, c);
37 }
3938
40 mp_clear (&t);
41 return res;
39 mp_clear(&t);
40 return res;
4241 }
4342 #endif
4443
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
44 /* ref: $Format:%D$ */
45 /* git commit: $Format:%H$ */
46 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* calc a value mod 2**b */
18 int
19 mp_mod_2d (mp_int * a, int b, mp_int * c)
18 int mp_mod_2d(const mp_int *a, int b, mp_int *c)
2019 {
21 int x, res;
20 int x, res;
2221
23 /* if b is <= 0 then zero the int */
24 if (b <= 0) {
25 mp_zero (c);
26 return MP_OKAY;
27 }
22 /* if b is <= 0 then zero the int */
23 if (b <= 0) {
24 mp_zero(c);
25 return MP_OKAY;
26 }
2827
29 /* if the modulus is larger than the value than return */
30 if (b >= (int) (a->used * DIGIT_BIT)) {
31 res = mp_copy (a, c);
32 return res;
33 }
28 /* if the modulus is larger than the value than return */
29 if (b >= (a->used * DIGIT_BIT)) {
30 res = mp_copy(a, c);
31 return res;
32 }
3433
35 /* copy */
36 if ((res = mp_copy (a, c)) != MP_OKAY) {
37 return res;
38 }
34 /* copy */
35 if ((res = mp_copy(a, c)) != MP_OKAY) {
36 return res;
37 }
3938
40 /* zero digits above the last digit of the modulus */
41 for (x = (b / DIGIT_BIT) + (((b % DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) {
42 c->dp[x] = 0;
43 }
44 /* clear the digit that is not completely outside/inside the modulus */
45 c->dp[b / DIGIT_BIT] &=
46 (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
47 mp_clamp (c);
48 return MP_OKAY;
39 /* zero digits above the last digit of the modulus */
40 for (x = (b / DIGIT_BIT) + (((b % DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) {
41 c->dp[x] = 0;
42 }
43 /* clear the digit that is not completely outside/inside the modulus */
44 c->dp[b / DIGIT_BIT] &=
45 ((mp_digit)1 << (mp_digit)(b % DIGIT_BIT)) - (mp_digit)1;
46 mp_clamp(c);
47 return MP_OKAY;
4948 }
5049 #endif
5150
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
51 /* ref: $Format:%D$ */
52 /* git commit: $Format:%H$ */
53 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 int
18 mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
17 int mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c)
1918 {
20 return mp_div_d(a, b, NULL, c);
19 return mp_div_d(a, b, NULL, c);
2120 }
2221 #endif
2322
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
23 /* ref: $Format:%D$ */
24 /* git commit: $Format:%H$ */
25 /* commit time: $Format:%ai$ */
2020 * The method is slightly modified to shift B unconditionally upto just under
2121 * the leading bit of b. This saves alot of multiple precision shifting.
2222 */
23 int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
23 int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b)
2424 {
25 int x, bits, res;
25 int x, bits, res;
2626
27 /* how many bits of last digit does b use */
28 bits = mp_count_bits (b) % DIGIT_BIT;
27 /* how many bits of last digit does b use */
28 bits = mp_count_bits(b) % DIGIT_BIT;
2929
30 if (b->used > 1) {
31 if ((res = mp_2expt (a, ((b->used - 1) * DIGIT_BIT) + bits - 1)) != MP_OKAY) {
32 return res;
33 }
34 } else {
35 mp_set(a, 1);
36 bits = 1;
37 }
30 if (b->used > 1) {
31 if ((res = mp_2expt(a, ((b->used - 1) * DIGIT_BIT) + bits - 1)) != MP_OKAY) {
32 return res;
33 }
34 } else {
35 mp_set(a, 1uL);
36 bits = 1;
37 }
3838
3939
40 /* now compute C = A * B mod b */
41 for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
42 if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
43 return res;
44 }
45 if (mp_cmp_mag (a, b) != MP_LT) {
46 if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
47 return res;
40 /* now compute C = A * B mod b */
41 for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
42 if ((res = mp_mul_2(a, a)) != MP_OKAY) {
43 return res;
4844 }
49 }
50 }
45 if (mp_cmp_mag(a, b) != MP_LT) {
46 if ((res = s_mp_sub(a, b, a)) != MP_OKAY) {
47 return res;
48 }
49 }
50 }
5151
52 return MP_OKAY;
52 return MP_OKAY;
5353 }
5454 #endif
5555
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
56 /* ref: $Format:%D$ */
57 /* git commit: $Format:%H$ */
58 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* computes xR**-1 == x (mod N) via Montgomery Reduction */
18 int
19 mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
18 int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
2019 {
21 int ix, res, digs;
22 mp_digit mu;
20 int ix, res, digs;
21 mp_digit mu;
2322
24 /* can the fast reduction [comba] method be used?
25 *
26 * Note that unlike in mul you're safely allowed *less*
27 * than the available columns [255 per default] since carries
28 * are fixed up in the inner loop.
29 */
30 digs = (n->used * 2) + 1;
31 if ((digs < MP_WARRAY) &&
32 (n->used <
33 (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
34 return fast_mp_montgomery_reduce (x, n, rho);
35 }
23 /* can the fast reduction [comba] method be used?
24 *
25 * Note that unlike in mul you're safely allowed *less*
26 * than the available columns [255 per default] since carries
27 * are fixed up in the inner loop.
28 */
29 digs = (n->used * 2) + 1;
30 if ((digs < (int)MP_WARRAY) &&
31 (x->used <= (int)MP_WARRAY) &&
32 (n->used <
33 (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) {
34 return fast_mp_montgomery_reduce(x, n, rho);
35 }
3636
37 /* grow the input as required */
38 if (x->alloc < digs) {
39 if ((res = mp_grow (x, digs)) != MP_OKAY) {
40 return res;
41 }
42 }
43 x->used = digs;
37 /* grow the input as required */
38 if (x->alloc < digs) {
39 if ((res = mp_grow(x, digs)) != MP_OKAY) {
40 return res;
41 }
42 }
43 x->used = digs;
4444
45 for (ix = 0; ix < n->used; ix++) {
46 /* mu = ai * rho mod b
47 *
48 * The value of rho must be precalculated via
49 * montgomery_setup() such that
50 * it equals -1/n0 mod b this allows the
51 * following inner loop to reduce the
52 * input one digit at a time
53 */
54 mu = (mp_digit) (((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK);
45 for (ix = 0; ix < n->used; ix++) {
46 /* mu = ai * rho mod b
47 *
48 * The value of rho must be precalculated via
49 * montgomery_setup() such that
50 * it equals -1/n0 mod b this allows the
51 * following inner loop to reduce the
52 * input one digit at a time
53 */
54 mu = (mp_digit)(((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK);
5555
56 /* a = a + mu * m * b**i */
57 {
58 int iy;
59 mp_digit *tmpn, *tmpx, u;
60 mp_word r;
56 /* a = a + mu * m * b**i */
57 {
58 int iy;
59 mp_digit *tmpn, *tmpx, u;
60 mp_word r;
6161
62 /* alias for digits of the modulus */
63 tmpn = n->dp;
62 /* alias for digits of the modulus */
63 tmpn = n->dp;
6464
65 /* alias for the digits of x [the input] */
66 tmpx = x->dp + ix;
65 /* alias for the digits of x [the input] */
66 tmpx = x->dp + ix;
6767
68 /* set the carry to zero */
69 u = 0;
68 /* set the carry to zero */
69 u = 0;
7070
71 /* Multiply and add in place */
72 for (iy = 0; iy < n->used; iy++) {
73 /* compute product and sum */
74 r = ((mp_word)mu * (mp_word)*tmpn++) +
75 (mp_word) u + (mp_word) *tmpx;
71 /* Multiply and add in place */
72 for (iy = 0; iy < n->used; iy++) {
73 /* compute product and sum */
74 r = ((mp_word)mu * (mp_word)*tmpn++) +
75 (mp_word)u + (mp_word)*tmpx;
7676
77 /* get carry */
78 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
77 /* get carry */
78 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
7979
80 /* fix digit */
81 *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
82 }
83 /* At this point the ix'th digit of x should be zero */
80 /* fix digit */
81 *tmpx++ = (mp_digit)(r & (mp_word)MP_MASK);
82 }
83 /* At this point the ix'th digit of x should be zero */
8484
8585
86 /* propagate carries upwards as required*/
87 while (u != 0) {
88 *tmpx += u;
89 u = *tmpx >> DIGIT_BIT;
90 *tmpx++ &= MP_MASK;
86 /* propagate carries upwards as required*/
87 while (u != 0u) {
88 *tmpx += u;
89 u = *tmpx >> DIGIT_BIT;
90 *tmpx++ &= MP_MASK;
91 }
9192 }
92 }
93 }
93 }
9494
95 /* at this point the n.used'th least
96 * significant digits of x are all zero
97 * which means we can shift x to the
98 * right by n.used digits and the
99 * residue is unchanged.
100 */
95 /* at this point the n.used'th least
96 * significant digits of x are all zero
97 * which means we can shift x to the
98 * right by n.used digits and the
99 * residue is unchanged.
100 */
101101
102 /* x = x/b**n.used */
103 mp_clamp(x);
104 mp_rshd (x, n->used);
102 /* x = x/b**n.used */
103 mp_clamp(x);
104 mp_rshd(x, n->used);
105105
106 /* if x >= n then x = x - n */
107 if (mp_cmp_mag (x, n) != MP_LT) {
108 return s_mp_sub (x, n, x);
109 }
106 /* if x >= n then x = x - n */
107 if (mp_cmp_mag(x, n) != MP_LT) {
108 return s_mp_sub(x, n, x);
109 }
110110
111 return MP_OKAY;
111 return MP_OKAY;
112112 }
113113 #endif
114114
115 /* $Source$ */
116 /* $Revision$ */
117 /* $Date$ */
115 /* ref: $Format:%D$ */
116 /* git commit: $Format:%H$ */
117 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* setups the montgomery reduction stuff */
18 int
19 mp_montgomery_setup (mp_int * n, mp_digit * rho)
18 int mp_montgomery_setup(const mp_int *n, mp_digit *rho)
2019 {
21 mp_digit x, b;
20 mp_digit x, b;
2221
23 /* fast inversion mod 2**k
24 *
25 * Based on the fact that
26 *
27 * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
28 * => 2*X*A - X*X*A*A = 1
29 * => 2*(1) - (1) = 1
30 */
31 b = n->dp[0];
22 /* fast inversion mod 2**k
23 *
24 * Based on the fact that
25 *
26 * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
27 * => 2*X*A - X*X*A*A = 1
28 * => 2*(1) - (1) = 1
29 */
30 b = n->dp[0];
3231
33 if ((b & 1) == 0) {
34 return MP_VAL;
35 }
32 if ((b & 1u) == 0u) {
33 return MP_VAL;
34 }
3635
37 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
38 x *= 2 - (b * x); /* here x*a==1 mod 2**8 */
36 x = (((b + 2u) & 4u) << 1) + b; /* here x*a==1 mod 2**4 */
37 x *= 2u - (b * x); /* here x*a==1 mod 2**8 */
3938 #if !defined(MP_8BIT)
40 x *= 2 - (b * x); /* here x*a==1 mod 2**16 */
39 x *= 2u - (b * x); /* here x*a==1 mod 2**16 */
4140 #endif
4241 #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
43 x *= 2 - (b * x); /* here x*a==1 mod 2**32 */
42 x *= 2u - (b * x); /* here x*a==1 mod 2**32 */
4443 #endif
4544 #ifdef MP_64BIT
46 x *= 2 - (b * x); /* here x*a==1 mod 2**64 */
45 x *= 2u - (b * x); /* here x*a==1 mod 2**64 */
4746 #endif
4847
49 /* rho = -1/m mod b */
50 *rho = (mp_digit)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
48 /* rho = -1/m mod b */
49 *rho = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - x) & MP_MASK;
5150
52 return MP_OKAY;
51 return MP_OKAY;
5352 }
5453 #endif
5554
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
55 /* ref: $Format:%D$ */
56 /* git commit: $Format:%H$ */
57 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* high level multiplication (handles sign) */
18 int mp_mul (mp_int * a, mp_int * b, mp_int * c)
18 int mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
1919 {
20 int res, neg;
21 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
20 int res, neg;
21 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
2222
23 /* use Toom-Cook? */
23 /* use Toom-Cook? */
2424 #ifdef BN_MP_TOOM_MUL_C
25 if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
26 res = mp_toom_mul(a, b, c);
27 } else
25 if (MIN(a->used, b->used) >= TOOM_MUL_CUTOFF) {
26 res = mp_toom_mul(a, b, c);
27 } else
2828 #endif
2929 #ifdef BN_MP_KARATSUBA_MUL_C
30 /* use Karatsuba? */
31 if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
32 res = mp_karatsuba_mul (a, b, c);
33 } else
30 /* use Karatsuba? */
31 if (MIN(a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
32 res = mp_karatsuba_mul(a, b, c);
33 } else
3434 #endif
35 {
36 /* can we use the fast multiplier?
37 *
38 * The fast multiplier can be used if the output will
39 * have less than MP_WARRAY digits and the number of
40 * digits won't affect carry propagation
41 */
42 int digs = a->used + b->used + 1;
35 {
36 /* can we use the fast multiplier?
37 *
38 * The fast multiplier can be used if the output will
39 * have less than MP_WARRAY digits and the number of
40 * digits won't affect carry propagation
41 */
42 int digs = a->used + b->used + 1;
4343
4444 #ifdef BN_FAST_S_MP_MUL_DIGS_C
45 if ((digs < MP_WARRAY) &&
46 (MIN(a->used, b->used) <=
47 (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
48 res = fast_s_mp_mul_digs (a, b, c, digs);
49 } else
45 if ((digs < (int)MP_WARRAY) &&
46 (MIN(a->used, b->used) <=
47 (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) {
48 res = fast_s_mp_mul_digs(a, b, c, digs);
49 } else
5050 #endif
51 {
51 {
5252 #ifdef BN_S_MP_MUL_DIGS_C
53 res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
53 res = s_mp_mul(a, b, c); /* uses s_mp_mul_digs */
5454 #else
55 res = MP_VAL;
55 res = MP_VAL;
5656 #endif
57 }
58 }
59 c->sign = (c->used > 0) ? neg : MP_ZPOS;
60 return res;
57 }
58 }
59 c->sign = (c->used > 0) ? neg : MP_ZPOS;
60 return res;
6161 }
6262 #endif
6363
64 /* $Source$ */
65 /* $Revision$ */
66 /* $Date$ */
64 /* ref: $Format:%D$ */
65 /* git commit: $Format:%H$ */
66 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* b = a*2 */
18 int mp_mul_2(mp_int * a, mp_int * b)
18 int mp_mul_2(const mp_int *a, mp_int *b)
1919 {
20 int x, res, oldused;
20 int x, res, oldused;
2121
22 /* grow to accomodate result */
23 if (b->alloc < (a->used + 1)) {
24 if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
25 return res;
26 }
27 }
22 /* grow to accomodate result */
23 if (b->alloc < (a->used + 1)) {
24 if ((res = mp_grow(b, a->used + 1)) != MP_OKAY) {
25 return res;
26 }
27 }
2828
29 oldused = b->used;
30 b->used = a->used;
29 oldused = b->used;
30 b->used = a->used;
3131
32 {
33 mp_digit r, rr, *tmpa, *tmpb;
32 {
33 mp_digit r, rr, *tmpa, *tmpb;
3434
35 /* alias for source */
36 tmpa = a->dp;
37
38 /* alias for dest */
39 tmpb = b->dp;
35 /* alias for source */
36 tmpa = a->dp;
4037
41 /* carry */
42 r = 0;
43 for (x = 0; x < a->used; x++) {
44
45 /* get what will be the *next* carry bit from the
46 * MSB of the current digit
38 /* alias for dest */
39 tmpb = b->dp;
40
41 /* carry */
42 r = 0;
43 for (x = 0; x < a->used; x++) {
44
45 /* get what will be the *next* carry bit from the
46 * MSB of the current digit
47 */
48 rr = *tmpa >> (mp_digit)(DIGIT_BIT - 1);
49
50 /* now shift up this digit, add in the carry [from the previous] */
51 *tmpb++ = ((*tmpa++ << 1uL) | r) & MP_MASK;
52
53 /* copy the carry that would be from the source
54 * digit into the next iteration
55 */
56 r = rr;
57 }
58
59 /* new leading digit? */
60 if (r != 0u) {
61 /* add a MSB which is always 1 at this point */
62 *tmpb = 1;
63 ++(b->used);
64 }
65
66 /* now zero any excess digits on the destination
67 * that we didn't write to
4768 */
48 rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
49
50 /* now shift up this digit, add in the carry [from the previous] */
51 *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
52
53 /* copy the carry that would be from the source
54 * digit into the next iteration
55 */
56 r = rr;
57 }
58
59 /* new leading digit? */
60 if (r != 0) {
61 /* add a MSB which is always 1 at this point */
62 *tmpb = 1;
63 ++(b->used);
64 }
65
66 /* now zero any excess digits on the destination
67 * that we didn't write to
68 */
69 tmpb = b->dp + b->used;
70 for (x = b->used; x < oldused; x++) {
71 *tmpb++ = 0;
72 }
73 }
74 b->sign = a->sign;
75 return MP_OKAY;
69 tmpb = b->dp + b->used;
70 for (x = b->used; x < oldused; x++) {
71 *tmpb++ = 0;
72 }
73 }
74 b->sign = a->sign;
75 return MP_OKAY;
7676 }
7777 #endif
7878
79 /* $Source$ */
80 /* $Revision$ */
81 /* $Date$ */
79 /* ref: $Format:%D$ */
80 /* git commit: $Format:%H$ */
81 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* shift left by a certain bit count */
18 int mp_mul_2d (mp_int * a, int b, mp_int * c)
18 int mp_mul_2d(const mp_int *a, int b, mp_int *c)
1919 {
20 mp_digit d;
21 int res;
20 mp_digit d;
21 int res;
2222
23 /* copy */
24 if (a != c) {
25 if ((res = mp_copy (a, c)) != MP_OKAY) {
26 return res;
27 }
28 }
23 /* copy */
24 if (a != c) {
25 if ((res = mp_copy(a, c)) != MP_OKAY) {
26 return res;
27 }
28 }
2929
30 if (c->alloc < (int)(c->used + (b / DIGIT_BIT) + 1)) {
31 if ((res = mp_grow (c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) {
32 return res;
33 }
34 }
30 if (c->alloc < (c->used + (b / DIGIT_BIT) + 1)) {
31 if ((res = mp_grow(c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) {
32 return res;
33 }
34 }
3535
36 /* shift by as many digits in the bit count */
37 if (b >= (int)DIGIT_BIT) {
38 if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
39 return res;
40 }
41 }
36 /* shift by as many digits in the bit count */
37 if (b >= DIGIT_BIT) {
38 if ((res = mp_lshd(c, b / DIGIT_BIT)) != MP_OKAY) {
39 return res;
40 }
41 }
4242
43 /* shift any bit count < DIGIT_BIT */
44 d = (mp_digit) (b % DIGIT_BIT);
45 if (d != 0) {
46 mp_digit *tmpc, shift, mask, r, rr;
47 int x;
43 /* shift any bit count < DIGIT_BIT */
44 d = (mp_digit)(b % DIGIT_BIT);
45 if (d != 0u) {
46 mp_digit *tmpc, shift, mask, r, rr;
47 int x;
4848
49 /* bitmask for carries */
50 mask = (((mp_digit)1) << d) - 1;
49 /* bitmask for carries */
50 mask = ((mp_digit)1 << d) - (mp_digit)1;
5151
52 /* shift for msbs */
53 shift = DIGIT_BIT - d;
52 /* shift for msbs */
53 shift = (mp_digit)DIGIT_BIT - d;
5454
55 /* alias */
56 tmpc = c->dp;
55 /* alias */
56 tmpc = c->dp;
5757
58 /* carry */
59 r = 0;
60 for (x = 0; x < c->used; x++) {
61 /* get the higher bits of the current word */
62 rr = (*tmpc >> shift) & mask;
58 /* carry */
59 r = 0;
60 for (x = 0; x < c->used; x++) {
61 /* get the higher bits of the current word */
62 rr = (*tmpc >> shift) & mask;
6363
64 /* shift the current word and OR in the carry */
65 *tmpc = ((*tmpc << d) | r) & MP_MASK;
66 ++tmpc;
64 /* shift the current word and OR in the carry */
65 *tmpc = ((*tmpc << d) | r) & MP_MASK;
66 ++tmpc;
6767
68 /* set the carry to the carry bits of the current word */
69 r = rr;
70 }
71
72 /* set final carry */
73 if (r != 0) {
74 c->dp[(c->used)++] = r;
75 }
76 }
77 mp_clamp (c);
78 return MP_OKAY;
68 /* set the carry to the carry bits of the current word */
69 r = rr;
70 }
71
72 /* set final carry */
73 if (r != 0u) {
74 c->dp[(c->used)++] = r;
75 }
76 }
77 mp_clamp(c);
78 return MP_OKAY;
7979 }
8080 #endif
8181
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
82 /* ref: $Format:%D$ */
83 /* git commit: $Format:%H$ */
84 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* multiply by a digit */
18 int
19 mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
18 int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c)
2019 {
21 mp_digit u, *tmpa, *tmpc;
22 mp_word r;
23 int ix, res, olduse;
20 mp_digit u, *tmpa, *tmpc;
21 mp_word r;
22 int ix, res, olduse;
2423
25 /* make sure c is big enough to hold a*b */
26 if (c->alloc < (a->used + 1)) {
27 if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
28 return res;
29 }
30 }
24 /* make sure c is big enough to hold a*b */
25 if (c->alloc < (a->used + 1)) {
26 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27 return res;
28 }
29 }
3130
32 /* get the original destinations used count */
33 olduse = c->used;
31 /* get the original destinations used count */
32 olduse = c->used;
3433
35 /* set the sign */
36 c->sign = a->sign;
34 /* set the sign */
35 c->sign = a->sign;
3736
38 /* alias for a->dp [source] */
39 tmpa = a->dp;
37 /* alias for a->dp [source] */
38 tmpa = a->dp;
4039
41 /* alias for c->dp [dest] */
42 tmpc = c->dp;
40 /* alias for c->dp [dest] */
41 tmpc = c->dp;
4342
44 /* zero carry */
45 u = 0;
43 /* zero carry */
44 u = 0;
4645
47 /* compute columns */
48 for (ix = 0; ix < a->used; ix++) {
49 /* compute product and carry sum for this term */
50 r = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b);
46 /* compute columns */
47 for (ix = 0; ix < a->used; ix++) {
48 /* compute product and carry sum for this term */
49 r = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b);
5150
52 /* mask off higher bits to get a single digit */
53 *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
51 /* mask off higher bits to get a single digit */
52 *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK);
5453
55 /* send carry into next iteration */
56 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
57 }
54 /* send carry into next iteration */
55 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
56 }
5857
59 /* store final carry [if any] and increment ix offset */
60 *tmpc++ = u;
61 ++ix;
58 /* store final carry [if any] and increment ix offset */
59 *tmpc++ = u;
60 ++ix;
6261
63 /* now zero digits above the top */
64 while (ix++ < olduse) {
65 *tmpc++ = 0;
66 }
62 /* now zero digits above the top */
63 while (ix++ < olduse) {
64 *tmpc++ = 0;
65 }
6766
68 /* set used count */
69 c->used = a->used + 1;
70 mp_clamp(c);
67 /* set used count */
68 c->used = a->used + 1;
69 mp_clamp(c);
7170
72 return MP_OKAY;
71 return MP_OKAY;
7372 }
7473 #endif
7574
76 /* $Source$ */
77 /* $Revision$ */
78 /* $Date$ */
75 /* ref: $Format:%D$ */
76 /* git commit: $Format:%H$ */
77 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* d = a * b (mod c) */
18 int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
18 int mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
1919 {
20 int res;
21 mp_int t;
20 int res;
21 mp_int t;
2222
23 if ((res = mp_init (&t)) != MP_OKAY) {
24 return res;
25 }
23 if ((res = mp_init_size(&t, c->used)) != MP_OKAY) {
24 return res;
25 }
2626
27 if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
28 mp_clear (&t);
29 return res;
30 }
31 res = mp_mod (&t, c, d);
32 mp_clear (&t);
33 return res;
27 if ((res = mp_mul(a, b, &t)) != MP_OKAY) {
28 mp_clear(&t);
29 return res;
30 }
31 res = mp_mod(&t, c, d);
32 mp_clear(&t);
33 return res;
3434 }
3535 #endif
3636
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
37 /* ref: $Format:%D$ */
38 /* git commit: $Format:%H$ */
39 /* commit time: $Format:%ai$ */
1717 /* wrapper function for mp_n_root_ex()
1818 * computes c = (a)**(1/b) such that (c)**b <= a and (c+1)**b > a
1919 */
20 int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
20 int mp_n_root(const mp_int *a, mp_digit b, mp_int *c)
2121 {
22 return mp_n_root_ex(a, b, c, 0);
22 return mp_n_root_ex(a, b, c, 0);
2323 }
2424
2525 #endif
2626
27 /* $Source$ */
28 /* $Revision$ */
29 /* $Date$ */
27 /* ref: $Format:%D$ */
28 /* git commit: $Format:%H$ */
29 /* commit time: $Format:%ai$ */
2424 * each step involves a fair bit. This is not meant to
2525 * find huge roots [square and cube, etc].
2626 */
27 int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast)
27 int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
2828 {
29 mp_int t1, t2, t3;
30 int res, neg;
29 mp_int t1, t2, t3, a_;
30 int res;
3131
32 /* input must be positive if b is even */
33 if (((b & 1) == 0) && (a->sign == MP_NEG)) {
34 return MP_VAL;
35 }
32 /* input must be positive if b is even */
33 if (((b & 1u) == 0u) && (a->sign == MP_NEG)) {
34 return MP_VAL;
35 }
3636
37 if ((res = mp_init (&t1)) != MP_OKAY) {
38 return res;
39 }
37 if ((res = mp_init(&t1)) != MP_OKAY) {
38 return res;
39 }
4040
41 if ((res = mp_init (&t2)) != MP_OKAY) {
42 goto LBL_T1;
43 }
41 if ((res = mp_init(&t2)) != MP_OKAY) {
42 goto LBL_T1;
43 }
4444
45 if ((res = mp_init (&t3)) != MP_OKAY) {
46 goto LBL_T2;
47 }
45 if ((res = mp_init(&t3)) != MP_OKAY) {
46 goto LBL_T2;
47 }
4848
49 /* if a is negative fudge the sign but keep track */
50 neg = a->sign;
51 a->sign = MP_ZPOS;
49 /* if a is negative fudge the sign but keep track */
50 a_ = *a;
51 a_.sign = MP_ZPOS;
5252
53 /* t2 = 2 */
54 mp_set (&t2, 2);
53 /* t2 = 2 */
54 mp_set(&t2, 2uL);
5555
56 do {
57 /* t1 = t2 */
58 if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
59 goto LBL_T3;
60 }
61
62 /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
63
64 /* t3 = t1**(b-1) */
65 if ((res = mp_expt_d_ex (&t1, b - 1, &t3, fast)) != MP_OKAY) {
66 goto LBL_T3;
67 }
68
69 /* numerator */
70 /* t2 = t1**b */
71 if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {
72 goto LBL_T3;
73 }
74
75 /* t2 = t1**b - a */
76 if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {
77 goto LBL_T3;
78 }
79
80 /* denominator */
81 /* t3 = t1**(b-1) * b */
82 if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {
83 goto LBL_T3;
84 }
85
86 /* t3 = (t1**b - a)/(b * t1**(b-1)) */
87 if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {
88 goto LBL_T3;
89 }
90
91 if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
92 goto LBL_T3;
93 }
94 } while (mp_cmp (&t1, &t2) != MP_EQ);
95
96 /* result can be off by a few so check */
97 for (;;) {
98 if ((res = mp_expt_d_ex (&t1, b, &t2, fast)) != MP_OKAY) {
99 goto LBL_T3;
100 }
101
102 if (mp_cmp (&t2, a) == MP_GT) {
103 if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
56 do {
57 /* t1 = t2 */
58 if ((res = mp_copy(&t2, &t1)) != MP_OKAY) {
10459 goto LBL_T3;
10560 }
106 } else {
107 break;
108 }
109 }
11061
111 /* reset the sign of a first */
112 a->sign = neg;
62 /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
11363
114 /* set the result */
115 mp_exch (&t1, c);
64 /* t3 = t1**(b-1) */
65 if ((res = mp_expt_d_ex(&t1, b - 1u, &t3, fast)) != MP_OKAY) {
66 goto LBL_T3;
67 }
11668
117 /* set the sign of the result */
118 c->sign = neg;
69 /* numerator */
70 /* t2 = t1**b */
71 if ((res = mp_mul(&t3, &t1, &t2)) != MP_OKAY) {
72 goto LBL_T3;
73 }
11974
120 res = MP_OKAY;
75 /* t2 = t1**b - a */
76 if ((res = mp_sub(&t2, &a_, &t2)) != MP_OKAY) {
77 goto LBL_T3;
78 }
12179
122 LBL_T3:mp_clear (&t3);
123 LBL_T2:mp_clear (&t2);
124 LBL_T1:mp_clear (&t1);
125 return res;
80 /* denominator */
81 /* t3 = t1**(b-1) * b */
82 if ((res = mp_mul_d(&t3, b, &t3)) != MP_OKAY) {
83 goto LBL_T3;
84 }
85
86 /* t3 = (t1**b - a)/(b * t1**(b-1)) */
87 if ((res = mp_div(&t2, &t3, &t3, NULL)) != MP_OKAY) {
88 goto LBL_T3;
89 }
90
91 if ((res = mp_sub(&t1, &t3, &t2)) != MP_OKAY) {
92 goto LBL_T3;
93 }
94 } while (mp_cmp(&t1, &t2) != MP_EQ);
95
96 /* result can be off by a few so check */
97 for (;;) {
98 if ((res = mp_expt_d_ex(&t1, b, &t2, fast)) != MP_OKAY) {
99 goto LBL_T3;
100 }
101
102 if (mp_cmp(&t2, &a_) == MP_GT) {
103 if ((res = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) {
104 goto LBL_T3;
105 }
106 } else {
107 break;
108 }
109 }
110
111 /* set the result */
112 mp_exch(&t1, c);
113
114 /* set the sign of the result */
115 c->sign = a->sign;
116
117 res = MP_OKAY;
118
119 LBL_T3:
120 mp_clear(&t3);
121 LBL_T2:
122 mp_clear(&t2);
123 LBL_T1:
124 mp_clear(&t1);
125 return res;
126126 }
127127 #endif
128128
129 /* $Source$ */
130 /* $Revision$ */
131 /* $Date$ */
129 /* ref: $Format:%D$ */
130 /* git commit: $Format:%H$ */
131 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* b = -a */
18 int mp_neg (mp_int * a, mp_int * b)
18 int mp_neg(const mp_int *a, mp_int *b)
1919 {
20 int res;
21 if (a != b) {
22 if ((res = mp_copy (a, b)) != MP_OKAY) {
23 return res;
24 }
25 }
20 int res;
21 if (a != b) {
22 if ((res = mp_copy(a, b)) != MP_OKAY) {
23 return res;
24 }
25 }
2626
27 if (mp_iszero(b) != MP_YES) {
28 b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
29 } else {
30 b->sign = MP_ZPOS;
31 }
27 if (mp_iszero(b) != MP_YES) {
28 b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
29 } else {
30 b->sign = MP_ZPOS;
31 }
3232
33 return MP_OKAY;
33 return MP_OKAY;
3434 }
3535 #endif
3636
37 /* $Source$ */
38 /* $Revision$ */
39 /* $Date$ */
37 /* ref: $Format:%D$ */
38 /* git commit: $Format:%H$ */
39 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* OR two ints together */
18 int mp_or (mp_int * a, mp_int * b, mp_int * c)
18 int mp_or(const mp_int *a, const mp_int *b, mp_int *c)
1919 {
20 int res, ix, px;
21 mp_int t, *x;
20 int res, ix, px;
21 mp_int t;
22 const mp_int *x;
2223
23 if (a->used > b->used) {
24 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
25 return res;
26 }
27 px = b->used;
28 x = b;
29 } else {
30 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
31 return res;
32 }
33 px = a->used;
34 x = a;
35 }
24 if (a->used > b->used) {
25 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
3637
37 for (ix = 0; ix < px; ix++) {
38 t.dp[ix] |= x->dp[ix];
39 }
40 mp_clamp (&t);
41 mp_exch (c, &t);
42 mp_clear (&t);
43 return MP_OKAY;
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] |= x->dp[ix];
40 }
41 mp_clamp(&t);
42 mp_exch(c, &t);
43 mp_clear(&t);
44 return MP_OKAY;
4445 }
4546 #endif
4647
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
48 /* ref: $Format:%D$ */
49 /* git commit: $Format:%H$ */
50 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* performs one Fermat test.
18 *
18 *
1919 * If "a" were prime then b**a == b (mod a) since the order of
2020 * the multiplicative sub-group would be phi(a) = a-1. That means
2121 * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
2222 *
2323 * Sets result to 1 if the congruence holds, or zero otherwise.
2424 */
25 int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
25 int mp_prime_fermat(const mp_int *a, const mp_int *b, int *result)
2626 {
27 mp_int t;
28 int err;
27 mp_int t;
28 int err;
2929
30 /* default to composite */
31 *result = MP_NO;
30 /* default to composite */
31 *result = MP_NO;
3232
33 /* ensure b > 1 */
34 if (mp_cmp_d(b, 1) != MP_GT) {
35 return MP_VAL;
36 }
33 /* ensure b > 1 */
34 if (mp_cmp_d(b, 1uL) != MP_GT) {
35 return MP_VAL;
36 }
3737
38 /* init t */
39 if ((err = mp_init (&t)) != MP_OKAY) {
40 return err;
41 }
38 /* init t */
39 if ((err = mp_init(&t)) != MP_OKAY) {
40 return err;
41 }
4242
43 /* compute t = b**a mod a */
44 if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
45 goto LBL_T;
46 }
43 /* compute t = b**a mod a */
44 if ((err = mp_exptmod(b, a, a, &t)) != MP_OKAY) {
45 goto LBL_T;
46 }
4747
48 /* is it equal to b? */
49 if (mp_cmp (&t, b) == MP_EQ) {
50 *result = MP_YES;
51 }
48 /* is it equal to b? */
49 if (mp_cmp(&t, b) == MP_EQ) {
50 *result = MP_YES;
51 }
5252
53 err = MP_OKAY;
54 LBL_T:mp_clear (&t);
55 return err;
53 err = MP_OKAY;
54 LBL_T:
55 mp_clear(&t);
56 return err;
5657 }
5758 #endif
5859
59 /* $Source$ */
60 /* $Revision$ */
61 /* $Date$ */
60 /* ref: $Format:%D$ */
61 /* git commit: $Format:%H$ */
62 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* determines if an integers is divisible by one
17 /* determines if an integers is divisible by one
1818 * of the first PRIME_SIZE primes or not
1919 *
2020 * sets result to 0 if not, 1 if yes
2121 */
22 int mp_prime_is_divisible (mp_int * a, int *result)
22 int mp_prime_is_divisible(const mp_int *a, int *result)
2323 {
24 int err, ix;
25 mp_digit res;
24 int err, ix;
25 mp_digit res;
2626
27 /* default to not */
28 *result = MP_NO;
27 /* default to not */
28 *result = MP_NO;
2929
30 for (ix = 0; ix < PRIME_SIZE; ix++) {
31 /* what is a mod LBL_prime_tab[ix] */
32 if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
33 return err;
34 }
30 for (ix = 0; ix < PRIME_SIZE; ix++) {
31 /* what is a mod LBL_prime_tab[ix] */
32 if ((err = mp_mod_d(a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
33 return err;
34 }
3535
36 /* is the residue zero? */
37 if (res == 0) {
38 *result = MP_YES;
39 return MP_OKAY;
40 }
41 }
36 /* is the residue zero? */
37 if (res == 0u) {
38 *result = MP_YES;
39 return MP_OKAY;
40 }
41 }
4242
43 return MP_OKAY;
43 return MP_OKAY;
4444 }
4545 #endif
4646
47 /* $Source$ */
48 /* $Revision$ */
49 /* $Date$ */
47 /* ref: $Format:%D$ */
48 /* git commit: $Format:%H$ */
49 /* commit time: $Format:%ai$ */
2121 *
2222 * Sets result to 1 if probably prime, 0 otherwise
2323 */
24 int mp_prime_is_prime (mp_int * a, int t, int *result)
24 int mp_prime_is_prime(const mp_int *a, int t, int *result)
2525 {
26 mp_int b;
27 int ix, err, res;
26 mp_int b;
27 int ix, err, res;
2828
29 /* default to no */
30 *result = MP_NO;
29 /* default to no */
30 *result = MP_NO;
3131
32 /* valid value of t? */
33 if ((t <= 0) || (t > PRIME_SIZE)) {
34 return MP_VAL;
35 }
32 /* valid value of t? */
33 if ((t <= 0) || (t > PRIME_SIZE)) {
34 return MP_VAL;
35 }
3636
37 /* is the input equal to one of the primes in the table? */
38 for (ix = 0; ix < PRIME_SIZE; ix++) {
37 /* is the input equal to one of the primes in the table? */
38 for (ix = 0; ix < PRIME_SIZE; ix++) {
3939 if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
4040 *result = 1;
4141 return MP_OKAY;
4242 }
43 }
43 }
4444
45 /* first perform trial division */
46 if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
47 return err;
48 }
45 /* first perform trial division */
46 if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) {
47 return err;
48 }
4949
50 /* return if it was trivially divisible */
51 if (res == MP_YES) {
52 return MP_OKAY;
53 }
50 /* return if it was trivially divisible */
51 if (res == MP_YES) {
52 return MP_OKAY;
53 }
5454
55 /* now perform the miller-rabin rounds */
56 if ((err = mp_init (&b)) != MP_OKAY) {
57 return err;
58 }
55 /* now perform the miller-rabin rounds */
56 if ((err = mp_init(&b)) != MP_OKAY) {
57 return err;
58 }
5959
60 for (ix = 0; ix < t; ix++) {
61 /* set the prime */
62 mp_set (&b, ltm_prime_tab[ix]);
60 for (ix = 0; ix < t; ix++) {
61 /* set the prime */
62 mp_set(&b, ltm_prime_tab[ix]);
6363
64 if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
65 goto LBL_B;
66 }
64 if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
65 goto LBL_B;
66 }
6767
68 if (res == MP_NO) {
69 goto LBL_B;
70 }
71 }
68 if (res == MP_NO) {
69 goto LBL_B;
70 }
71 }
7272
73 /* passed the test */
74 *result = MP_YES;
75 LBL_B:mp_clear (&b);
76 return err;
73 /* passed the test */
74 *result = MP_YES;
75 LBL_B:
76 mp_clear(&b);
77 return err;
7778 }
7879 #endif
7980
80 /* $Source$ */
81 /* $Revision$ */
82 /* $Date$ */
81 /* ref: $Format:%D$ */
82 /* git commit: $Format:%H$ */
83 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* Miller-Rabin test of "a" to the base of "b" as described in
17 /* Miller-Rabin test of "a" to the base of "b" as described in
1818 * HAC pp. 139 Algorithm 4.24
1919 *
2020 * Sets result to 0 if definitely composite or 1 if probably prime.
21 * Randomly the chance of error is no more than 1/4 and often
21 * Randomly the chance of error is no more than 1/4 and often
2222 * very much lower.
2323 */
24 int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
24 int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result)
2525 {
26 mp_int n1, y, r;
27 int s, j, err;
26 mp_int n1, y, r;
27 int s, j, err;
2828
29 /* default */
30 *result = MP_NO;
29 /* default */
30 *result = MP_NO;
3131
32 /* ensure b > 1 */
33 if (mp_cmp_d(b, 1) != MP_GT) {
34 return MP_VAL;
35 }
32 /* ensure b > 1 */
33 if (mp_cmp_d(b, 1uL) != MP_GT) {
34 return MP_VAL;
35 }
3636
37 /* get n1 = a - 1 */
38 if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
39 return err;
40 }
41 if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
42 goto LBL_N1;
43 }
37 /* get n1 = a - 1 */
38 if ((err = mp_init_copy(&n1, a)) != MP_OKAY) {
39 return err;
40 }
41 if ((err = mp_sub_d(&n1, 1uL, &n1)) != MP_OKAY) {
42 goto LBL_N1;
43 }
4444
45 /* set 2**s * r = n1 */
46 if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
47 goto LBL_N1;
48 }
45 /* set 2**s * r = n1 */
46 if ((err = mp_init_copy(&r, &n1)) != MP_OKAY) {
47 goto LBL_N1;
48 }
4949
50 /* count the number of least significant bits
51 * which are zero
52 */
53 s = mp_cnt_lsb(&r);
50 /* count the number of least significant bits
51 * which are zero
52 */
53 s = mp_cnt_lsb(&r);
5454
55 /* now divide n - 1 by 2**s */
56 if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
57 goto LBL_R;
58 }
55 /* now divide n - 1 by 2**s */
56 if ((err = mp_div_2d(&r, s, &r, NULL)) != MP_OKAY) {
57 goto LBL_R;
58 }
5959
60 /* compute y = b**r mod a */
61 if ((err = mp_init (&y)) != MP_OKAY) {
62 goto LBL_R;
63 }
64 if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
65 goto LBL_Y;
66 }
60 /* compute y = b**r mod a */
61 if ((err = mp_init(&y)) != MP_OKAY) {
62 goto LBL_R;
63 }
64 if ((err = mp_exptmod(b, &r, a, &y)) != MP_OKAY) {
65 goto LBL_Y;
66 }
6767
68 /* if y != 1 and y != n1 do */
69 if ((mp_cmp_d (&y, 1) != MP_EQ) && (mp_cmp (&y, &n1) != MP_EQ)) {
70 j = 1;
71 /* while j <= s-1 and y != n1 */
72 while ((j <= (s - 1)) && (mp_cmp (&y, &n1) != MP_EQ)) {
73 if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
68 /* if y != 1 and y != n1 do */
69 if ((mp_cmp_d(&y, 1uL) != MP_EQ) && (mp_cmp(&y, &n1) != MP_EQ)) {
70 j = 1;
71 /* while j <= s-1 and y != n1 */
72 while ((j <= (s - 1)) && (mp_cmp(&y, &n1) != MP_EQ)) {
73 if ((err = mp_sqrmod(&y, a, &y)) != MP_OKAY) {
74 goto LBL_Y;
75 }
76
77 /* if y == 1 then composite */
78 if (mp_cmp_d(&y, 1uL) == MP_EQ) {
79 goto LBL_Y;
80 }
81
82 ++j;
83 }
84
85 /* if y != n1 then composite */
86 if (mp_cmp(&y, &n1) != MP_EQ) {
7487 goto LBL_Y;
7588 }
89 }
7690
77 /* if y == 1 then composite */
78 if (mp_cmp_d (&y, 1) == MP_EQ) {
79 goto LBL_Y;
80 }
81
82 ++j;
83 }
84
85 /* if y != n1 then composite */
86 if (mp_cmp (&y, &n1) != MP_EQ) {
87 goto LBL_Y;
88 }
89 }
90
91 /* probably prime now */
92 *result = MP_YES;
93 LBL_Y:mp_clear (&y);
94 LBL_R:mp_clear (&r);
95 LBL_N1:mp_clear (&n1);
96 return err;
91 /* probably prime now */
92 *result = MP_YES;
93 LBL_Y:
94 mp_clear(&y);
95 LBL_R:
96 mp_clear(&r);
97 LBL_N1:
98 mp_clear(&n1);
99 return err;
97100 }
98101 #endif
99102
100 /* $Source$ */
101 /* $Revision$ */
102 /* $Date$ */
103 /* ref: $Format:%D$ */
104 /* git commit: $Format:%H$ */
105 /* commit time: $Format:%ai$ */
3737 if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
3838 /* find which prime it is bigger than */
3939 for (x = PRIME_SIZE - 2; x >= 0; x--) {
40 if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
41 if (bbs_style == 1) {
42 /* ok we found a prime smaller or
43 * equal [so the next is larger]
44 *
45 * however, the prime must be
46 * congruent to 3 mod 4
47 */
48 if ((ltm_prime_tab[x + 1] & 3) != 3) {
49 /* scan upwards for a prime congruent to 3 mod 4 */
50 for (y = x + 1; y < PRIME_SIZE; y++) {
51 if ((ltm_prime_tab[y] & 3) == 3) {
52 mp_set(a, ltm_prime_tab[y]);
53 return MP_OKAY;
54 }
55 }
56 }
57 } else {
58 mp_set(a, ltm_prime_tab[x + 1]);
59 return MP_OKAY;
60 }
61 }
40 if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
41 if (bbs_style == 1) {
42 /* ok we found a prime smaller or
43 * equal [so the next is larger]
44 *
45 * however, the prime must be
46 * congruent to 3 mod 4
47 */
48 if ((ltm_prime_tab[x + 1] & 3u) != 3u) {
49 /* scan upwards for a prime congruent to 3 mod 4 */
50 for (y = x + 1; y < PRIME_SIZE; y++) {
51 if ((ltm_prime_tab[y] & 3u) == 3u) {
52 mp_set(a, ltm_prime_tab[y]);
53 return MP_OKAY;
54 }
55 }
56 }
57 } else {
58 mp_set(a, ltm_prime_tab[x + 1]);
59 return MP_OKAY;
60 }
61 }
6262 }
6363 /* at this point a maybe 1 */
64 if (mp_cmp_d(a, 1) == MP_EQ) {
65 mp_set(a, 2);
64 if (mp_cmp_d(a, 1uL) == MP_EQ) {
65 mp_set(a, 2uL);
6666 return MP_OKAY;
6767 }
6868 /* fall through to the sieve */
7979
8080 if (bbs_style == 1) {
8181 /* if a mod 4 != 3 subtract the correct value to make it so */
82 if ((a->dp[0] & 3) != 3) {
83 if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
82 if ((a->dp[0] & 3u) != 3u) {
83 if ((err = mp_sub_d(a, (a->dp[0] & 3u) + 1u, a)) != MP_OKAY) {
84 return err;
85 };
8486 }
8587 } else {
8688 if (mp_iseven(a) == MP_YES) {
8789 /* force odd */
88 if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
90 if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) {
8991 return err;
9092 }
9193 }
115117
116118 /* compute the new residue without using division */
117119 for (x = 1; x < PRIME_SIZE; x++) {
118 /* add the step to each residue */
119 res_tab[x] += kstep;
120 /* add the step to each residue */
121 res_tab[x] += kstep;
120122
121 /* subtract the modulus [instead of using division] */
122 if (res_tab[x] >= ltm_prime_tab[x]) {
123 res_tab[x] -= ltm_prime_tab[x];
124 }
123 /* subtract the modulus [instead of using division] */
124 if (res_tab[x] >= ltm_prime_tab[x]) {
125 res_tab[x] -= ltm_prime_tab[x];
126 }
125127
126 /* set flag if zero */
127 if (res_tab[x] == 0) {
128 y = 1;
129 }
128 /* set flag if zero */
129 if (res_tab[x] == 0u) {
130 y = 1;
131 }
130132 }
131 } while ((y == 1) && (step < ((((mp_digit)1) << DIGIT_BIT) - kstep)));
133 } while ((y == 1) && (step < (((mp_digit)1 << DIGIT_BIT) - kstep)));
132134
133135 /* add the step */
134136 if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
136138 }
137139
138140 /* if didn't pass sieve and step == MAX then skip test */
139 if ((y == 1) && (step >= ((((mp_digit)1) << DIGIT_BIT) - kstep))) {
141 if ((y == 1) && (step >= (((mp_digit)1 << DIGIT_BIT) - kstep))) {
140142 continue;
141143 }
142144
143145 /* is this prime? */
144146 for (x = 0; x < t; x++) {
145 mp_set(&b, ltm_prime_tab[x]);
146 if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
147 goto LBL_ERR;
148 }
149 if (res == MP_NO) {
150 break;
151 }
147 mp_set(&b, ltm_prime_tab[x]);
148 if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
149 goto LBL_ERR;
150 }
151 if (res == MP_NO) {
152 break;
153 }
152154 }
153155
154156 if (res == MP_YES) {
164166
165167 #endif
166168
167 /* $Source$ */
168 /* $Revision$ */
169 /* $Date$ */
169 /* ref: $Format:%D$ */
170 /* git commit: $Format:%H$ */
171 /* commit time: $Format:%ai$ */
1818 static const struct {
1919 int k, t;
2020 } sizes[] = {
21 { 128, 28 },
22 { 256, 16 },
23 { 384, 10 },
24 { 512, 7 },
25 { 640, 6 },
26 { 768, 5 },
27 { 896, 4 },
28 { 1024, 4 }
21 { 128, 28 },
22 { 256, 16 },
23 { 384, 10 },
24 { 512, 7 },
25 { 640, 6 },
26 { 768, 5 },
27 { 896, 4 },
28 { 1024, 4 }
2929 };
3030
3131 /* returns # of RM trials required for a given bit size */
3434 int x;
3535
3636 for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
37 if (sizes[x].k == size) {
38 return sizes[x].t;
39 } else if (sizes[x].k > size) {
40 return (x == 0) ? sizes[0].t : sizes[x - 1].t;
41 }
37 if (sizes[x].k == size) {
38 return sizes[x].t;
39 } else if (sizes[x].k > size) {
40 return (x == 0) ? sizes[0].t : sizes[x - 1].t;
41 }
4242 }
4343 return sizes[x-1].t + 1;
4444 }
4646
4747 #endif
4848
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
49 /* ref: $Format:%D$ */
50 /* git commit: $Format:%H$ */
51 /* commit time: $Format:%ai$ */
1717 /* makes a truly random prime of a given size (bits),
1818 *
1919 * Flags are as follows:
20 *
20 *
2121 * LTM_PRIME_BBS - make prime congruent to 3 mod 4
2222 * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
2323 * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
4848 bsize = (size>>3) + ((size&7)?1:0);
4949
5050 /* we need a buffer of bsize bytes */
51 tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
51 tmp = OPT_CAST(unsigned char) XMALLOC((size_t)bsize);
5252 if (tmp == NULL) {
5353 return MP_MEM;
5454 }
6161 maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
6262 if ((flags & LTM_PRIME_2MSB_ON) != 0) {
6363 maskOR_msb |= 0x80 >> ((9 - size) & 7);
64 }
64 }
6565
6666 /* get the maskOR_lsb */
6767 maskOR_lsb = 1;
7575 err = MP_VAL;
7676 goto error;
7777 }
78
78
7979 /* work over the MSbyte */
8080 tmp[0] &= maskAND;
8181 tmp[0] |= 1 << ((size - 1) & 7);
8585 tmp[bsize-1] |= maskOR_lsb;
8686
8787 /* read it in */
88 if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; }
88 if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) {
89 goto error;
90 }
8991
9092 /* is it prime? */
91 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
92 if (res == MP_NO) {
93 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) {
94 goto error;
95 }
96 if (res == MP_NO) {
9397 continue;
9498 }
9599
96100 if ((flags & LTM_PRIME_SAFE) != 0) {
97101 /* see if (a-1)/2 is prime */
98 if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; }
99 if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; }
100
102 if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) {
103 goto error;
104 }
105 if ((err = mp_div_2(a, a)) != MP_OKAY) {
106 goto error;
107 }
108
101109 /* is it prime? */
102 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
110 if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) {
111 goto error;
112 }
103113 }
104114 } while (res == MP_NO);
105115
106116 if ((flags & LTM_PRIME_SAFE) != 0) {
107117 /* restore a to the original value */
108 if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; }
109 if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; }
118 if ((err = mp_mul_2(a, a)) != MP_OKAY) {
119 goto error;
120 }
121 if ((err = mp_add_d(a, 1uL, a)) != MP_OKAY) {
122 goto error;
123 }
110124 }
111125
112126 err = MP_OKAY;
118132
119133 #endif
120134
121 /* $Source$ */
122 /* $Revision$ */
123 /* $Date$ */
135 /* ref: $Format:%D$ */
136 /* git commit: $Format:%H$ */
137 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* returns size of ASCII reprensentation */
18 int mp_radix_size (mp_int * a, int radix, int *size)
18 int mp_radix_size(const mp_int *a, int radix, int *size)
1919 {
20 int res, digs;
21 mp_int t;
22 mp_digit d;
20 int res, digs;
21 mp_int t;
22 mp_digit d;
2323
24 *size = 0;
24 *size = 0;
2525
26 /* make sure the radix is in range */
27 if ((radix < 2) || (radix > 64)) {
28 return MP_VAL;
29 }
26 /* make sure the radix is in range */
27 if ((radix < 2) || (radix > 64)) {
28 return MP_VAL;
29 }
3030
31 if (mp_iszero(a) == MP_YES) {
32 *size = 2;
33 return MP_OKAY;
34 }
31 if (mp_iszero(a) == MP_YES) {
32 *size = 2;
33 return MP_OKAY;
34 }
3535
36 /* special case for binary */
37 if (radix == 2) {
38 *size = mp_count_bits (a) + ((a->sign == MP_NEG) ? 1 : 0) + 1;
39 return MP_OKAY;
40 }
36 /* special case for binary */
37 if (radix == 2) {
38 *size = mp_count_bits(a) + ((a->sign == MP_NEG) ? 1 : 0) + 1;
39 return MP_OKAY;
40 }
4141
42 /* digs is the digit count */
43 digs = 0;
42 /* digs is the digit count */
43 digs = 0;
4444
45 /* if it's negative add one for the sign */
46 if (a->sign == MP_NEG) {
47 ++digs;
48 }
45 /* if it's negative add one for the sign */
46 if (a->sign == MP_NEG) {
47 ++digs;
48 }
4949
50 /* init a copy of the input */
51 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
52 return res;
53 }
50 /* init a copy of the input */
51 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
52 return res;
53 }
5454
55 /* force temp to positive */
56 t.sign = MP_ZPOS;
55 /* force temp to positive */
56 t.sign = MP_ZPOS;
5757
58 /* fetch out all of the digits */
59 while (mp_iszero (&t) == MP_NO) {
60 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
61 mp_clear (&t);
62 return res;
63 }
64 ++digs;
65 }
66 mp_clear (&t);
58 /* fetch out all of the digits */
59 while (mp_iszero(&t) == MP_NO) {
60 if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
61 mp_clear(&t);
62 return res;
63 }
64 ++digs;
65 }
66 mp_clear(&t);
6767
68 /* return digs + 1, the 1 is for the NULL byte that would be required. */
69 *size = digs + 1;
70 return MP_OKAY;
68 /* return digs + 1, the 1 is for the NULL byte that would be required. */
69 *size = digs + 1;
70 return MP_OKAY;
7171 }
7272
7373 #endif
7474
75 /* $Source$ */
76 /* $Revision$ */
77 /* $Date$ */
75 /* ref: $Format:%D$ */
76 /* git commit: $Format:%H$ */
77 /* commit time: $Format:%ai$ */
1616
1717 /* chars used in radix conversions */
1818 const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
19 const uint8_t mp_s_rmap_reverse[] = {
20 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* ()*+,-./ */
21 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */
22 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */
23 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* @ABCDEFG */
24 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* HIJKLMNO */
25 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* PQRSTUVW */
26 0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */
27 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, /* `abcdefg */
28 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, /* hijklmno */
29 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, /* pqrstuvw */
30 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, /* xyz{|}~. */
31 };
32 const size_t mp_s_rmap_reverse_sz = sizeof(mp_s_rmap_reverse);
1933 #endif
2034
21 /* $Source$ */
22 /* $Revision$ */
23 /* $Date$ */
35 /* ref: $Format:%D$ */
36 /* git commit: $Format:%H$ */
37 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 #if defined(MP_8BIT) || defined(MP_16BIT)
18 #define MP_GEN_RANDOM_SHIFT DIGIT_BIT
19 #else
20 #if MP_GEN_RANDOM_MAX == 0xffffffffu
21 #define MP_GEN_RANDOM_SHIFT 32
22 #elif MP_GEN_RANDOM_MAX == 32767
23 /* SHRT_MAX */
24 #define MP_GEN_RANDOM_SHIFT 15
25 #elif MP_GEN_RANDOM_MAX == 2147483647
26 /* INT_MAX */
27 #define MP_GEN_RANDOM_SHIFT 31
28 #elif !defined(MP_GEN_RANDOM_SHIFT)
29 #error Thou shalt define their own valid MP_GEN_RANDOM_SHIFT
30 #endif
31 #endif
32
1733 /* makes a pseudo-random int of a given size */
18 int
19 mp_rand (mp_int * a, int digits)
34 static mp_digit s_gen_random(void)
2035 {
21 int res;
22 mp_digit d;
36 mp_digit d = 0, msk = 0;
37 do {
38 d <<= MP_GEN_RANDOM_SHIFT;
39 d |= ((mp_digit) MP_GEN_RANDOM());
40 msk <<= MP_GEN_RANDOM_SHIFT;
41 msk |= (MP_MASK & MP_GEN_RANDOM_MAX);
42 } while ((MP_MASK & msk) != MP_MASK);
43 d &= MP_MASK;
44 return d;
45 }
2346
24 mp_zero (a);
25 if (digits <= 0) {
26 return MP_OKAY;
27 }
47 int mp_rand(mp_int *a, int digits)
48 {
49 int res;
50 mp_digit d;
2851
29 /* first place a random non-zero digit */
30 do {
31 d = ((mp_digit) abs (MP_GEN_RANDOM())) & MP_MASK;
32 } while (d == 0);
52 mp_zero(a);
53 if (digits <= 0) {
54 return MP_OKAY;
55 }
3356
34 if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
35 return res;
36 }
57 /* first place a random non-zero digit */
58 do {
59 d = s_gen_random();
60 } while (d == 0u);
3761
38 while (--digits > 0) {
39 if ((res = mp_lshd (a, 1)) != MP_OKAY) {
62 if ((res = mp_add_d(a, d, a)) != MP_OKAY) {
4063 return res;
41 }
64 }
4265
43 if ((res = mp_add_d (a, ((mp_digit) abs (MP_GEN_RANDOM())), a)) != MP_OKAY) {
44 return res;
45 }
46 }
66 while (--digits > 0) {
67 if ((res = mp_lshd(a, 1)) != MP_OKAY) {
68 return res;
69 }
4770
48 return MP_OKAY;
71 if ((res = mp_add_d(a, s_gen_random(), a)) != MP_OKAY) {
72 return res;
73 }
74 }
75
76 return MP_OKAY;
4977 }
5078 #endif
5179
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
80 /* ref: $Format:%D$ */
81 /* git commit: $Format:%H$ */
82 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* read a string [ASCII] in a given radix */
18 int mp_read_radix (mp_int * a, const char *str, int radix)
18 int mp_read_radix(mp_int *a, const char *str, int radix)
1919 {
20 int y, res, neg;
21 char ch;
20 int y, res, neg;
21 unsigned pos;
22 char ch;
2223
23 /* zero the digit bignum */
24 mp_zero(a);
24 /* zero the digit bignum */
25 mp_zero(a);
2526
26 /* make sure the radix is ok */
27 if ((radix < 2) || (radix > 64)) {
28 return MP_VAL;
29 }
27 /* make sure the radix is ok */
28 if ((radix < 2) || (radix > 64)) {
29 return MP_VAL;
30 }
3031
31 /* if the leading digit is a
32 * minus set the sign to negative.
33 */
34 if (*str == '-') {
35 ++str;
36 neg = MP_NEG;
37 } else {
38 neg = MP_ZPOS;
39 }
32 /* if the leading digit is a
33 * minus set the sign to negative.
34 */
35 if (*str == '-') {
36 ++str;
37 neg = MP_NEG;
38 } else {
39 neg = MP_ZPOS;
40 }
4041
41 /* set the integer to the default of zero */
42 mp_zero (a);
43
44 /* process each digit of the string */
45 while (*str != '\0') {
46 /* if the radix <= 36 the conversion is case insensitive
47 * this allows numbers like 1AB and 1ab to represent the same value
48 * [e.g. in hex]
49 */
50 ch = (radix <= 36) ? (char)toupper((int)*str) : *str;
51 for (y = 0; y < 64; y++) {
52 if (ch == mp_s_rmap[y]) {
42 /* set the integer to the default of zero */
43 mp_zero(a);
44
45 /* process each digit of the string */
46 while (*str != '\0') {
47 /* if the radix <= 36 the conversion is case insensitive
48 * this allows numbers like 1AB and 1ab to represent the same value
49 * [e.g. in hex]
50 */
51 ch = (radix <= 36) ? (char)toupper((int)*str) : *str;
52 pos = (unsigned)(ch - '(');
53 if (mp_s_rmap_reverse_sz < pos) {
5354 break;
5455 }
55 }
56 y = (int)mp_s_rmap_reverse[pos];
5657
57 /* if the char was found in the map
58 * and is less than the given radix add it
59 * to the number, otherwise exit the loop.
60 */
61 if (y < radix) {
62 if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
58 /* if the char was found in the map
59 * and is less than the given radix add it
60 * to the number, otherwise exit the loop.
61 */
62 if ((y == 0xff) || (y >= radix)) {
63 break;
64 }
65 if ((res = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
6366 return res;
6467 }
65 if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
68 if ((res = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
6669 return res;
6770 }
68 } else {
69 break;
70 }
71 ++str;
72 }
73
74 /* set the sign only if a != 0 */
75 if (mp_iszero(a) != MP_YES) {
76 a->sign = neg;
77 }
78 return MP_OKAY;
71 ++str;
72 }
73
74 /* if an illegal character was found, fail. */
75 if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) {
76 mp_zero(a);
77 return MP_VAL;
78 }
79
80 /* set the sign only if a != 0 */
81 if (mp_iszero(a) != MP_YES) {
82 a->sign = neg;
83 }
84 return MP_OKAY;
7985 }
8086 #endif
8187
82 /* $Source$ */
83 /* $Revision$ */
84 /* $Date$ */
88 /* ref: $Format:%D$ */
89 /* git commit: $Format:%H$ */
90 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* read signed bin, big endian, first byte is 0==positive or 1==negative */
18 int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
18 int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c)
1919 {
20 int res;
20 int res;
2121
22 /* read magnitude */
23 if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
24 return res;
25 }
22 /* read magnitude */
23 if ((res = mp_read_unsigned_bin(a, b + 1, c - 1)) != MP_OKAY) {
24 return res;
25 }
2626
27 /* first byte is 0 for positive, non-zero for negative */
28 if (b[0] == 0) {
29 a->sign = MP_ZPOS;
30 } else {
31 a->sign = MP_NEG;
32 }
27 /* first byte is 0 for positive, non-zero for negative */
28 if (b[0] == (unsigned char)0) {
29 a->sign = MP_ZPOS;
30 } else {
31 a->sign = MP_NEG;
32 }
3333
34 return MP_OKAY;
34 return MP_OKAY;
3535 }
3636 #endif
3737
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
38 /* ref: $Format:%D$ */
39 /* git commit: $Format:%H$ */
40 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* reads a unsigned char array, assumes the msb is stored first [big endian] */
18 int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
18 int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c)
1919 {
20 int res;
20 int res;
2121
22 /* make sure there are at least two digits */
23 if (a->alloc < 2) {
24 if ((res = mp_grow(a, 2)) != MP_OKAY) {
25 return res;
26 }
27 }
22 /* make sure there are at least two digits */
23 if (a->alloc < 2) {
24 if ((res = mp_grow(a, 2)) != MP_OKAY) {
25 return res;
26 }
27 }
2828
29 /* zero the int */
30 mp_zero (a);
29 /* zero the int */
30 mp_zero(a);
3131
32 /* read the bytes in */
33 while (c-- > 0) {
34 if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
35 return res;
36 }
32 /* read the bytes in */
33 while (c-- > 0) {
34 if ((res = mp_mul_2d(a, 8, a)) != MP_OKAY) {
35 return res;
36 }
3737
3838 #ifndef MP_8BIT
39 a->dp[0] |= *b++;
40 a->used += 1;
39 a->dp[0] |= *b++;
40 a->used += 1;
4141 #else
42 a->dp[0] = (*b & MP_MASK);
43 a->dp[1] |= ((*b++ >> 7U) & 1);
44 a->used += 2;
42 a->dp[0] = (*b & MP_MASK);
43 a->dp[1] |= ((*b++ >> 7) & 1u);
44 a->used += 2;
4545 #endif
46 }
47 mp_clamp (a);
48 return MP_OKAY;
46 }
47 mp_clamp(a);
48 return MP_OKAY;
4949 }
5050 #endif
5151
52 /* $Source$ */
53 /* $Revision$ */
54 /* $Date$ */
52 /* ref: $Format:%D$ */
53 /* git commit: $Format:%H$ */
54 /* commit time: $Format:%ai$ */
1818 * precomputed via mp_reduce_setup.
1919 * From HAC pp.604 Algorithm 14.42
2020 */
21 int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
21 int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
2222 {
23 mp_int q;
24 int res, um = m->used;
23 mp_int q;
24 int res, um = m->used;
2525
26 /* q = x */
27 if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
28 return res;
29 }
26 /* q = x */
27 if ((res = mp_init_copy(&q, x)) != MP_OKAY) {
28 return res;
29 }
3030
31 /* q1 = x / b**(k-1) */
32 mp_rshd (&q, um - 1);
31 /* q1 = x / b**(k-1) */
32 mp_rshd(&q, um - 1);
3333
34 /* according to HAC this optimization is ok */
35 if (((mp_digit) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
36 if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
34 /* according to HAC this optimization is ok */
35 if ((mp_digit)um > ((mp_digit)1 << (DIGIT_BIT - 1))) {
36 if ((res = mp_mul(&q, mu, &q)) != MP_OKAY) {
37 goto CLEANUP;
38 }
39 } else {
40 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
41 if ((res = s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) {
42 goto CLEANUP;
43 }
44 #elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
45 if ((res = fast_s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) {
46 goto CLEANUP;
47 }
48 #else
49 {
50 res = MP_VAL;
51 goto CLEANUP;
52 }
53 #endif
54 }
55
56 /* q3 = q2 / b**(k+1) */
57 mp_rshd(&q, um + 1);
58
59 /* x = x mod b**(k+1), quick (no division) */
60 if ((res = mp_mod_2d(x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
3761 goto CLEANUP;
38 }
39 } else {
40 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
41 if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
62 }
63
64 /* q = q * m mod b**(k+1), quick (no division) */
65 if ((res = s_mp_mul_digs(&q, m, &q, um + 1)) != MP_OKAY) {
4266 goto CLEANUP;
43 }
44 #elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
45 if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
67 }
68
69 /* x = x - q */
70 if ((res = mp_sub(x, &q, x)) != MP_OKAY) {
4671 goto CLEANUP;
47 }
48 #else
49 {
50 res = MP_VAL;
51 goto CLEANUP;
52 }
53 #endif
54 }
72 }
5573
56 /* q3 = q2 / b**(k+1) */
57 mp_rshd (&q, um + 1);
74 /* If x < 0, add b**(k+1) to it */
75 if (mp_cmp_d(x, 0uL) == MP_LT) {
76 mp_set(&q, 1uL);
77 if ((res = mp_lshd(&q, um + 1)) != MP_OKAY)
78 goto CLEANUP;
79 if ((res = mp_add(x, &q, x)) != MP_OKAY)
80 goto CLEANUP;
81 }
5882
59 /* x = x mod b**(k+1), quick (no division) */
60 if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
61 goto CLEANUP;
62 }
63
64 /* q = q * m mod b**(k+1), quick (no division) */
65 if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
66 goto CLEANUP;
67 }
68
69 /* x = x - q */
70 if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
71 goto CLEANUP;
72 }
73
74 /* If x < 0, add b**(k+1) to it */
75 if (mp_cmp_d (x, 0) == MP_LT) {
76 mp_set (&q, 1);
77 if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
78 goto CLEANUP;
79 if ((res = mp_add (x, &q, x)) != MP_OKAY)
80 goto CLEANUP;
81 }
82
83 /* Back off if it's too big */
84 while (mp_cmp (x, m) != MP_LT) {
85 if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
86 goto CLEANUP;
87 }
88 }
83 /* Back off if it's too big */
84 while (mp_cmp(x, m) != MP_LT) {
85 if ((res = s_mp_sub(x, m, x)) != MP_OKAY) {
86 goto CLEANUP;
87 }
88 }
8989
9090 CLEANUP:
91 mp_clear (&q);
91 mp_clear(&q);
9292
93 return res;
93 return res;
9494 }
9595 #endif
9696
97 /* $Source$ */
98 /* $Revision$ */
99 /* $Date$ */
97 /* ref: $Format:%D$ */
98 /* git commit: $Format:%H$ */
99 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* reduces a modulo n where n is of the form 2**p - d */
18 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
18 int mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d)
1919 {
2020 mp_int q;
2121 int p, res;
3131 goto ERR;
3232 }
3333
34 if (d != 1) {
34 if (d != 1u) {
3535 /* q = q * d */
3636 if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
3737 goto ERR;
5757
5858 #endif
5959
60 /* $Source$ */
61 /* $Revision$ */
62 /* $Date$ */
60 /* ref: $Format:%D$ */
61 /* git commit: $Format:%H$ */
62 /* commit time: $Format:%ai$ */
1818 This differs from reduce_2k since "d" can be larger
1919 than a single digit.
2020 */
21 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
21 int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d)
2222 {
2323 mp_int q;
2424 int p, res;
5858
5959 #endif
6060
61 /* $Source$ */
62 /* $Revision$ */
63 /* $Date$ */
61 /* ref: $Format:%D$ */
62 /* git commit: $Format:%H$ */
63 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* determines the setup value */
18 int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
18 int mp_reduce_2k_setup(const mp_int *a, mp_digit *d)
1919 {
2020 int res, p;
2121 mp_int tmp;
22
22
2323 if ((res = mp_init(&tmp)) != MP_OKAY) {
2424 return res;
2525 }
26
26
2727 p = mp_count_bits(a);
2828 if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
2929 mp_clear(&tmp);
3030 return res;
3131 }
32
32
3333 if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
3434 mp_clear(&tmp);
3535 return res;
3636 }
37
37
3838 *d = tmp.dp[0];
3939 mp_clear(&tmp);
4040 return MP_OKAY;
4141 }
4242 #endif
4343
44 /* $Source$ */
45 /* $Revision$ */
46 /* $Date$ */
44 /* ref: $Format:%D$ */
45 /* git commit: $Format:%H$ */
46 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* determines the setup value */
18 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
18 int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d)
1919 {
2020 int res;
2121 mp_int tmp;
22
22
2323 if ((res = mp_init(&tmp)) != MP_OKAY) {
2424 return res;
2525 }
26
26
2727 if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
2828 goto ERR;
2929 }
30
30
3131 if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
3232 goto ERR;
3333 }
34
34
3535 ERR:
3636 mp_clear(&tmp);
3737 return res;
3838 }
3939 #endif
4040
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
41 /* ref: $Format:%D$ */
42 /* git commit: $Format:%H$ */
43 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* determines if mp_reduce_2k can be used */
18 int mp_reduce_is_2k(mp_int *a)
18 int mp_reduce_is_2k(const mp_int *a)
1919 {
2020 int ix, iy, iw;
2121 mp_digit iz;
22
22
2323 if (a->used == 0) {
2424 return MP_NO;
2525 } else if (a->used == 1) {
2828 iy = mp_count_bits(a);
2929 iz = 1;
3030 iw = 1;
31
31
3232 /* Test every bit from the second digit up, must be 1 */
3333 for (ix = DIGIT_BIT; ix < iy; ix++) {
34 if ((a->dp[iw] & iz) == 0) {
35 return MP_NO;
36 }
37 iz <<= 1;
38 if (iz > (mp_digit)MP_MASK) {
39 ++iw;
40 iz = 1;
41 }
34 if ((a->dp[iw] & iz) == 0u) {
35 return MP_NO;
36 }
37 iz <<= 1;
38 if (iz > (mp_digit)MP_MASK) {
39 ++iw;
40 iz = 1;
41 }
4242 }
4343 }
4444 return MP_YES;
4646
4747 #endif
4848
49 /* $Source$ */
50 /* $Revision$ */
51 /* $Date$ */
49 /* ref: $Format:%D$ */
50 /* git commit: $Format:%H$ */
51 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* determines if reduce_2k_l can be used */
18 int mp_reduce_is_2k_l(mp_int *a)
18 int mp_reduce_is_2k_l(const mp_int *a)
1919 {
2020 int ix, iy;
21
21
2222 if (a->used == 0) {
2323 return MP_NO;
2424 } else if (a->used == 1) {
2626 } else if (a->used > 1) {
2727 /* if more than half of the digits are -1 we're sold */
2828 for (iy = ix = 0; ix < a->used; ix++) {
29 if (a->dp[ix] == MP_MASK) {
30 ++iy;
31 }
29 if (a->dp[ix] == MP_MASK) {
30 ++iy;
31 }
3232 }
3333 return (iy >= (a->used/2)) ? MP_YES : MP_NO;
34
34
3535 }
3636 return MP_NO;
3737 }
3838
3939 #endif
4040
41 /* $Source$ */
42 /* $Revision$ */
43 /* $Date$ */
41 /* ref: $Format:%D$ */
42 /* git commit: $Format:%H$ */
43 /* commit time: $Format:%ai$ */
1717 /* pre-calculate the value required for Barrett reduction
1818 * For a given modulus "b" it calulates the value required in "a"
1919 */
20 int mp_reduce_setup (mp_int * a, mp_int * b)
20 int mp_reduce_setup(mp_int *a, const mp_int *b)
2121 {
22 int res;
23
24 if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
25 return res;
26 }
27 return mp_div (a, b, a, NULL);
22 int res;
23
24 if ((res = mp_2expt(a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
25 return res;
26 }
27 return mp_div(a, b, a, NULL);
2828 }
2929 #endif
3030
31 /* $Source$ */
32 /* $Revision$ */
33 /* $Date$ */
31 /* ref: $Format:%D$ */
32 /* git commit: $Format:%H$ */
33 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* shift right a certain amount of digits */
18 void mp_rshd (mp_int * a, int b)
18 void mp_rshd(mp_int *a, int b)
1919 {
20 int x;
20 int x;
2121
22 /* if b <= 0 then ignore it */
23 if (b <= 0) {
24 return;
25 }
22 /* if b <= 0 then ignore it */
23 if (b <= 0) {
24 return;
25 }
2626
27 /* if b > used then simply zero it and return */
28 if (a->used <= b) {
29 mp_zero (a);
30 return;
31 }
27 /* if b > used then simply zero it and return */
28 if (a->used <= b) {
29 mp_zero(a);
30 return;
31 }
3232
33 {
34 mp_digit *bottom, *top;
33 {
34 mp_digit *bottom, *top;
3535
36 /* shift the digits down */
36 /* shift the digits down */
3737
38 /* bottom */
39 bottom = a->dp;
38 /* bottom */
39 bottom = a->dp;
4040
41 /* top [offset into digits] */
42 top = a->dp + b;
41 /* top [offset into digits] */
42 top = a->dp + b;
4343
44 /* this is implemented as a sliding window where
45 * the window is b-digits long and digits from
46 * the top of the window are copied to the bottom
47 *
48 * e.g.
44 /* this is implemented as a sliding window where
45 * the window is b-digits long and digits from
46 * the top of the window are copied to the bottom
47 *
48 * e.g.
4949
50 b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
51 /\ | ---->
52 \-------------------/ ---->
53 */
54 for (x = 0; x < (a->used - b); x++) {
55 *bottom++ = *top++;
56 }
50 b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
51 /\ | ---->
52 \-------------------/ ---->
53 */
54 for (x = 0; x < (a->used - b); x++) {
55 *bottom++ = *top++;
56 }
5757
58 /* zero the top digits */
59 for (; x < a->used; x++) {
60 *bottom++ = 0;
61 }
62 }
63
64 /* remove excess digits */
65 a->used -= b;
58 /* zero the top digits */
59 for (; x < a->used; x++) {
60 *bottom++ = 0;
61 }
62 }
63
64 /* remove excess digits */
65 a->used -= b;
6666 }
6767 #endif
6868
69 /* $Source$ */
70 /* $Revision$ */
71 /* $Date$ */
69 /* ref: $Format:%D$ */
70 /* git commit: $Format:%H$ */
71 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* set to a digit */
18 void mp_set (mp_int * a, mp_digit b)
18 void mp_set(mp_int *a, mp_digit b)
1919 {
20 mp_zero (a);
21 a->dp[0] = b & MP_MASK;
22 a->used = (a->dp[0] != 0) ? 1 : 0;
20 mp_zero(a);
21 a->dp[0] = b & MP_MASK;
22 a->used = (a->dp[0] != 0u) ? 1 : 0;
2323 }
2424 #endif
2525
26 /* $Source$ */
27 /* $Revision$ */
28 /* $Date$ */
26 /* ref: $Format:%D$ */
27 /* git commit: $Format:%H$ */
28 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* set a 32-bit const */
18 int mp_set_int (mp_int * a, unsigned long b)
18 int mp_set_int(mp_int *a, unsigned long b)
1919 {
20 int x, res;
20 int x, res;
2121
22 mp_zero (a);
23
24 /* set four bits at a time */
25 for (x = 0; x < 8; x++) {
26 /* shift the number up four bits */
27 if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
28 return res;
29 }
22 mp_zero(a);
3023
31 /* OR in the top four bits of the source */
32 a->dp[0] |= (b >> 28) & 15;
24 /* set four bits at a time */
25 for (x = 0; x < 8; x++) {
26 /* shift the number up four bits */
27 if ((res = mp_mul_2d(a, 4, a)) != MP_OKAY) {
28 return res;
29 }
3330
34 /* shift the source up to the next four bits */
35 b <<= 4;
31 /* OR in the top four bits of the source */
32 a->dp[0] |= (mp_digit)(b >> 28) & 15uL;
3633
37 /* ensure that digits are not clamped off */
38 a->used += 1;
39 }
40 mp_clamp (a);
41 return MP_OKAY;
34 /* shift the source up to the next four bits */
35 b <<= 4;
36
37 /* ensure that digits are not clamped off */
38 a->used += 1;
39 }
40 mp_clamp(a);
41 return MP_OKAY;
4242 }
4343 #endif
4444
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
45 /* ref: $Format:%D$ */
46 /* git commit: $Format:%H$ */
47 /* commit time: $Format:%ai$ */
1818 MP_SET_XLONG(mp_set_long, unsigned long)
1919 #endif
2020
21 /* $Source$ */
22 /* $Revision$ */
23 /* $Date$ */
21 /* ref: $Format:%D$ */
22 /* git commit: $Format:%H$ */
23 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* set a platform dependent unsigned long long int */
18 MP_SET_XLONG(mp_set_long_long, unsigned long long)
18 MP_SET_XLONG(mp_set_long_long, uint64_t)
1919 #endif
2020
21 /* $Source$ */
22 /* $Revision$ */
23 /* $Date$ */
21 /* ref: $Format:%D$ */
22 /* git commit: $Format:%H$ */
23 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* shrink a bignum */
18 int mp_shrink (mp_int * a)
18 int mp_shrink(mp_int *a)
1919 {
20 mp_digit *tmp;
21 int used = 1;
22
23 if(a->used > 0) {
24 used = a->used;
25 }
26
27 if (a->alloc != used) {
28 if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) {
29 return MP_MEM;
30 }
31 a->dp = tmp;
32 a->alloc = used;
33 }
34 return MP_OKAY;
20 mp_digit *tmp;
21 int used = 1;
22
23 if (a->used > 0) {
24 used = a->used;
25 }
26
27 if (a->alloc != used) {
28 if ((tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * (size_t)used)) == NULL) {
29 return MP_MEM;
30 }
31 a->dp = tmp;
32 a->alloc = used;
33 }
34 return MP_OKAY;
3535 }
3636 #endif
3737
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
38 /* ref: $Format:%D$ */
39 /* git commit: $Format:%H$ */
40 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* get the size for an signed equivalent */
18 int mp_signed_bin_size (mp_int * a)
18 int mp_signed_bin_size(const mp_int *a)
1919 {
20 return 1 + mp_unsigned_bin_size (a);
20 return 1 + mp_unsigned_bin_size(a);
2121 }
2222 #endif
2323
24 /* $Source$ */
25 /* $Revision$ */
26 /* $Date$ */
24 /* ref: $Format:%D$ */
25 /* git commit: $Format:%H$ */
26 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* computes b = a*a */
18 int
19 mp_sqr (mp_int * a, mp_int * b)
18 int mp_sqr(const mp_int *a, mp_int *b)
2019 {
21 int res;
20 int res;
2221
2322 #ifdef BN_MP_TOOM_SQR_C
24 /* use Toom-Cook? */
25 if (a->used >= TOOM_SQR_CUTOFF) {
26 res = mp_toom_sqr(a, b);
27 /* Karatsuba? */
28 } else
23 /* use Toom-Cook? */
24 if (a->used >= TOOM_SQR_CUTOFF) {
25 res = mp_toom_sqr(a, b);
26 /* Karatsuba? */
27 } else
2928 #endif
3029 #ifdef BN_MP_KARATSUBA_SQR_C
31 if (a->used >= KARATSUBA_SQR_CUTOFF) {
32 res = mp_karatsuba_sqr (a, b);
33 } else
30 if (a->used >= KARATSUBA_SQR_CUTOFF) {
31 res = mp_karatsuba_sqr(a, b);
32 } else
3433 #endif
35 {
34 {
3635 #ifdef BN_FAST_S_MP_SQR_C
37 /* can we use the fast comba multiplier? */
38 if ((((a->used * 2) + 1) < MP_WARRAY) &&
39 (a->used <
40 (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) - 1)))) {
41 res = fast_s_mp_sqr (a, b);
42 } else
36 /* can we use the fast comba multiplier? */
37 if ((((a->used * 2) + 1) < (int)MP_WARRAY) &&
38 (a->used <
39 (int)(1u << (((sizeof(mp_word) * (size_t)CHAR_BIT) - (2u * (size_t)DIGIT_BIT)) - 1u)))) {
40 res = fast_s_mp_sqr(a, b);
41 } else
4342 #endif
44 {
43 {
4544 #ifdef BN_S_MP_SQR_C
46 res = s_mp_sqr (a, b);
45 res = s_mp_sqr(a, b);
4746 #else
48 res = MP_VAL;
47 res = MP_VAL;
4948 #endif
50 }
51 }
52 b->sign = MP_ZPOS;
53 return res;
49 }
50 }
51 b->sign = MP_ZPOS;
52 return res;
5453 }
5554 #endif
5655
57 /* $Source$ */
58 /* $Revision$ */
59 /* $Date$ */
56 /* ref: $Format:%D$ */
57 /* git commit: $Format:%H$ */
58 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* c = a * a (mod b) */
18 int
19 mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
18 int mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c)
2019 {
21 int res;
22 mp_int t;
20 int res;
21 mp_int t;
2322
24 if ((res = mp_init (&t)) != MP_OKAY) {
25 return res;
26 }
23 if ((res = mp_init(&t)) != MP_OKAY) {
24 return res;
25 }
2726
28 if ((res = mp_sqr (a, &t)) != MP_OKAY) {
29 mp_clear (&t);
30 return res;
31 }
32 res = mp_mod (&t, b, c);
33 mp_clear (&t);
34 return res;
27 if ((res = mp_sqr(a, &t)) != MP_OKAY) {
28 mp_clear(&t);
29 return res;
30 }
31 res = mp_mod(&t, b, c);
32 mp_clear(&t);
33 return res;
3534 }
3635 #endif
3736
38 /* $Source$ */
39 /* $Revision$ */
40 /* $Date$ */
37 /* ref: $Format:%D$ */
38 /* git commit: $Format:%H$ */
39 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* this function is less generic than mp_n_root, simpler and faster */
18 int mp_sqrt(mp_int *arg, mp_int *ret)
18 int mp_sqrt(const mp_int *arg, mp_int *ret)
1919 {
20 int res;
21 mp_int t1,t2;
20 int res;
21 mp_int t1, t2;
2222
23 /* must be positive */
24 if (arg->sign == MP_NEG) {
25 return MP_VAL;
26 }
23 /* must be positive */
24 if (arg->sign == MP_NEG) {
25 return MP_VAL;
26 }
2727
28 /* easy out */
29 if (mp_iszero(arg) == MP_YES) {
30 mp_zero(ret);
31 return MP_OKAY;
32 }
28 /* easy out */
29 if (mp_iszero(arg) == MP_YES) {
30 mp_zero(ret);
31 return MP_OKAY;
32 }
3333
34 if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
35 return res;
36 }
34 if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
35 return res;
36 }
3737
38 if ((res = mp_init(&t2)) != MP_OKAY) {
39 goto E2;
40 }
38 if ((res = mp_init(&t2)) != MP_OKAY) {
39 goto E2;
40 }
4141
42 /* First approx. (not very bad for large arg) */
43 mp_rshd (&t1,t1.used/2);
42 /* First approx. (not very bad for large arg) */
43 mp_rshd(&t1, t1.used/2);
4444
45 /* t1 > 0 */
46 if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
47 goto E1;
48 }
49 if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
50 goto E1;
51 }
52 if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
53 goto E1;
54 }
55 /* And now t1 > sqrt(arg) */
56 do {
57 if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
45 /* t1 > 0 */
46 if ((res = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) {
5847 goto E1;
59 }
60 if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
48 }
49 if ((res = mp_add(&t1, &t2, &t1)) != MP_OKAY) {
6150 goto E1;
62 }
63 if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
51 }
52 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) {
6453 goto E1;
65 }
66 /* t1 >= sqrt(arg) >= t2 at this point */
67 } while (mp_cmp_mag(&t1,&t2) == MP_GT);
54 }
55 /* And now t1 > sqrt(arg) */
56 do {
57 if ((res = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) {
58 goto E1;
59 }
60 if ((res = mp_add(&t1, &t2, &t1)) != MP_OKAY) {
61 goto E1;
62 }
63 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) {
64 goto E1;
65 }
66 /* t1 >= sqrt(arg) >= t2 at this point */
67 } while (mp_cmp_mag(&t1, &t2) == MP_GT);
6868
69 mp_exch(&t1,ret);
69 mp_exch(&t1, ret);
7070
71 E1: mp_clear(&t2);
72 E2: mp_clear(&t1);
73 return res;
71 E1:
72 mp_clear(&t2);
73 E2:
74 mp_clear(&t1);
75 return res;
7476 }
7577
7678 #endif
7779
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
80 /* ref: $Format:%D$ */
81 /* git commit: $Format:%H$ */
82 /* commit time: $Format:%ai$ */
1414 *
1515 */
1616
17 int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret)
17 int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
1818 {
19 int res, legendre;
20 mp_int t1, C, Q, S, Z, M, T, R, two;
21 mp_digit i;
19 int res, legendre;
20 mp_int t1, C, Q, S, Z, M, T, R, two;
21 mp_digit i;
2222
23 /* first handle the simple cases */
24 if (mp_cmp_d(n, 0) == MP_EQ) {
25 mp_zero(ret);
26 return MP_OKAY;
27 }
28 if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */
29 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res;
30 if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */
23 /* first handle the simple cases */
24 if (mp_cmp_d(n, 0uL) == MP_EQ) {
25 mp_zero(ret);
26 return MP_OKAY;
27 }
28 if (mp_cmp_d(prime, 2uL) == MP_EQ) return MP_VAL; /* prime must be odd */
29 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res;
30 if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */
3131
32 if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) {
33 return res;
34 }
32 if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) {
33 return res;
34 }
3535
36 /* SPECIAL CASE: if prime mod 4 == 3
37 * compute directly: res = n^(prime+1)/4 mod prime
38 * Handbook of Applied Cryptography algorithm 3.36
39 */
40 if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup;
41 if (i == 3) {
42 if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup;
43 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
44 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
45 if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup;
46 res = MP_OKAY;
47 goto cleanup;
48 }
49
50 /* NOW: Tonelli-Shanks algorithm */
51
52 /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */
53 if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup;
54 if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup;
55 /* Q = prime - 1 */
56 mp_zero(&S);
57 /* S = 0 */
58 while (mp_iseven(&Q) != MP_NO) {
59 if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup;
60 /* Q = Q / 2 */
61 if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup;
62 /* S = S + 1 */
63 }
64
65 /* find a Z such that the Legendre symbol (Z|prime) == -1 */
66 if ((res = mp_set_int(&Z, 2)) != MP_OKAY) goto cleanup;
67 /* Z = 2 */
68 while(1) {
69 if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup;
70 if (legendre == -1) break;
71 if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup;
72 /* Z = Z + 1 */
73 }
74
75 if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup;
76 /* C = Z ^ Q mod prime */
77 if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup;
78 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
79 /* t1 = (Q + 1) / 2 */
80 if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup;
81 /* R = n ^ ((Q + 1) / 2) mod prime */
82 if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup;
83 /* T = n ^ Q mod prime */
84 if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup;
85 /* M = S */
86 if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup;
87
88 res = MP_VAL;
89 while (1) {
90 if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup;
91 i = 0;
92 while (1) {
93 if (mp_cmp_d(&t1, 1) == MP_EQ) break;
94 if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup;
95 i++;
96 }
97 if (i == 0) {
98 if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup;
36 /* SPECIAL CASE: if prime mod 4 == 3
37 * compute directly: res = n^(prime+1)/4 mod prime
38 * Handbook of Applied Cryptography algorithm 3.36
39 */
40 if ((res = mp_mod_d(prime, 4uL, &i)) != MP_OKAY) goto cleanup;
41 if (i == 3u) {
42 if ((res = mp_add_d(prime, 1uL, &t1)) != MP_OKAY) goto cleanup;
43 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
44 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
45 if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup;
9946 res = MP_OKAY;
10047 goto cleanup;
101 }
102 if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup;
103 if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup;
104 if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
105 /* t1 = 2 ^ (M - i - 1) */
106 if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
107 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
108 if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup;
109 /* C = (t1 * t1) mod prime */
110 if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup;
111 /* R = (R * t1) mod prime */
112 if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup;
113 /* T = (T * C) mod prime */
114 mp_set(&M, i);
115 /* M = i */
116 }
48 }
49
50 /* NOW: Tonelli-Shanks algorithm */
51
52 /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */
53 if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup;
54 if ((res = mp_sub_d(&Q, 1uL, &Q)) != MP_OKAY) goto cleanup;
55 /* Q = prime - 1 */
56 mp_zero(&S);
57 /* S = 0 */
58 while (mp_iseven(&Q) != MP_NO) {
59 if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup;
60 /* Q = Q / 2 */
61 if ((res = mp_add_d(&S, 1uL, &S)) != MP_OKAY) goto cleanup;
62 /* S = S + 1 */
63 }
64
65 /* find a Z such that the Legendre symbol (Z|prime) == -1 */
66 if ((res = mp_set_int(&Z, 2uL)) != MP_OKAY) goto cleanup;
67 /* Z = 2 */
68 while (1) {
69 if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup;
70 if (legendre == -1) break;
71 if ((res = mp_add_d(&Z, 1uL, &Z)) != MP_OKAY) goto cleanup;
72 /* Z = Z + 1 */
73 }
74
75 if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup;
76 /* C = Z ^ Q mod prime */
77 if ((res = mp_add_d(&Q, 1uL, &t1)) != MP_OKAY) goto cleanup;
78 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
79 /* t1 = (Q + 1) / 2 */
80 if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup;
81 /* R = n ^ ((Q + 1) / 2) mod prime */
82 if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup;
83 /* T = n ^ Q mod prime */
84 if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup;
85 /* M = S */
86 if ((res = mp_set_int(&two, 2uL)) != MP_OKAY) goto cleanup;
87
88 res = MP_VAL;
89 while (1) {
90 if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup;
91 i = 0;
92 while (1) {
93 if (mp_cmp_d(&t1, 1uL) == MP_EQ) break;
94 if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup;
95 i++;
96 }
97 if (i == 0u) {
98 if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup;
99 res = MP_OKAY;
100 goto cleanup;
101 }
102 if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup;
103 if ((res = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) goto cleanup;
104 if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
105 /* t1 = 2 ^ (M - i - 1) */
106 if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
107 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
108 if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup;
109 /* C = (t1 * t1) mod prime */
110 if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup;
111 /* R = (R * t1) mod prime */
112 if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup;
113 /* T = (T * C) mod prime */
114 mp_set(&M, i);
115 /* M = i */
116 }
117117
118118 cleanup:
119 mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL);
120 return res;
119 mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL);
120 return res;
121121 }
122122
123123 #endif
1515 */
1616
1717 /* high level subtraction (handles signs) */
18 int
19 mp_sub (mp_int * a, mp_int * b, mp_int * c)
18 int mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
2019 {
21 int sa, sb, res;
20 int sa, sb, res;
2221
23 sa = a->sign;
24 sb = b->sign;
22 sa = a->sign;
23 sb = b->sign;
2524
26 if (sa != sb) {
27 /* subtract a negative from a positive, OR */
28 /* subtract a positive from a negative. */
29 /* In either case, ADD their magnitudes, */
30 /* and use the sign of the first number. */
31 c->sign = sa;
32 res = s_mp_add (a, b, c);
33 } else {
34 /* subtract a positive from a positive, OR */
35 /* subtract a negative from a negative. */
36 /* First, take the difference between their */
37 /* magnitudes, then... */
38 if (mp_cmp_mag (a, b) != MP_LT) {
39 /* Copy the sign from the first */
25 if (sa != sb) {
26 /* subtract a negative from a positive, OR */
27 /* subtract a positive from a negative. */
28 /* In either case, ADD their magnitudes, */
29 /* and use the sign of the first number. */
4030 c->sign = sa;
41 /* The first has a larger or equal magnitude */
42 res = s_mp_sub (a, b, c);
43 } else {
44 /* The result has the *opposite* sign from */
45 /* the first number. */
46 c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
47 /* The second has a larger magnitude */
48 res = s_mp_sub (b, a, c);
49 }
50 }
51 return res;
31 res = s_mp_add(a, b, c);
32 } else {
33 /* subtract a positive from a positive, OR */
34 /* subtract a negative from a negative. */
35 /* First, take the difference between their */
36 /* magnitudes, then... */
37 if (mp_cmp_mag(a, b) != MP_LT) {
38 /* Copy the sign from the first */
39 c->sign = sa;
40 /* The first has a larger or equal magnitude */
41 res = s_mp_sub(a, b, c);
42 } else {
43 /* The result has the *opposite* sign from */
44 /* the first number. */
45 c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
46 /* The second has a larger magnitude */
47 res = s_mp_sub(b, a, c);
48 }
49 }
50 return res;
5251 }
5352
5453 #endif
5554
56 /* $Source$ */
57 /* $Revision$ */
58 /* $Date$ */
55 /* ref: $Format:%D$ */
56 /* git commit: $Format:%H$ */
57 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* single digit subtraction */
18 int
19 mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
18 int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
2019 {
21 mp_digit *tmpa, *tmpc, mu;
22 int res, ix, oldused;
20 mp_digit *tmpa, *tmpc, mu;
21 int res, ix, oldused;
2322
24 /* grow c as required */
25 if (c->alloc < (a->used + 1)) {
26 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27 return res;
28 }
29 }
23 /* grow c as required */
24 if (c->alloc < (a->used + 1)) {
25 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
26 return res;
27 }
28 }
3029
31 /* if a is negative just do an unsigned
32 * addition [with fudged signs]
33 */
34 if (a->sign == MP_NEG) {
35 a->sign = MP_ZPOS;
36 res = mp_add_d(a, b, c);
37 a->sign = c->sign = MP_NEG;
30 /* if a is negative just do an unsigned
31 * addition [with fudged signs]
32 */
33 if (a->sign == MP_NEG) {
34 mp_int a_ = *a;
35 a_.sign = MP_ZPOS;
36 res = mp_add_d(&a_, b, c);
37 c->sign = MP_NEG;
3838
39 /* clamp */
40 mp_clamp(c);
39 /* clamp */
40 mp_clamp(c);
4141
42 return res;
43 }
42 return res;
43 }
4444
45 /* setup regs */
46 oldused = c->used;
47 tmpa = a->dp;
48 tmpc = c->dp;
45 /* setup regs */
46 oldused = c->used;
47 tmpa = a->dp;
48 tmpc = c->dp;
4949
50 /* if a <= b simply fix the single digit */
51 if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) {
52 if (a->used == 1) {
53 *tmpc++ = b - *tmpa;
54 } else {
55 *tmpc++ = b;
56 }
57 ix = 1;
50 /* if a <= b simply fix the single digit */
51 if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) {
52 if (a->used == 1) {
53 *tmpc++ = b - *tmpa;
54 } else {
55 *tmpc++ = b;
56 }
57 ix = 1;
5858
59 /* negative/1digit */
60 c->sign = MP_NEG;
61 c->used = 1;
62 } else {
63 /* positive/size */
64 c->sign = MP_ZPOS;
65 c->used = a->used;
59 /* negative/1digit */
60 c->sign = MP_NEG;
61 c->used = 1;
62 } else {
63 /* positive/size */
64 c->sign = MP_ZPOS;
65 c->used = a->used;
6666
67 /* subtract first digit */
68 *tmpc = *tmpa++ - b;
69 mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1);
70 *tmpc++ &= MP_MASK;
67 /* subtract first digit */
68 *tmpc = *tmpa++ - b;
69 mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u);
70 *tmpc++ &= MP_MASK;
7171
72 /* handle rest of the digits */
73 for (ix = 1; ix < a->used; ix++) {
74 *tmpc = *tmpa++ - mu;
75 mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1);
76 *tmpc++ &= MP_MASK;
77 }
78 }
72 /* handle rest of the digits */
73 for (ix = 1; ix < a->used; ix++) {
74 *tmpc = *tmpa++ - mu;
75 mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u);
76 *tmpc++ &= MP_MASK;
77 }
78 }
7979
80 /* zero excess digits */
81 while (ix++ < oldused) {
82 *tmpc++ = 0;
83 }
84 mp_clamp(c);
85 return MP_OKAY;
80 /* zero excess digits */
81 while (ix++ < oldused) {
82 *tmpc++ = 0;
83 }
84 mp_clamp(c);
85 return MP_OKAY;
8686 }
8787
8888 #endif
8989
90 /* $Source$ */
91 /* $Revision$ */
92 /* $Date$ */
90 /* ref: $Format:%D$ */
91 /* git commit: $Format:%H$ */
92 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* d = a - b (mod c) */
18 int
19 mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
18 int mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
2019 {
21 int res;
22 mp_int t;
20 int res;
21 mp_int t;
2322
2423
25 if ((res = mp_init (&t)) != MP_OKAY) {
26 return res;
27 }
24 if ((res = mp_init(&t)) != MP_OKAY) {
25 return res;
26 }
2827
29 if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
30 mp_clear (&t);
31 return res;
32 }
33 res = mp_mod (&t, c, d);
34 mp_clear (&t);
35 return res;
28 if ((res = mp_sub(a, b, &t)) != MP_OKAY) {
29 mp_clear(&t);
30 return res;
31 }
32 res = mp_mod(&t, c, d);
33 mp_clear(&t);
34 return res;
3635 }
3736 #endif
3837
39 /* $Source$ */
40 /* $Revision$ */
41 /* $Date$ */
38 /* ref: $Format:%D$ */
39 /* git commit: $Format:%H$ */
40 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* store in signed [big endian] format */
18 int mp_to_signed_bin (mp_int * a, unsigned char *b)
18 int mp_to_signed_bin(const mp_int *a, unsigned char *b)
1919 {
20 int res;
20 int res;
2121
22 if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
23 return res;
24 }
25 b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1;
26 return MP_OKAY;
22 if ((res = mp_to_unsigned_bin(a, b + 1)) != MP_OKAY) {
23 return res;
24 }
25 b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1;
26 return MP_OKAY;
2727 }
2828 #endif
2929
30 /* $Source$ */
31 /* $Revision$ */
32 /* $Date$ */
30 /* ref: $Format:%D$ */
31 /* git commit: $Format:%H$ */
32 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* store in signed [big endian] format */
18 int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
18 int mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen)
1919 {
2020 if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
2121 return MP_VAL;
2222 }
23 *outlen = mp_signed_bin_size(a);
23 *outlen = (unsigned long)mp_signed_bin_size(a);
2424 return mp_to_signed_bin(a, b);
2525 }
2626 #endif
2727
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
28 /* ref: $Format:%D$ */
29 /* git commit: $Format:%H$ */
30 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* store in unsigned [big endian] format */
18 int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
18 int mp_to_unsigned_bin(const mp_int *a, unsigned char *b)
1919 {
20 int x, res;
21 mp_int t;
20 int x, res;
21 mp_int t;
2222
23 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
24 return res;
25 }
23 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
24 return res;
25 }
2626
27 x = 0;
28 while (mp_iszero (&t) == MP_NO) {
27 x = 0;
28 while (mp_iszero(&t) == MP_NO) {
2929 #ifndef MP_8BIT
30 b[x++] = (unsigned char) (t.dp[0] & 255);
30 b[x++] = (unsigned char)(t.dp[0] & 255u);
3131 #else
32 b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
32 b[x++] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7));
3333 #endif
34 if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
35 mp_clear (&t);
36 return res;
37 }
38 }
39 bn_reverse (b, x);
40 mp_clear (&t);
41 return MP_OKAY;
34 if ((res = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) {
35 mp_clear(&t);
36 return res;
37 }
38 }
39 bn_reverse(b, x);
40 mp_clear(&t);
41 return MP_OKAY;
4242 }
4343 #endif
4444
45 /* $Source$ */
46 /* $Revision$ */
47 /* $Date$ */
45 /* ref: $Format:%D$ */
46 /* git commit: $Format:%H$ */
47 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* store in unsigned [big endian] format */
18 int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
18 int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen)
1919 {
2020 if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
2121 return MP_VAL;
2222 }
23 *outlen = mp_unsigned_bin_size(a);
23 *outlen = (unsigned long)mp_unsigned_bin_size(a);
2424 return mp_to_unsigned_bin(a, b);
2525 }
2626 #endif
2727
28 /* $Source$ */
29 /* $Revision$ */
30 /* $Date$ */
28 /* ref: $Format:%D$ */
29 /* git commit: $Format:%H$ */
30 /* commit time: $Format:%ai$ */
2121 * only particularly useful on VERY large inputs
2222 * (we're talking 1000s of digits here...).
2323 */
24 int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
24 int mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
2525 {
26 mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
27 int res, B;
28
29 /* init temps */
30 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
31 &a0, &a1, &a2, &b0, &b1,
32 &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
33 return res;
34 }
35
36 /* B */
37 B = MIN(a->used, b->used) / 3;
38
39 /* a = a2 * B**2 + a1 * B + a0 */
40 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
41 goto ERR;
42 }
43
44 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
45 goto ERR;
46 }
47 mp_rshd(&a1, B);
48 if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
49 goto ERR;
50 }
51
52 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
53 goto ERR;
54 }
55 mp_rshd(&a2, B*2);
56
57 /* b = b2 * B**2 + b1 * B + b0 */
58 if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
59 goto ERR;
60 }
61
62 if ((res = mp_copy(b, &b1)) != MP_OKAY) {
63 goto ERR;
64 }
65 mp_rshd(&b1, B);
66 (void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
67
68 if ((res = mp_copy(b, &b2)) != MP_OKAY) {
69 goto ERR;
70 }
71 mp_rshd(&b2, B*2);
72
73 /* w0 = a0*b0 */
74 if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
75 goto ERR;
76 }
77
78 /* w4 = a2 * b2 */
79 if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
80 goto ERR;
81 }
82
83 /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
84 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
85 goto ERR;
86 }
87 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
88 goto ERR;
89 }
90 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
91 goto ERR;
92 }
93 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
94 goto ERR;
95 }
96
97 if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
98 goto ERR;
99 }
100 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
101 goto ERR;
102 }
103 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
104 goto ERR;
105 }
106 if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
107 goto ERR;
108 }
109
110 if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
111 goto ERR;
112 }
113
114 /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
115 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
116 goto ERR;
117 }
118 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
119 goto ERR;
120 }
121 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
122 goto ERR;
123 }
124 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
125 goto ERR;
126 }
127
128 if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
129 goto ERR;
130 }
131 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
132 goto ERR;
133 }
134 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
135 goto ERR;
136 }
137 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
138 goto ERR;
139 }
140
141 if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
142 goto ERR;
143 }
144
145
146 /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
147 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
148 goto ERR;
149 }
150 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
151 goto ERR;
152 }
153 if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
154 goto ERR;
155 }
156 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
157 goto ERR;
158 }
159 if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
160 goto ERR;
161 }
162
163 /* now solve the matrix
164
165 0 0 0 0 1
166 1 2 4 8 16
167 1 1 1 1 1
168 16 8 4 2 1
169 1 0 0 0 0
170
171 using 12 subtractions, 4 shifts,
172 2 small divisions and 1 small multiplication
173 */
174
175 /* r1 - r4 */
176 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
177 goto ERR;
178 }
179 /* r3 - r0 */
180 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
181 goto ERR;
182 }
183 /* r1/2 */
184 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
185 goto ERR;
186 }
187 /* r3/2 */
188 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
189 goto ERR;
190 }
191 /* r2 - r0 - r4 */
192 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
193 goto ERR;
194 }
195 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
196 goto ERR;
197 }
198 /* r1 - r2 */
199 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
200 goto ERR;
201 }
202 /* r3 - r2 */
203 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
204 goto ERR;
205 }
206 /* r1 - 8r0 */
207 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
208 goto ERR;
209 }
210 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
211 goto ERR;
212 }
213 /* r3 - 8r4 */
214 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
215 goto ERR;
216 }
217 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
218 goto ERR;
219 }
220 /* 3r2 - r1 - r3 */
221 if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
222 goto ERR;
223 }
224 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
225 goto ERR;
226 }
227 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
228 goto ERR;
229 }
230 /* r1 - r2 */
231 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
232 goto ERR;
233 }
234 /* r3 - r2 */
235 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
236 goto ERR;
237 }
238 /* r1/3 */
239 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
240 goto ERR;
241 }
242 /* r3/3 */
243 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
244 goto ERR;
245 }
246
247 /* at this point shift W[n] by B*n */
248 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
249 goto ERR;
250 }
251 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
252 goto ERR;
253 }
254 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
255 goto ERR;
256 }
257 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
258 goto ERR;
259 }
260
261 if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
262 goto ERR;
263 }
264 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
265 goto ERR;
266 }
267 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
268 goto ERR;
269 }
270 if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
271 goto ERR;
272 }
26 mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
27 int res, B;
28
29 /* init temps */
30 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
31 &a0, &a1, &a2, &b0, &b1,
32 &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
33 return res;
34 }
35
36 /* B */
37 B = MIN(a->used, b->used) / 3;
38
39 /* a = a2 * B**2 + a1 * B + a0 */
40 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
41 goto ERR;
42 }
43
44 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
45 goto ERR;
46 }
47 mp_rshd(&a1, B);
48 if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
49 goto ERR;
50 }
51
52 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
53 goto ERR;
54 }
55 mp_rshd(&a2, B*2);
56
57 /* b = b2 * B**2 + b1 * B + b0 */
58 if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
59 goto ERR;
60 }
61
62 if ((res = mp_copy(b, &b1)) != MP_OKAY) {
63 goto ERR;
64 }
65 mp_rshd(&b1, B);
66 (void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
67
68 if ((res = mp_copy(b, &b2)) != MP_OKAY) {
69 goto ERR;
70 }
71 mp_rshd(&b2, B*2);
72
73 /* w0 = a0*b0 */
74 if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
75 goto ERR;
76 }
77
78 /* w4 = a2 * b2 */
79 if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
80 goto ERR;
81 }
82
83 /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
84 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
85 goto ERR;
86 }
87 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
88 goto ERR;
89 }
90 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
91 goto ERR;
92 }
93 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
94 goto ERR;
95 }
96
97 if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
98 goto ERR;
99 }
100 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
101 goto ERR;
102 }
103 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
104 goto ERR;
105 }
106 if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
107 goto ERR;
108 }
109
110 if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
111 goto ERR;
112 }
113
114 /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
115 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
116 goto ERR;
117 }
118 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
119 goto ERR;
120 }
121 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
122 goto ERR;
123 }
124 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
125 goto ERR;
126 }
127
128 if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
129 goto ERR;
130 }
131 if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
132 goto ERR;
133 }
134 if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
135 goto ERR;
136 }
137 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
138 goto ERR;
139 }
140
141 if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
142 goto ERR;
143 }
144
145
146 /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
147 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
148 goto ERR;
149 }
150 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
151 goto ERR;
152 }
153 if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
154 goto ERR;
155 }
156 if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
157 goto ERR;
158 }
159 if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
160 goto ERR;
161 }
162
163 /* now solve the matrix
164
165 0 0 0 0 1
166 1 2 4 8 16
167 1 1 1 1 1
168 16 8 4 2 1
169 1 0 0 0 0
170
171 using 12 subtractions, 4 shifts,
172 2 small divisions and 1 small multiplication
173 */
174
175 /* r1 - r4 */
176 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
177 goto ERR;
178 }
179 /* r3 - r0 */
180 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
181 goto ERR;
182 }
183 /* r1/2 */
184 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
185 goto ERR;
186 }
187 /* r3/2 */
188 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
189 goto ERR;
190 }
191 /* r2 - r0 - r4 */
192 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
193 goto ERR;
194 }
195 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
196 goto ERR;
197 }
198 /* r1 - r2 */
199 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
200 goto ERR;
201 }
202 /* r3 - r2 */
203 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
204 goto ERR;
205 }
206 /* r1 - 8r0 */
207 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
208 goto ERR;
209 }
210 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
211 goto ERR;
212 }
213 /* r3 - 8r4 */
214 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
215 goto ERR;
216 }
217 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
218 goto ERR;
219 }
220 /* 3r2 - r1 - r3 */
221 if ((res = mp_mul_d(&w2, 3uL, &w2)) != MP_OKAY) {
222 goto ERR;
223 }
224 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
225 goto ERR;
226 }
227 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
228 goto ERR;
229 }
230 /* r1 - r2 */
231 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
232 goto ERR;
233 }
234 /* r3 - r2 */
235 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
236 goto ERR;
237 }
238 /* r1/3 */
239 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
240 goto ERR;
241 }
242 /* r3/3 */
243 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
244 goto ERR;
245 }
246
247 /* at this point shift W[n] by B*n */
248 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
249 goto ERR;
250 }
251 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
252 goto ERR;
253 }
254 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
255 goto ERR;
256 }
257 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
258 goto ERR;
259 }
260
261 if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
262 goto ERR;
263 }
264 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
265 goto ERR;
266 }
267 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
268 goto ERR;
269 }
270 if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
271 goto ERR;
272 }
273273
274274 ERR:
275 mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
276 &a0, &a1, &a2, &b0, &b1,
277 &b2, &tmp1, &tmp2, NULL);
278 return res;
275 mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
276 &a0, &a1, &a2, &b0, &b1,
277 &b2, &tmp1, &tmp2, NULL);
278 return res;
279279 }
280280
281281 #endif
282282
283 /* $Source$ */
284 /* $Revision$ */
285 /* $Date$ */
283 /* ref: $Format:%D$ */
284 /* git commit: $Format:%H$ */
285 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* squaring using Toom-Cook 3-way algorithm */
18 int
19 mp_toom_sqr(mp_int *a, mp_int *b)
18 int mp_toom_sqr(const mp_int *a, mp_int *b)
2019 {
21 mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
22 int res, B;
23
24 /* init temps */
25 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
26 return res;
27 }
28
29 /* B */
30 B = a->used / 3;
31
32 /* a = a2 * B**2 + a1 * B + a0 */
33 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
34 goto ERR;
35 }
36
37 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
38 goto ERR;
39 }
40 mp_rshd(&a1, B);
41 if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
42 goto ERR;
43 }
44
45 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
46 goto ERR;
47 }
48 mp_rshd(&a2, B*2);
49
50 /* w0 = a0*a0 */
51 if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
52 goto ERR;
53 }
54
55 /* w4 = a2 * a2 */
56 if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
57 goto ERR;
58 }
59
60 /* w1 = (a2 + 2(a1 + 2a0))**2 */
61 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
62 goto ERR;
63 }
64 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
65 goto ERR;
66 }
67 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
68 goto ERR;
69 }
70 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
71 goto ERR;
72 }
73
74 if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
75 goto ERR;
76 }
77
78 /* w3 = (a0 + 2(a1 + 2a2))**2 */
79 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
80 goto ERR;
81 }
82 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
83 goto ERR;
84 }
85 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
86 goto ERR;
87 }
88 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
89 goto ERR;
90 }
91
92 if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
93 goto ERR;
94 }
95
96
97 /* w2 = (a2 + a1 + a0)**2 */
98 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
99 goto ERR;
100 }
101 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
102 goto ERR;
103 }
104 if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
105 goto ERR;
106 }
107
108 /* now solve the matrix
109
110 0 0 0 0 1
111 1 2 4 8 16
112 1 1 1 1 1
113 16 8 4 2 1
114 1 0 0 0 0
115
116 using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
117 */
118
119 /* r1 - r4 */
120 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
121 goto ERR;
122 }
123 /* r3 - r0 */
124 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
125 goto ERR;
126 }
127 /* r1/2 */
128 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
129 goto ERR;
130 }
131 /* r3/2 */
132 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
133 goto ERR;
134 }
135 /* r2 - r0 - r4 */
136 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
137 goto ERR;
138 }
139 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
140 goto ERR;
141 }
142 /* r1 - r2 */
143 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
144 goto ERR;
145 }
146 /* r3 - r2 */
147 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
148 goto ERR;
149 }
150 /* r1 - 8r0 */
151 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
152 goto ERR;
153 }
154 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
155 goto ERR;
156 }
157 /* r3 - 8r4 */
158 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
159 goto ERR;
160 }
161 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
162 goto ERR;
163 }
164 /* 3r2 - r1 - r3 */
165 if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
166 goto ERR;
167 }
168 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
169 goto ERR;
170 }
171 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
172 goto ERR;
173 }
174 /* r1 - r2 */
175 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
176 goto ERR;
177 }
178 /* r3 - r2 */
179 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
180 goto ERR;
181 }
182 /* r1/3 */
183 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
184 goto ERR;
185 }
186 /* r3/3 */
187 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
188 goto ERR;
189 }
190
191 /* at this point shift W[n] by B*n */
192 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
193 goto ERR;
194 }
195 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
196 goto ERR;
197 }
198 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
199 goto ERR;
200 }
201 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
202 goto ERR;
203 }
204
205 if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
206 goto ERR;
207 }
208 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
209 goto ERR;
210 }
211 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
212 goto ERR;
213 }
214 if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
215 goto ERR;
216 }
20 mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
21 int res, B;
22
23 /* init temps */
24 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
25 return res;
26 }
27
28 /* B */
29 B = a->used / 3;
30
31 /* a = a2 * B**2 + a1 * B + a0 */
32 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
33 goto ERR;
34 }
35
36 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
37 goto ERR;
38 }
39 mp_rshd(&a1, B);
40 if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
41 goto ERR;
42 }
43
44 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
45 goto ERR;
46 }
47 mp_rshd(&a2, B*2);
48
49 /* w0 = a0*a0 */
50 if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
51 goto ERR;
52 }
53
54 /* w4 = a2 * a2 */
55 if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
56 goto ERR;
57 }
58
59 /* w1 = (a2 + 2(a1 + 2a0))**2 */
60 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
61 goto ERR;
62 }
63 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
64 goto ERR;
65 }
66 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
67 goto ERR;
68 }
69 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
70 goto ERR;
71 }
72
73 if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
74 goto ERR;
75 }
76
77 /* w3 = (a0 + 2(a1 + 2a2))**2 */
78 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
79 goto ERR;
80 }
81 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
82 goto ERR;
83 }
84 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
85 goto ERR;
86 }
87 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
88 goto ERR;
89 }
90
91 if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
92 goto ERR;
93 }
94
95
96 /* w2 = (a2 + a1 + a0)**2 */
97 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
98 goto ERR;
99 }
100 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
101 goto ERR;
102 }
103 if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
104 goto ERR;
105 }
106
107 /* now solve the matrix
108
109 0 0 0 0 1
110 1 2 4 8 16
111 1 1 1 1 1
112 16 8 4 2 1
113 1 0 0 0 0
114
115 using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
116 */
117
118 /* r1 - r4 */
119 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
120 goto ERR;
121 }
122 /* r3 - r0 */
123 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
124 goto ERR;
125 }
126 /* r1/2 */
127 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
128 goto ERR;
129 }
130 /* r3/2 */
131 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
132 goto ERR;
133 }
134 /* r2 - r0 - r4 */
135 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
136 goto ERR;
137 }
138 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
139 goto ERR;
140 }
141 /* r1 - r2 */
142 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
143 goto ERR;
144 }
145 /* r3 - r2 */
146 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
147 goto ERR;
148 }
149 /* r1 - 8r0 */
150 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
151 goto ERR;
152 }
153 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
154 goto ERR;
155 }
156 /* r3 - 8r4 */
157 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
158 goto ERR;
159 }
160 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
161 goto ERR;
162 }
163 /* 3r2 - r1 - r3 */
164 if ((res = mp_mul_d(&w2, 3uL, &w2)) != MP_OKAY) {
165 goto ERR;
166 }
167 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
168 goto ERR;
169 }
170 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
171 goto ERR;
172 }
173 /* r1 - r2 */
174 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
175 goto ERR;
176 }
177 /* r3 - r2 */
178 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
179 goto ERR;
180 }
181 /* r1/3 */
182 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
183 goto ERR;
184 }
185 /* r3/3 */
186 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
187 goto ERR;
188 }
189
190 /* at this point shift W[n] by B*n */
191 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
192 goto ERR;
193 }
194 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
195 goto ERR;
196 }
197 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
198 goto ERR;
199 }
200 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
201 goto ERR;
202 }
203
204 if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
205 goto ERR;
206 }
207 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
208 goto ERR;
209 }
210 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
211 goto ERR;
212 }
213 if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
214 goto ERR;
215 }
217216
218217 ERR:
219 mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
220 return res;
218 mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
219 return res;
221220 }
222221
223222 #endif
224223
225 /* $Source$ */
226 /* $Revision$ */
227 /* $Date$ */
224 /* ref: $Format:%D$ */
225 /* git commit: $Format:%H$ */
226 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* stores a bignum as a ASCII string in a given radix (2..64) */
18 int mp_toradix (mp_int * a, char *str, int radix)
18 int mp_toradix(const mp_int *a, char *str, int radix)
1919 {
20 int res, digs;
21 mp_int t;
22 mp_digit d;
23 char *_s = str;
20 int res, digs;
21 mp_int t;
22 mp_digit d;
23 char *_s = str;
2424
25 /* check range of the radix */
26 if ((radix < 2) || (radix > 64)) {
27 return MP_VAL;
28 }
25 /* check range of the radix */
26 if ((radix < 2) || (radix > 64)) {
27 return MP_VAL;
28 }
2929
30 /* quick out if its zero */
31 if (mp_iszero(a) == MP_YES) {
32 *str++ = '0';
33 *str = '\0';
34 return MP_OKAY;
35 }
30 /* quick out if its zero */
31 if (mp_iszero(a) == MP_YES) {
32 *str++ = '0';
33 *str = '\0';
34 return MP_OKAY;
35 }
3636
37 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
38 return res;
39 }
37 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
38 return res;
39 }
4040
41 /* if it is negative output a - */
42 if (t.sign == MP_NEG) {
43 ++_s;
44 *str++ = '-';
45 t.sign = MP_ZPOS;
46 }
41 /* if it is negative output a - */
42 if (t.sign == MP_NEG) {
43 ++_s;
44 *str++ = '-';
45 t.sign = MP_ZPOS;
46 }
4747
48 digs = 0;
49 while (mp_iszero (&t) == MP_NO) {
50 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
51 mp_clear (&t);
52 return res;
53 }
54 *str++ = mp_s_rmap[d];
55 ++digs;
56 }
48 digs = 0;
49 while (mp_iszero(&t) == MP_NO) {
50 if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
51 mp_clear(&t);
52 return res;
53 }
54 *str++ = mp_s_rmap[d];
55 ++digs;
56 }
5757
58 /* reverse the digits of the string. In this case _s points
59 * to the first digit [exluding the sign] of the number]
60 */
61 bn_reverse ((unsigned char *)_s, digs);
58 /* reverse the digits of the string. In this case _s points
59 * to the first digit [exluding the sign] of the number]
60 */
61 bn_reverse((unsigned char *)_s, digs);
6262
63 /* append a NULL so the string is properly terminated */
64 *str = '\0';
63 /* append a NULL so the string is properly terminated */
64 *str = '\0';
6565
66 mp_clear (&t);
67 return MP_OKAY;
66 mp_clear(&t);
67 return MP_OKAY;
6868 }
6969
7070 #endif
7171
72 /* $Source$ */
73 /* $Revision$ */
74 /* $Date$ */
72 /* ref: $Format:%D$ */
73 /* git commit: $Format:%H$ */
74 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616
17 /* stores a bignum as a ASCII string in a given radix (2..64)
17 /* stores a bignum as a ASCII string in a given radix (2..64)
1818 *
19 * Stores upto maxlen-1 chars and always a NULL byte
19 * Stores upto maxlen-1 chars and always a NULL byte
2020 */
21 int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
21 int mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen)
2222 {
23 int res, digs;
24 mp_int t;
25 mp_digit d;
26 char *_s = str;
23 int res, digs;
24 mp_int t;
25 mp_digit d;
26 char *_s = str;
2727
28 /* check range of the maxlen, radix */
29 if ((maxlen < 2) || (radix < 2) || (radix > 64)) {
30 return MP_VAL;
31 }
28 /* check range of the maxlen, radix */
29 if ((maxlen < 2) || (radix < 2) || (radix > 64)) {
30 return MP_VAL;
31 }
3232
33 /* quick out if its zero */
34 if (mp_iszero(a) == MP_YES) {
35 *str++ = '0';
36 *str = '\0';
37 return MP_OKAY;
38 }
33 /* quick out if its zero */
34 if (mp_iszero(a) == MP_YES) {
35 *str++ = '0';
36 *str = '\0';
37 return MP_OKAY;
38 }
3939
40 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
41 return res;
42 }
40 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
41 return res;
42 }
4343
44 /* if it is negative output a - */
45 if (t.sign == MP_NEG) {
46 /* we have to reverse our digits later... but not the - sign!! */
47 ++_s;
44 /* if it is negative output a - */
45 if (t.sign == MP_NEG) {
46 /* we have to reverse our digits later... but not the - sign!! */
47 ++_s;
4848
49 /* store the flag and mark the number as positive */
50 *str++ = '-';
51 t.sign = MP_ZPOS;
52
53 /* subtract a char */
54 --maxlen;
55 }
49 /* store the flag and mark the number as positive */
50 *str++ = '-';
51 t.sign = MP_ZPOS;
5652
57 digs = 0;
58 while (mp_iszero (&t) == MP_NO) {
59 if (--maxlen < 1) {
60 /* no more room */
61 break;
62 }
63 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
64 mp_clear (&t);
65 return res;
66 }
67 *str++ = mp_s_rmap[d];
68 ++digs;
69 }
53 /* subtract a char */
54 --maxlen;
55 }
7056
71 /* reverse the digits of the string. In this case _s points
72 * to the first digit [exluding the sign] of the number
73 */
74 bn_reverse ((unsigned char *)_s, digs);
57 digs = 0;
58 while (mp_iszero(&t) == MP_NO) {
59 if (--maxlen < 1) {
60 /* no more room */
61 break;
62 }
63 if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
64 mp_clear(&t);
65 return res;
66 }
67 *str++ = mp_s_rmap[d];
68 ++digs;
69 }
7570
76 /* append a NULL so the string is properly terminated */
77 *str = '\0';
71 /* reverse the digits of the string. In this case _s points
72 * to the first digit [exluding the sign] of the number
73 */
74 bn_reverse((unsigned char *)_s, digs);
7875
79 mp_clear (&t);
80 return MP_OKAY;
76 /* append a NULL so the string is properly terminated */
77 *str = '\0';
78
79 mp_clear(&t);
80 return MP_OKAY;
8181 }
8282
8383 #endif
8484
85 /* $Source$ */
86 /* $Revision$ */
87 /* $Date$ */
85 /* ref: $Format:%D$ */
86 /* git commit: $Format:%H$ */
87 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* get the size for an unsigned equivalent */
18 int mp_unsigned_bin_size (mp_int * a)
18 int mp_unsigned_bin_size(const mp_int *a)
1919 {
20 int size = mp_count_bits (a);
21 return (size / 8) + (((size & 7) != 0) ? 1 : 0);
20 int size = mp_count_bits(a);
21 return (size / 8) + ((((unsigned)size & 7u) != 0u) ? 1 : 0);
2222 }
2323 #endif
2424
25 /* $Source$ */
26 /* $Revision$ */
27 /* $Date$ */
25 /* ref: $Format:%D$ */
26 /* git commit: $Format:%H$ */
27 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* XOR two ints together */
18 int
19 mp_xor (mp_int * a, mp_int * b, mp_int * c)
18 int mp_xor(const mp_int *a, const mp_int *b, mp_int *c)
2019 {
21 int res, ix, px;
22 mp_int t, *x;
20 int res, ix, px;
21 mp_int t;
22 const mp_int *x;
2323
24 if (a->used > b->used) {
25 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
24 if (a->used > b->used) {
25 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
26 return res;
27 }
28 px = b->used;
29 x = b;
30 } else {
31 if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
32 return res;
33 }
34 px = a->used;
35 x = a;
36 }
3737
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] ^= x->dp[ix];
40 }
41 mp_clamp (&t);
42 mp_exch (c, &t);
43 mp_clear (&t);
44 return MP_OKAY;
38 for (ix = 0; ix < px; ix++) {
39 t.dp[ix] ^= x->dp[ix];
40 }
41 mp_clamp(&t);
42 mp_exch(c, &t);
43 mp_clear(&t);
44 return MP_OKAY;
4545 }
4646 #endif
4747
48 /* $Source$ */
49 /* $Revision$ */
50 /* $Date$ */
48 /* ref: $Format:%D$ */
49 /* git commit: $Format:%H$ */
50 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* set to zero */
18 void mp_zero (mp_int * a)
18 void mp_zero(mp_int *a)
1919 {
20 int n;
21 mp_digit *tmp;
20 int n;
21 mp_digit *tmp;
2222
23 a->sign = MP_ZPOS;
24 a->used = 0;
23 a->sign = MP_ZPOS;
24 a->used = 0;
2525
26 tmp = a->dp;
27 for (n = 0; n < a->alloc; n++) {
28 *tmp++ = 0;
29 }
26 tmp = a->dp;
27 for (n = 0; n < a->alloc; n++) {
28 *tmp++ = 0;
29 }
3030 }
3131 #endif
3232
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
33 /* ref: $Format:%D$ */
34 /* git commit: $Format:%H$ */
35 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616 const mp_digit ltm_prime_tab[] = {
17 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
18 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
19 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
20 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
17 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
18 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
19 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
20 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
2121 #ifndef MP_8BIT
22 0x0083,
23 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
24 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
25 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
26 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
22 0x0083,
23 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
24 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
25 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
26 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
2727
28 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
29 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
30 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
31 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
32 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
33 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
34 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
35 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
28 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
29 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
30 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
31 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
32 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
33 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
34 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
35 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
3636
37 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
38 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
39 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
40 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
41 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
42 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
43 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
44 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
37 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
38 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
39 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
40 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
41 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
42 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
43 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
44 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
4545
46 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
47 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
48 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
49 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
50 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
51 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
52 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
53 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
46 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
47 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
48 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
49 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
50 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
51 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
52 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
53 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
5454 #endif
5555 };
5656 #endif
5757
58 /* $Source$ */
59 /* $Revision$ */
60 /* $Date$ */
58 /* ref: $Format:%D$ */
59 /* git commit: $Format:%H$ */
60 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* reverse an array, used for radix code */
18 void
19 bn_reverse (unsigned char *s, int len)
18 void bn_reverse(unsigned char *s, int len)
2019 {
21 int ix, iy;
22 unsigned char t;
20 int ix, iy;
21 unsigned char t;
2322
24 ix = 0;
25 iy = len - 1;
26 while (ix < iy) {
27 t = s[ix];
28 s[ix] = s[iy];
29 s[iy] = t;
30 ++ix;
31 --iy;
32 }
23 ix = 0;
24 iy = len - 1;
25 while (ix < iy) {
26 t = s[ix];
27 s[ix] = s[iy];
28 s[iy] = t;
29 ++ix;
30 --iy;
31 }
3332 }
3433 #endif
3534
36 /* $Source$ */
37 /* $Revision$ */
38 /* $Date$ */
35 /* ref: $Format:%D$ */
36 /* git commit: $Format:%H$ */
37 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* low level addition, based on HAC pp.594, Algorithm 14.7 */
18 int
19 s_mp_add (mp_int * a, mp_int * b, mp_int * c)
18 int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
2019 {
21 mp_int *x;
22 int olduse, res, min, max;
20 const mp_int *x;
21 int olduse, res, min, max;
2322
24 /* find sizes, we let |a| <= |b| which means we have to sort
25 * them. "x" will point to the input with the most digits
26 */
27 if (a->used > b->used) {
28 min = b->used;
29 max = a->used;
30 x = a;
31 } else {
32 min = a->used;
33 max = b->used;
34 x = b;
35 }
23 /* find sizes, we let |a| <= |b| which means we have to sort
24 * them. "x" will point to the input with the most digits
25 */
26 if (a->used > b->used) {
27 min = b->used;
28 max = a->used;
29 x = a;
30 } else {
31 min = a->used;
32 max = b->used;
33 x = b;
34 }
3635
37 /* init result */
38 if (c->alloc < (max + 1)) {
39 if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
40 return res;
41 }
42 }
36 /* init result */
37 if (c->alloc < (max + 1)) {
38 if ((res = mp_grow(c, max + 1)) != MP_OKAY) {
39 return res;
40 }
41 }
4342
44 /* get old used digit count and set new one */
45 olduse = c->used;
46 c->used = max + 1;
43 /* get old used digit count and set new one */
44 olduse = c->used;
45 c->used = max + 1;
4746
48 {
49 mp_digit u, *tmpa, *tmpb, *tmpc;
50 int i;
47 {
48 mp_digit u, *tmpa, *tmpb, *tmpc;
49 int i;
5150
52 /* alias for digit pointers */
51 /* alias for digit pointers */
5352
54 /* first input */
55 tmpa = a->dp;
53 /* first input */
54 tmpa = a->dp;
5655
57 /* second input */
58 tmpb = b->dp;
56 /* second input */
57 tmpb = b->dp;
5958
60 /* destination */
61 tmpc = c->dp;
59 /* destination */
60 tmpc = c->dp;
6261
63 /* zero the carry */
64 u = 0;
65 for (i = 0; i < min; i++) {
66 /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
67 *tmpc = *tmpa++ + *tmpb++ + u;
62 /* zero the carry */
63 u = 0;
64 for (i = 0; i < min; i++) {
65 /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
66 *tmpc = *tmpa++ + *tmpb++ + u;
6867
69 /* U = carry bit of T[i] */
70 u = *tmpc >> ((mp_digit)DIGIT_BIT);
68 /* U = carry bit of T[i] */
69 u = *tmpc >> (mp_digit)DIGIT_BIT;
7170
72 /* take away carry bit from T[i] */
73 *tmpc++ &= MP_MASK;
74 }
71 /* take away carry bit from T[i] */
72 *tmpc++ &= MP_MASK;
73 }
7574
76 /* now copy higher words if any, that is in A+B
77 * if A or B has more digits add those in
78 */
79 if (min != max) {
80 for (; i < max; i++) {
81 /* T[i] = X[i] + U */
82 *tmpc = x->dp[i] + u;
75 /* now copy higher words if any, that is in A+B
76 * if A or B has more digits add those in
77 */
78 if (min != max) {
79 for (; i < max; i++) {
80 /* T[i] = X[i] + U */
81 *tmpc = x->dp[i] + u;
8382
84 /* U = carry bit of T[i] */
85 u = *tmpc >> ((mp_digit)DIGIT_BIT);
83 /* U = carry bit of T[i] */
84 u = *tmpc >> (mp_digit)DIGIT_BIT;
8685
87 /* take away carry bit from T[i] */
88 *tmpc++ &= MP_MASK;
86 /* take away carry bit from T[i] */
87 *tmpc++ &= MP_MASK;
88 }
8989 }
90 }
9190
92 /* add carry */
93 *tmpc++ = u;
91 /* add carry */
92 *tmpc++ = u;
9493
95 /* clear digits above oldused */
96 for (i = c->used; i < olduse; i++) {
97 *tmpc++ = 0;
98 }
99 }
94 /* clear digits above oldused */
95 for (i = c->used; i < olduse; i++) {
96 *tmpc++ = 0;
97 }
98 }
10099
101 mp_clamp (c);
102 return MP_OKAY;
100 mp_clamp(c);
101 return MP_OKAY;
103102 }
104103 #endif
105104
106 /* $Source$ */
107 /* $Revision$ */
108 /* $Date$ */
105 /* ref: $Format:%D$ */
106 /* git commit: $Format:%H$ */
107 /* commit time: $Format:%ai$ */
1414 * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
1515 */
1616 #ifdef MP_LOW_MEM
17 #define TAB_SIZE 32
17 # define TAB_SIZE 32
1818 #else
19 #define TAB_SIZE 256
19 # define TAB_SIZE 256
2020 #endif
2121
22 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
22 int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
2323 {
24 mp_int M[TAB_SIZE], res, mu;
25 mp_digit buf;
26 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
27 int (*redux)(mp_int*,mp_int*,mp_int*);
28
29 /* find window size */
30 x = mp_count_bits (X);
31 if (x <= 7) {
32 winsize = 2;
33 } else if (x <= 36) {
34 winsize = 3;
35 } else if (x <= 140) {
36 winsize = 4;
37 } else if (x <= 450) {
38 winsize = 5;
39 } else if (x <= 1303) {
40 winsize = 6;
41 } else if (x <= 3529) {
42 winsize = 7;
43 } else {
44 winsize = 8;
45 }
24 mp_int M[TAB_SIZE], res, mu;
25 mp_digit buf;
26 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
27 int (*redux)(mp_int *x, const mp_int *m, const mp_int *mu);
28
29 /* find window size */
30 x = mp_count_bits(X);
31 if (x <= 7) {
32 winsize = 2;
33 } else if (x <= 36) {
34 winsize = 3;
35 } else if (x <= 140) {
36 winsize = 4;
37 } else if (x <= 450) {
38 winsize = 5;
39 } else if (x <= 1303) {
40 winsize = 6;
41 } else if (x <= 3529) {
42 winsize = 7;
43 } else {
44 winsize = 8;
45 }
4646
4747 #ifdef MP_LOW_MEM
48 if (winsize > 5) {
49 winsize = 5;
50 }
48 if (winsize > 5) {
49 winsize = 5;
50 }
5151 #endif
5252
53 /* init M array */
54 /* init first cell */
55 if ((err = mp_init(&M[1])) != MP_OKAY) {
56 return err;
57 }
58
59 /* now init the second half of the array */
60 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
61 if ((err = mp_init(&M[x])) != MP_OKAY) {
62 for (y = 1<<(winsize-1); y < x; y++) {
63 mp_clear (&M[y]);
64 }
65 mp_clear(&M[1]);
53 /* init M array */
54 /* init first cell */
55 if ((err = mp_init(&M[1])) != MP_OKAY) {
6656 return err;
67 }
68 }
69
70 /* create mu, used for Barrett reduction */
71 if ((err = mp_init (&mu)) != MP_OKAY) {
72 goto LBL_M;
73 }
74
75 if (redmode == 0) {
76 if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
77 goto LBL_MU;
78 }
79 redux = mp_reduce;
80 } else {
81 if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
82 goto LBL_MU;
83 }
84 redux = mp_reduce_2k_l;
85 }
86
87 /* create M table
88 *
89 * The M table contains powers of the base,
90 * e.g. M[x] = G**x mod P
91 *
92 * The first half of the table is not
93 * computed though accept for M[0] and M[1]
94 */
95 if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
96 goto LBL_MU;
97 }
98
99 /* compute the value at M[1<<(winsize-1)] by squaring
100 * M[1] (winsize-1) times
101 */
102 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
103 goto LBL_MU;
104 }
105
106 for (x = 0; x < (winsize - 1); x++) {
107 /* square it */
108 if ((err = mp_sqr (&M[1 << (winsize - 1)],
109 &M[1 << (winsize - 1)])) != MP_OKAY) {
57 }
58
59 /* now init the second half of the array */
60 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
61 if ((err = mp_init(&M[x])) != MP_OKAY) {
62 for (y = 1<<(winsize-1); y < x; y++) {
63 mp_clear(&M[y]);
64 }
65 mp_clear(&M[1]);
66 return err;
67 }
68 }
69
70 /* create mu, used for Barrett reduction */
71 if ((err = mp_init(&mu)) != MP_OKAY) {
72 goto LBL_M;
73 }
74
75 if (redmode == 0) {
76 if ((err = mp_reduce_setup(&mu, P)) != MP_OKAY) {
77 goto LBL_MU;
78 }
79 redux = mp_reduce;
80 } else {
81 if ((err = mp_reduce_2k_setup_l(P, &mu)) != MP_OKAY) {
82 goto LBL_MU;
83 }
84 redux = mp_reduce_2k_l;
85 }
86
87 /* create M table
88 *
89 * The M table contains powers of the base,
90 * e.g. M[x] = G**x mod P
91 *
92 * The first half of the table is not
93 * computed though accept for M[0] and M[1]
94 */
95 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
11096 goto LBL_MU;
111 }
112
113 /* reduce modulo P */
114 if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
97 }
98
99 /* compute the value at M[1<<(winsize-1)] by squaring
100 * M[1] (winsize-1) times
101 */
102 if ((err = mp_copy(&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
115103 goto LBL_MU;
116 }
117 }
118
119 /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
120 * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
121 */
122 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
123 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
104 }
105
106 for (x = 0; x < (winsize - 1); x++) {
107 /* square it */
108 if ((err = mp_sqr(&M[1 << (winsize - 1)],
109 &M[1 << (winsize - 1)])) != MP_OKAY) {
110 goto LBL_MU;
111 }
112
113 /* reduce modulo P */
114 if ((err = redux(&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
115 goto LBL_MU;
116 }
117 }
118
119 /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
120 * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
121 */
122 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
123 if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
124 goto LBL_MU;
125 }
126 if ((err = redux(&M[x], P, &mu)) != MP_OKAY) {
127 goto LBL_MU;
128 }
129 }
130
131 /* setup result */
132 if ((err = mp_init(&res)) != MP_OKAY) {
124133 goto LBL_MU;
125 }
126 if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
127 goto LBL_MU;
128 }
129 }
130
131 /* setup result */
132 if ((err = mp_init (&res)) != MP_OKAY) {
133 goto LBL_MU;
134 }
135 mp_set (&res, 1);
136
137 /* set initial mode and bit cnt */
138 mode = 0;
139 bitcnt = 1;
140 buf = 0;
141 digidx = X->used - 1;
142 bitcpy = 0;
143 bitbuf = 0;
144
145 for (;;) {
146 /* grab next digit as required */
147 if (--bitcnt == 0) {
148 /* if digidx == -1 we are out of digits */
149 if (digidx == -1) {
150 break;
151 }
152 /* read next digit and reset the bitcnt */
153 buf = X->dp[digidx--];
154 bitcnt = (int) DIGIT_BIT;
155 }
156
157 /* grab the next msb from the exponent */
158 y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
159 buf <<= (mp_digit)1;
160
161 /* if the bit is zero and mode == 0 then we ignore it
162 * These represent the leading zero bits before the first 1 bit
163 * in the exponent. Technically this opt is not required but it
164 * does lower the # of trivial squaring/reductions used
165 */
166 if ((mode == 0) && (y == 0)) {
167 continue;
168 }
169
170 /* if the bit is zero and mode == 1 then we square */
171 if ((mode == 1) && (y == 0)) {
172 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
173 goto LBL_RES;
174 }
175 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
176 goto LBL_RES;
177 }
178 continue;
179 }
180
181 /* else we add it to the window */
182 bitbuf |= (y << (winsize - ++bitcpy));
183 mode = 2;
184
185 if (bitcpy == winsize) {
186 /* ok window is filled so square as required and multiply */
187 /* square first */
188 for (x = 0; x < winsize; x++) {
189 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
190 goto LBL_RES;
191 }
192 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
193 goto LBL_RES;
194 }
195 }
196
197 /* then multiply */
198 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
199 goto LBL_RES;
200 }
201 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
202 goto LBL_RES;
203 }
204
205 /* empty window and reset */
206 bitcpy = 0;
207 bitbuf = 0;
208 mode = 1;
209 }
210 }
211
212 /* if bits remain then square/multiply */
213 if ((mode == 2) && (bitcpy > 0)) {
214 /* square then multiply if the bit is set */
215 for (x = 0; x < bitcpy; x++) {
216 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
217 goto LBL_RES;
218 }
219 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
220 goto LBL_RES;
221 }
222
223 bitbuf <<= 1;
224 if ((bitbuf & (1 << winsize)) != 0) {
225 /* then multiply */
226 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
227 goto LBL_RES;
228 }
229 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
230 goto LBL_RES;
231 }
232 }
233 }
234 }
235
236 mp_exch (&res, Y);
237 err = MP_OKAY;
238 LBL_RES:mp_clear (&res);
239 LBL_MU:mp_clear (&mu);
134 }
135 mp_set(&res, 1uL);
136
137 /* set initial mode and bit cnt */
138 mode = 0;
139 bitcnt = 1;
140 buf = 0;
141 digidx = X->used - 1;
142 bitcpy = 0;
143 bitbuf = 0;
144
145 for (;;) {
146 /* grab next digit as required */
147 if (--bitcnt == 0) {
148 /* if digidx == -1 we are out of digits */
149 if (digidx == -1) {
150 break;
151 }
152 /* read next digit and reset the bitcnt */
153 buf = X->dp[digidx--];
154 bitcnt = (int)DIGIT_BIT;
155 }
156
157 /* grab the next msb from the exponent */
158 y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
159 buf <<= (mp_digit)1;
160
161 /* if the bit is zero and mode == 0 then we ignore it
162 * These represent the leading zero bits before the first 1 bit
163 * in the exponent. Technically this opt is not required but it
164 * does lower the # of trivial squaring/reductions used
165 */
166 if ((mode == 0) && (y == 0)) {
167 continue;
168 }
169
170 /* if the bit is zero and mode == 1 then we square */
171 if ((mode == 1) && (y == 0)) {
172 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
173 goto LBL_RES;
174 }
175 if ((err = redux(&res, P, &mu)) != MP_OKAY) {
176 goto LBL_RES;
177 }
178 continue;
179 }
180
181 /* else we add it to the window */
182 bitbuf |= (y << (winsize - ++bitcpy));
183 mode = 2;
184
185 if (bitcpy == winsize) {
186 /* ok window is filled so square as required and multiply */
187 /* square first */
188 for (x = 0; x < winsize; x++) {
189 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
190 goto LBL_RES;
191 }
192 if ((err = redux(&res, P, &mu)) != MP_OKAY) {
193 goto LBL_RES;
194 }
195 }
196
197 /* then multiply */
198 if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) {
199 goto LBL_RES;
200 }
201 if ((err = redux(&res, P, &mu)) != MP_OKAY) {
202 goto LBL_RES;
203 }
204
205 /* empty window and reset */
206 bitcpy = 0;
207 bitbuf = 0;
208 mode = 1;
209 }
210 }
211
212 /* if bits remain then square/multiply */
213 if ((mode == 2) && (bitcpy > 0)) {
214 /* square then multiply if the bit is set */
215 for (x = 0; x < bitcpy; x++) {
216 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
217 goto LBL_RES;
218 }
219 if ((err = redux(&res, P, &mu)) != MP_OKAY) {
220 goto LBL_RES;
221 }
222
223 bitbuf <<= 1;
224 if ((bitbuf & (1 << winsize)) != 0) {
225 /* then multiply */
226 if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) {
227 goto LBL_RES;
228 }
229 if ((err = redux(&res, P, &mu)) != MP_OKAY) {
230 goto LBL_RES;
231 }
232 }
233 }
234 }
235
236 mp_exch(&res, Y);
237 err = MP_OKAY;
238 LBL_RES:
239 mp_clear(&res);
240 LBL_MU:
241 mp_clear(&mu);
240242 LBL_M:
241 mp_clear(&M[1]);
242 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
243 mp_clear (&M[x]);
244 }
245 return err;
243 mp_clear(&M[1]);
244 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
245 mp_clear(&M[x]);
246 }
247 return err;
246248 }
247249 #endif
248250
249 /* $Source$ */
250 /* $Revision$ */
251 /* $Date$ */
251 /* ref: $Format:%D$ */
252 /* git commit: $Format:%H$ */
253 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* multiplies |a| * |b| and only computes upto digs digits of result
18 * HAC pp. 595, Algorithm 14.12 Modified so you can control how
18 * HAC pp. 595, Algorithm 14.12 Modified so you can control how
1919 * many digits of output are created.
2020 */
21 int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
21 int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
2222 {
23 mp_int t;
24 int res, pa, pb, ix, iy;
25 mp_digit u;
26 mp_word r;
27 mp_digit tmpx, *tmpt, *tmpy;
23 mp_int t;
24 int res, pa, pb, ix, iy;
25 mp_digit u;
26 mp_word r;
27 mp_digit tmpx, *tmpt, *tmpy;
2828
29 /* can we use the fast multiplier? */
30 if (((digs) < MP_WARRAY) &&
31 (MIN (a->used, b->used) <
32 (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
33 return fast_s_mp_mul_digs (a, b, c, digs);
34 }
29 /* can we use the fast multiplier? */
30 if ((digs < (int)MP_WARRAY) &&
31 (MIN(a->used, b->used) <
32 (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) {
33 return fast_s_mp_mul_digs(a, b, c, digs);
34 }
3535
36 if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
37 return res;
38 }
39 t.used = digs;
36 if ((res = mp_init_size(&t, digs)) != MP_OKAY) {
37 return res;
38 }
39 t.used = digs;
4040
41 /* compute the digits of the product directly */
42 pa = a->used;
43 for (ix = 0; ix < pa; ix++) {
44 /* set the carry to zero */
45 u = 0;
41 /* compute the digits of the product directly */
42 pa = a->used;
43 for (ix = 0; ix < pa; ix++) {
44 /* set the carry to zero */
45 u = 0;
4646
47 /* limit ourselves to making digs digits of output */
48 pb = MIN (b->used, digs - ix);
47 /* limit ourselves to making digs digits of output */
48 pb = MIN(b->used, digs - ix);
4949
50 /* setup some aliases */
51 /* copy of the digit from a used within the nested loop */
52 tmpx = a->dp[ix];
53
54 /* an alias for the destination shifted ix places */
55 tmpt = t.dp + ix;
56
57 /* an alias for the digits of b */
58 tmpy = b->dp;
50 /* setup some aliases */
51 /* copy of the digit from a used within the nested loop */
52 tmpx = a->dp[ix];
5953
60 /* compute the columns of the output and propagate the carry */
61 for (iy = 0; iy < pb; iy++) {
62 /* compute the column as a mp_word */
63 r = (mp_word)*tmpt +
64 ((mp_word)tmpx * (mp_word)*tmpy++) +
65 (mp_word)u;
54 /* an alias for the destination shifted ix places */
55 tmpt = t.dp + ix;
6656
67 /* the new column is the lower part of the result */
68 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
57 /* an alias for the digits of b */
58 tmpy = b->dp;
6959
70 /* get the carry word from the result */
71 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
72 }
73 /* set carry if it is placed below digs */
74 if ((ix + iy) < digs) {
75 *tmpt = u;
76 }
77 }
60 /* compute the columns of the output and propagate the carry */
61 for (iy = 0; iy < pb; iy++) {
62 /* compute the column as a mp_word */
63 r = (mp_word)*tmpt +
64 ((mp_word)tmpx * (mp_word)*tmpy++) +
65 (mp_word)u;
7866
79 mp_clamp (&t);
80 mp_exch (&t, c);
67 /* the new column is the lower part of the result */
68 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
8169
82 mp_clear (&t);
83 return MP_OKAY;
70 /* get the carry word from the result */
71 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
72 }
73 /* set carry if it is placed below digs */
74 if ((ix + iy) < digs) {
75 *tmpt = u;
76 }
77 }
78
79 mp_clamp(&t);
80 mp_exch(&t, c);
81
82 mp_clear(&t);
83 return MP_OKAY;
8484 }
8585 #endif
8686
87 /* $Source$ */
88 /* $Revision$ */
89 /* $Date$ */
87 /* ref: $Format:%D$ */
88 /* git commit: $Format:%H$ */
89 /* commit time: $Format:%ai$ */
1717 /* multiplies |a| * |b| and does not compute the lower digs digits
1818 * [meant to get the higher part of the product]
1919 */
20 int
21 s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
20 int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
2221 {
23 mp_int t;
24 int res, pa, pb, ix, iy;
25 mp_digit u;
26 mp_word r;
27 mp_digit tmpx, *tmpt, *tmpy;
22 mp_int t;
23 int res, pa, pb, ix, iy;
24 mp_digit u;
25 mp_word r;
26 mp_digit tmpx, *tmpt, *tmpy;
2827
29 /* can we use the fast multiplier? */
28 /* can we use the fast multiplier? */
3029 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
31 if (((a->used + b->used + 1) < MP_WARRAY)
32 && (MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
33 return fast_s_mp_mul_high_digs (a, b, c, digs);
34 }
30 if (((a->used + b->used + 1) < (int)MP_WARRAY)
31 && (MIN(a->used, b->used) < (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) {
32 return fast_s_mp_mul_high_digs(a, b, c, digs);
33 }
3534 #endif
3635
37 if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
38 return res;
39 }
40 t.used = a->used + b->used + 1;
36 if ((res = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) {
37 return res;
38 }
39 t.used = a->used + b->used + 1;
4140
42 pa = a->used;
43 pb = b->used;
44 for (ix = 0; ix < pa; ix++) {
45 /* clear the carry */
46 u = 0;
41 pa = a->used;
42 pb = b->used;
43 for (ix = 0; ix < pa; ix++) {
44 /* clear the carry */
45 u = 0;
4746
48 /* left hand side of A[ix] * B[iy] */
49 tmpx = a->dp[ix];
47 /* left hand side of A[ix] * B[iy] */
48 tmpx = a->dp[ix];
5049
51 /* alias to the address of where the digits will be stored */
52 tmpt = &(t.dp[digs]);
50 /* alias to the address of where the digits will be stored */
51 tmpt = &(t.dp[digs]);
5352
54 /* alias for where to read the right hand side from */
55 tmpy = b->dp + (digs - ix);
53 /* alias for where to read the right hand side from */
54 tmpy = b->dp + (digs - ix);
5655
57 for (iy = digs - ix; iy < pb; iy++) {
58 /* calculate the double precision result */
59 r = (mp_word)*tmpt +
60 ((mp_word)tmpx * (mp_word)*tmpy++) +
61 (mp_word)u;
56 for (iy = digs - ix; iy < pb; iy++) {
57 /* calculate the double precision result */
58 r = (mp_word)*tmpt +
59 ((mp_word)tmpx * (mp_word)*tmpy++) +
60 (mp_word)u;
6261
63 /* get the lower part */
64 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
62 /* get the lower part */
63 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
6564
66 /* carry the carry */
67 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
68 }
69 *tmpt = u;
70 }
71 mp_clamp (&t);
72 mp_exch (&t, c);
73 mp_clear (&t);
74 return MP_OKAY;
65 /* carry the carry */
66 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
67 }
68 *tmpt = u;
69 }
70 mp_clamp(&t);
71 mp_exch(&t, c);
72 mp_clear(&t);
73 return MP_OKAY;
7574 }
7675 #endif
7776
78 /* $Source$ */
79 /* $Revision$ */
80 /* $Date$ */
77 /* ref: $Format:%D$ */
78 /* git commit: $Format:%H$ */
79 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
18 int s_mp_sqr (mp_int * a, mp_int * b)
18 int s_mp_sqr(const mp_int *a, mp_int *b)
1919 {
20 mp_int t;
21 int res, ix, iy, pa;
22 mp_word r;
23 mp_digit u, tmpx, *tmpt;
20 mp_int t;
21 int res, ix, iy, pa;
22 mp_word r;
23 mp_digit u, tmpx, *tmpt;
2424
25 pa = a->used;
26 if ((res = mp_init_size (&t, (2 * pa) + 1)) != MP_OKAY) {
27 return res;
28 }
25 pa = a->used;
26 if ((res = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) {
27 return res;
28 }
2929
30 /* default used is maximum possible size */
31 t.used = (2 * pa) + 1;
30 /* default used is maximum possible size */
31 t.used = (2 * pa) + 1;
3232
33 for (ix = 0; ix < pa; ix++) {
34 /* first calculate the digit at 2*ix */
35 /* calculate double precision result */
36 r = (mp_word)t.dp[2*ix] +
37 ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]);
33 for (ix = 0; ix < pa; ix++) {
34 /* first calculate the digit at 2*ix */
35 /* calculate double precision result */
36 r = (mp_word)t.dp[2*ix] +
37 ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]);
3838
39 /* store lower part in result */
40 t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
39 /* store lower part in result */
40 t.dp[ix+ix] = (mp_digit)(r & (mp_word)MP_MASK);
4141
42 /* get the carry */
43 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
42 /* get the carry */
43 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
4444
45 /* left hand side of A[ix] * A[iy] */
46 tmpx = a->dp[ix];
45 /* left hand side of A[ix] * A[iy] */
46 tmpx = a->dp[ix];
4747
48 /* alias for where to store the results */
49 tmpt = t.dp + ((2 * ix) + 1);
50
51 for (iy = ix + 1; iy < pa; iy++) {
52 /* first calculate the product */
53 r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
48 /* alias for where to store the results */
49 tmpt = t.dp + ((2 * ix) + 1);
5450
55 /* now calculate the double precision result, note we use
56 * addition instead of *2 since it's easier to optimize
57 */
58 r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
51 for (iy = ix + 1; iy < pa; iy++) {
52 /* first calculate the product */
53 r = (mp_word)tmpx * (mp_word)a->dp[iy];
5954
60 /* store lower part */
61 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
55 /* now calculate the double precision result, note we use
56 * addition instead of *2 since it's easier to optimize
57 */
58 r = (mp_word)*tmpt + r + r + (mp_word)u;
6259
63 /* get carry */
64 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
65 }
66 /* propagate upwards */
67 while (u != ((mp_digit) 0)) {
68 r = ((mp_word) *tmpt) + ((mp_word) u);
69 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
70 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
71 }
72 }
60 /* store lower part */
61 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
7362
74 mp_clamp (&t);
75 mp_exch (&t, b);
76 mp_clear (&t);
77 return MP_OKAY;
63 /* get carry */
64 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
65 }
66 /* propagate upwards */
67 while (u != 0uL) {
68 r = (mp_word)*tmpt + (mp_word)u;
69 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
70 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
71 }
72 }
73
74 mp_clamp(&t);
75 mp_exch(&t, b);
76 mp_clear(&t);
77 return MP_OKAY;
7878 }
7979 #endif
8080
81 /* $Source$ */
82 /* $Revision$ */
83 /* $Date$ */
81 /* ref: $Format:%D$ */
82 /* git commit: $Format:%H$ */
83 /* commit time: $Format:%ai$ */
1515 */
1616
1717 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
18 int
19 s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
18 int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
2019 {
21 int olduse, res, min, max;
20 int olduse, res, min, max;
2221
23 /* find sizes */
24 min = b->used;
25 max = a->used;
22 /* find sizes */
23 min = b->used;
24 max = a->used;
2625
27 /* init result */
28 if (c->alloc < max) {
29 if ((res = mp_grow (c, max)) != MP_OKAY) {
30 return res;
31 }
32 }
33 olduse = c->used;
34 c->used = max;
26 /* init result */
27 if (c->alloc < max) {
28 if ((res = mp_grow(c, max)) != MP_OKAY) {
29 return res;
30 }
31 }
32 olduse = c->used;
33 c->used = max;
3534
36 {
37 mp_digit u, *tmpa, *tmpb, *tmpc;
38 int i;
35 {
36 mp_digit u, *tmpa, *tmpb, *tmpc;
37 int i;
3938
40 /* alias for digit pointers */
41 tmpa = a->dp;
42 tmpb = b->dp;
43 tmpc = c->dp;
39 /* alias for digit pointers */
40 tmpa = a->dp;
41 tmpb = b->dp;
42 tmpc = c->dp;
4443
45 /* set carry to zero */
46 u = 0;
47 for (i = 0; i < min; i++) {
48 /* T[i] = A[i] - B[i] - U */
49 *tmpc = (*tmpa++ - *tmpb++) - u;
44 /* set carry to zero */
45 u = 0;
46 for (i = 0; i < min; i++) {
47 /* T[i] = A[i] - B[i] - U */
48 *tmpc = (*tmpa++ - *tmpb++) - u;
5049
51 /* U = carry bit of T[i]
52 * Note this saves performing an AND operation since
53 * if a carry does occur it will propagate all the way to the
54 * MSB. As a result a single shift is enough to get the carry
55 */
56 u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1));
50 /* U = carry bit of T[i]
51 * Note this saves performing an AND operation since
52 * if a carry does occur it will propagate all the way to the
53 * MSB. As a result a single shift is enough to get the carry
54 */
55 u = *tmpc >> (((size_t)CHAR_BIT * sizeof(mp_digit)) - 1u);
5756
58 /* Clear carry from T[i] */
59 *tmpc++ &= MP_MASK;
60 }
57 /* Clear carry from T[i] */
58 *tmpc++ &= MP_MASK;
59 }
6160
62 /* now copy higher words if any, e.g. if A has more digits than B */
63 for (; i < max; i++) {
64 /* T[i] = A[i] - U */
65 *tmpc = *tmpa++ - u;
61 /* now copy higher words if any, e.g. if A has more digits than B */
62 for (; i < max; i++) {
63 /* T[i] = A[i] - U */
64 *tmpc = *tmpa++ - u;
6665
67 /* U = carry bit of T[i] */
68 u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1));
66 /* U = carry bit of T[i] */
67 u = *tmpc >> (((size_t)CHAR_BIT * sizeof(mp_digit)) - 1u);
6968
70 /* Clear carry from T[i] */
71 *tmpc++ &= MP_MASK;
72 }
69 /* Clear carry from T[i] */
70 *tmpc++ &= MP_MASK;
71 }
7372
74 /* clear digits above used (since we may not have grown result above) */
75 for (i = c->used; i < olduse; i++) {
76 *tmpc++ = 0;
77 }
78 }
73 /* clear digits above used (since we may not have grown result above) */
74 for (i = c->used; i < olduse; i++) {
75 *tmpc++ = 0;
76 }
77 }
7978
80 mp_clamp (c);
81 return MP_OKAY;
79 mp_clamp(c);
80 return MP_OKAY;
8281 }
8382
8483 #endif
8584
86 /* $Source$ */
87 /* $Revision$ */
88 /* $Date$ */
85 /* ref: $Format:%D$ */
86 /* git commit: $Format:%H$ */
87 /* commit time: $Format:%ai$ */
2020 -------------------------------------------------------------
2121 Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-)
2222 AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35
23
23
2424 */
2525
2626 int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */
2727 KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */
28
28
2929 TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
30 TOOM_SQR_CUTOFF = 400;
30 TOOM_SQR_CUTOFF = 400;
3131 #endif
3232
33 /* $Source$ */
34 /* $Revision$ */
35 /* $Date$ */
33 /* ref: $Format:%D$ */
34 /* git commit: $Format:%H$ */
35 /* commit time: $Format:%ai$ */
1818 #include <stdlib.h>
1919 #include <limits.h>
2020
21 #if !defined(_MSC_VER) || _MSC_VER >= 1600
22 /* supported since Microsoft Visual Studio 2010 */
23 #include <stdint.h>
24 #else
25 typedef signed char int8_t;
26 typedef unsigned char uint8_t;
27 typedef signed short int16_t;
28 typedef unsigned short uint16_t;
29 typedef signed int int32_t;
30 typedef unsigned int uint32_t;
31 # ifdef _MSC_VER
32 /* long long does not work before MS Visual C++ 7.0 */
33 typedef signed __int64 int64_t;
34 typedef unsigned __int64 uint64_t;
35 # else
36 typedef long long int64_t;
37 typedef unsigned long long uint64_t;
38 # endif
39 #endif
40
2141 #include <tommath_class.h>
2242
2343 #ifdef __cplusplus
2444 extern "C" {
2545 #endif
2646
27 /* unsigned int types */
28 typedef unsigned char mp_uint8;
29 typedef unsigned short mp_uint16;
30 typedef unsigned int mp_uint32;
31 #ifdef _MSC_VER
32 #undef BN_MP_SET_LONG_LONG_C
33 #undef BN_MP_GET_LONG_LONG_C
34 typedef unsigned __int64 mp_uint64;
35 #else
36 typedef unsigned long long mp_uint64;
47 /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */
48 #if defined(_MSC_VER) || defined(__LLP64__)
49 # define MP_32BIT
3750 #endif
3851
3952 /* detect 64-bit mode if possible */
40 #if defined(__x86_64__)
41 #if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
42 #if defined(__GNUC__)
43 typedef unsigned long mp_uint128 __attribute__ ((mode(TI)));
44 #define MP_64BIT
45 #elif defined(_MSC_VER)
46 typedef unsigned __int128 mp_uint128;
47 #define MP_64BIT
48 #endif
49 #endif
53 #if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \
54 defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \
55 defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \
56 defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \
57 defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \
58 defined(__LP64__) || defined(_LP64) || defined(__64BIT__)
59 # if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
60 # define MP_64BIT
61 # endif
5062 #endif
5163
5264 /* some default configurations.
5870 * [any size beyond that is ok provided it doesn't overflow the data type]
5971 */
6072 #ifdef MP_8BIT
61 typedef mp_uint8 mp_digit;
62 typedef mp_uint16 mp_word;
63 #define MP_SIZEOF_MP_DIGIT 1
64 #ifdef DIGIT_BIT
65 #error You must not define DIGIT_BIT when using MP_8BIT
66 #endif
73 typedef uint8_t mp_digit;
74 typedef uint16_t mp_word;
75 # define MP_SIZEOF_MP_DIGIT 1
76 # ifdef DIGIT_BIT
77 # error You must not define DIGIT_BIT when using MP_8BIT
78 # endif
6779 #elif defined(MP_16BIT)
68 typedef mp_uint16 mp_digit;
69 typedef mp_uint32 mp_word;
70 #define MP_SIZEOF_MP_DIGIT 2
71 #ifdef DIGIT_BIT
72 #error You must not define DIGIT_BIT when using MP_16BIT
73 #endif
80 typedef uint16_t mp_digit;
81 typedef uint32_t mp_word;
82 # define MP_SIZEOF_MP_DIGIT 2
83 # ifdef DIGIT_BIT
84 # error You must not define DIGIT_BIT when using MP_16BIT
85 # endif
7486 #elif defined(MP_64BIT)
75 typedef mp_uint64 mp_digit;
76 typedef mp_uint128 mp_word;
77 #define DIGIT_BIT 60
87 /* for GCC only on supported platforms */
88 typedef uint64_t mp_digit;
89 # if defined(__GNUC__)
90 typedef unsigned long mp_word __attribute__((mode(TI)));
91 # else
92 /* it seems you have a problem
93 * but we assume you can somewhere define your own uint128_t */
94 typedef uint128_t mp_word;
95 # endif
96
97 # define DIGIT_BIT 60
7898 #else
79 /* this is the default case, 28-bit digits */
80
81 /* this is to make porting into LibTomCrypt easier :-) */
82 typedef mp_uint32 mp_digit;
83 typedef mp_uint64 mp_word;
84
85 #ifdef MP_31BIT
86 /* this is an extension that uses 31-bit digits */
87 #define DIGIT_BIT 31
88 #else
89 /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
90 #define DIGIT_BIT 28
91 #define MP_28BIT
92 #endif
99 /* this is the default case, 28-bit digits */
100
101 /* this is to make porting into LibTomCrypt easier :-) */
102 typedef uint32_t mp_digit;
103 typedef uint64_t mp_word;
104
105 # ifdef MP_31BIT
106 /* this is an extension that uses 31-bit digits */
107 # define DIGIT_BIT 31
108 # else
109 /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
110 # define DIGIT_BIT 28
111 # define MP_28BIT
112 # endif
93113 #endif
94114
95115 /* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
96116 #ifndef DIGIT_BIT
97 #define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
98 typedef mp_uint32 mp_min_u32;
117 # define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
118 typedef uint_least32_t mp_min_u32;
99119 #else
100 typedef mp_digit mp_min_u32;
101 #endif
102
103 /* platforms that can use a better rand function */
120 typedef mp_digit mp_min_u32;
121 #endif
122
123 /* use arc4random on platforms that support it */
104124 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
105 #define MP_USE_ALT_RAND 1
106 #endif
107
108 /* use arc4random on platforms that support it */
109 #ifdef MP_USE_ALT_RAND
110 #define MP_GEN_RANDOM() arc4random()
111 #define MP_GEN_RANDOM_MAX 0xffffffff
112 #else
113 #define MP_GEN_RANDOM() rand()
114 #define MP_GEN_RANDOM_MAX RAND_MAX
125 # define MP_GEN_RANDOM() arc4random()
126 # define MP_GEN_RANDOM_MAX 0xffffffffu
127 #endif
128
129 /* use rand() as fall-back if there's no better rand function */
130 #ifndef MP_GEN_RANDOM
131 # define MP_GEN_RANDOM() rand()
132 # define MP_GEN_RANDOM_MAX RAND_MAX
115133 #endif
116134
117135 #define MP_DIGIT_BIT DIGIT_BIT
143161
144162 /* you'll have to tune these... */
145163 extern int KARATSUBA_MUL_CUTOFF,
146 KARATSUBA_SQR_CUTOFF,
147 TOOM_MUL_CUTOFF,
148 TOOM_SQR_CUTOFF;
164 KARATSUBA_SQR_CUTOFF,
165 TOOM_MUL_CUTOFF,
166 TOOM_SQR_CUTOFF;
149167
150168 /* define this to use lower memory usage routines (exptmods mostly) */
151169 /* #define MP_LOW_MEM */
152170
153171 /* default precision */
154172 #ifndef MP_PREC
155 #ifndef MP_LOW_MEM
156 #define MP_PREC 32 /* default digits of precision */
157 #else
158 #define MP_PREC 8 /* default digits of precision */
159 #endif
173 # ifndef MP_LOW_MEM
174 # define MP_PREC 32 /* default digits of precision */
175 # else
176 # define MP_PREC 8 /* default digits of precision */
177 # endif
160178 #endif
161179
162180 /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
163 #define MP_WARRAY (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
181 #define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
164182
165183 /* the infamous mp_int structure */
166184 typedef struct {
167 int used, alloc, sign;
168 mp_digit *dp;
185 int used, alloc, sign;
186 mp_digit *dp;
169187 } mp_int;
170188
171189 /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
172190 typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
173191
174192
175 #define USED(m) ((m)->used)
176 #define DIGIT(m,k) ((m)->dp[(k)])
177 #define SIGN(m) ((m)->sign)
193 #define USED(m) ((m)->used)
194 #define DIGIT(m, k) ((m)->dp[(k)])
195 #define SIGN(m) ((m)->sign)
178196
179197 /* error code to char* string */
180198 const char *mp_error_to_string(int code);
206224
207225 /* ---> Basic Manipulations <--- */
208226 #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
209 #define mp_iseven(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO)
227 #define mp_iseven(a) ((((a)->used == 0) || (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO)
210228 #define mp_isodd(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO)
211229 #define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
212230
222240 /* set a platform dependent unsigned long value */
223241 int mp_set_long(mp_int *a, unsigned long b);
224242
225 #ifdef BN_MP_SET_LONG_LONG_C
226243 /* set a platform dependent unsigned long long value */
227 int mp_set_long_long(mp_int *a, unsigned long long b);
228 #endif
244 int mp_set_long_long(mp_int *a, uint64_t b);
229245
230246 /* get a 32-bit value */
231 unsigned long mp_get_int(mp_int * a);
247 unsigned long mp_get_int(const mp_int *a);
232248
233249 /* get a platform dependent unsigned long value */
234 unsigned long mp_get_long(mp_int * a);
235
236 #ifdef BN_MP_GET_LONG_LONG_C
250 unsigned long mp_get_long(const mp_int *a);
251
237252 /* get a platform dependent unsigned long long value */
238 unsigned long long mp_get_long_long(mp_int * a);
239 #endif
253 uint64_t mp_get_long_long(const mp_int *a);
240254
241255 /* initialize and set a digit */
242 int mp_init_set (mp_int * a, mp_digit b);
256 int mp_init_set(mp_int *a, mp_digit b);
243257
244258 /* initialize and set 32-bit value */
245 int mp_init_set_int (mp_int * a, unsigned long b);
259 int mp_init_set_int(mp_int *a, unsigned long b);
246260
247261 /* copy, b = a */
248 int mp_copy(mp_int *a, mp_int *b);
262 int mp_copy(const mp_int *a, mp_int *b);
249263
250264 /* inits and copies, a = b */
251 int mp_init_copy(mp_int *a, mp_int *b);
265 int mp_init_copy(mp_int *a, const mp_int *b);
252266
253267 /* trim unused digits */
254268 void mp_clamp(mp_int *a);
255269
256270 /* import binary data */
257 int mp_import(mp_int* rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op);
271 int mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op);
258272
259273 /* export binary data */
260 int mp_export(void* rop, size_t* countp, int order, size_t size, int endian, size_t nails, mp_int* op);
274 int mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mp_int *op);
261275
262276 /* ---> digit manipulation <--- */
263277
268282 int mp_lshd(mp_int *a, int b);
269283
270284 /* c = a / 2**b, implemented as c = a >> b */
271 int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
285 int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d);
272286
273287 /* b = a/2 */
274 int mp_div_2(mp_int *a, mp_int *b);
288 int mp_div_2(const mp_int *a, mp_int *b);
275289
276290 /* c = a * 2**b, implemented as c = a << b */
277 int mp_mul_2d(mp_int *a, int b, mp_int *c);
291 int mp_mul_2d(const mp_int *a, int b, mp_int *c);
278292
279293 /* b = a*2 */
280 int mp_mul_2(mp_int *a, mp_int *b);
294 int mp_mul_2(const mp_int *a, mp_int *b);
281295
282296 /* c = a mod 2**b */
283 int mp_mod_2d(mp_int *a, int b, mp_int *c);
297 int mp_mod_2d(const mp_int *a, int b, mp_int *c);
284298
285299 /* computes a = 2**b */
286300 int mp_2expt(mp_int *a, int b);
287301
288302 /* Counts the number of lsbs which are zero before the first zero bit */
289 int mp_cnt_lsb(mp_int *a);
303 int mp_cnt_lsb(const mp_int *a);
290304
291305 /* I Love Earth! */
292306
295309
296310 /* ---> binary operations <--- */
297311 /* c = a XOR b */
298 int mp_xor(mp_int *a, mp_int *b, mp_int *c);
312 int mp_xor(const mp_int *a, const mp_int *b, mp_int *c);
299313
300314 /* c = a OR b */
301 int mp_or(mp_int *a, mp_int *b, mp_int *c);
315 int mp_or(const mp_int *a, const mp_int *b, mp_int *c);
302316
303317 /* c = a AND b */
304 int mp_and(mp_int *a, mp_int *b, mp_int *c);
318 int mp_and(const mp_int *a, const mp_int *b, mp_int *c);
305319
306320 /* ---> Basic arithmetic <--- */
307321
308322 /* b = -a */
309 int mp_neg(mp_int *a, mp_int *b);
323 int mp_neg(const mp_int *a, mp_int *b);
310324
311325 /* b = |a| */
312 int mp_abs(mp_int *a, mp_int *b);
326 int mp_abs(const mp_int *a, mp_int *b);
313327
314328 /* compare a to b */
315 int mp_cmp(mp_int *a, mp_int *b);
329 int mp_cmp(const mp_int *a, const mp_int *b);
316330
317331 /* compare |a| to |b| */
318 int mp_cmp_mag(mp_int *a, mp_int *b);
332 int mp_cmp_mag(const mp_int *a, const mp_int *b);
319333
320334 /* c = a + b */
321 int mp_add(mp_int *a, mp_int *b, mp_int *c);
335 int mp_add(const mp_int *a, const mp_int *b, mp_int *c);
322336
323337 /* c = a - b */
324 int mp_sub(mp_int *a, mp_int *b, mp_int *c);
338 int mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
325339
326340 /* c = a * b */
327 int mp_mul(mp_int *a, mp_int *b, mp_int *c);
341 int mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
328342
329343 /* b = a*a */
330 int mp_sqr(mp_int *a, mp_int *b);
344 int mp_sqr(const mp_int *a, mp_int *b);
331345
332346 /* a/b => cb + d == a */
333 int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
347 int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d);
334348
335349 /* c = a mod b, 0 <= c < b */
336 int mp_mod(mp_int *a, mp_int *b, mp_int *c);
350 int mp_mod(const mp_int *a, const mp_int *b, mp_int *c);
337351
338352 /* ---> single digit functions <--- */
339353
340354 /* compare against a single digit */
341 int mp_cmp_d(mp_int *a, mp_digit b);
355 int mp_cmp_d(const mp_int *a, mp_digit b);
342356
343357 /* c = a + b */
344 int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
358 int mp_add_d(const mp_int *a, mp_digit b, mp_int *c);
345359
346360 /* c = a - b */
347 int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
361 int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c);
348362
349363 /* c = a * b */
350 int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
364 int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c);
351365
352366 /* a/b => cb + d == a */
353 int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
367 int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
354368
355369 /* a/3 => 3c + d == a */
356 int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
370 int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d);
357371
358372 /* c = a**b */
359 int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
360 int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast);
373 int mp_expt_d(const mp_int *a, mp_digit b, mp_int *c);
374 int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast);
361375
362376 /* c = a mod b, 0 <= c < b */
363 int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
377 int mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c);
364378
365379 /* ---> number theory <--- */
366380
367381 /* d = a + b (mod c) */
368 int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
382 int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
369383
370384 /* d = a - b (mod c) */
371 int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
385 int mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
372386
373387 /* d = a * b (mod c) */
374 int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
388 int mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
375389
376390 /* c = a * a (mod b) */
377 int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
391 int mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c);
378392
379393 /* c = 1/a (mod b) */
380 int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
394 int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c);
381395
382396 /* c = (a, b) */
383 int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
397 int mp_gcd(const mp_int *a, const mp_int *b, mp_int *c);
384398
385399 /* produces value such that U1*a + U2*b = U3 */
386 int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
400 int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
387401
388402 /* c = [a, b] or (a*b)/(a, b) */
389 int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
403 int mp_lcm(const mp_int *a, const mp_int *b, mp_int *c);
390404
391405 /* finds one of the b'th root of a, such that |c|**b <= |a|
392406 *
393407 * returns error if a < 0 and b is even
394408 */
395 int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
396 int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast);
409 int mp_n_root(const mp_int *a, mp_digit b, mp_int *c);
410 int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast);
397411
398412 /* special sqrt algo */
399 int mp_sqrt(mp_int *arg, mp_int *ret);
413 int mp_sqrt(const mp_int *arg, mp_int *ret);
400414
401415 /* special sqrt (mod prime) */
402 int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret);
416 int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret);
403417
404418 /* is number a square? */
405 int mp_is_square(mp_int *arg, int *ret);
419 int mp_is_square(const mp_int *arg, int *ret);
406420
407421 /* computes the jacobi c = (a | n) (or Legendre if b is prime) */
408 int mp_jacobi(mp_int *a, mp_int *n, int *c);
422 int mp_jacobi(const mp_int *a, const mp_int *n, int *c);
409423
410424 /* used to setup the Barrett reduction for a given modulus b */
411 int mp_reduce_setup(mp_int *a, mp_int *b);
425 int mp_reduce_setup(mp_int *a, const mp_int *b);
412426
413427 /* Barrett Reduction, computes a (mod b) with a precomputed value c
414428 *
415 * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
416 * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
417 */
418 int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
429 * Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely
430 * compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code].
431 */
432 int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
419433
420434 /* setups the montgomery reduction */
421 int mp_montgomery_setup(mp_int *a, mp_digit *mp);
435 int mp_montgomery_setup(const mp_int *n, mp_digit *rho);
422436
423437 /* computes a = B**n mod b without division or multiplication useful for
424438 * normalizing numbers in a Montgomery system.
425439 */
426 int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
440 int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b);
427441
428442 /* computes x/R == x (mod N) via Montgomery Reduction */
429 int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
443 int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho);
430444
431445 /* returns 1 if a is a valid DR modulus */
432 int mp_dr_is_modulus(mp_int *a);
446 int mp_dr_is_modulus(const mp_int *a);
433447
434448 /* sets the value of "d" required for mp_dr_reduce */
435 void mp_dr_setup(mp_int *a, mp_digit *d);
436
437 /* reduces a modulo b using the Diminished Radix method */
438 int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
449 void mp_dr_setup(const mp_int *a, mp_digit *d);
450
451 /* reduces a modulo n using the Diminished Radix method */
452 int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k);
439453
440454 /* returns true if a can be reduced with mp_reduce_2k */
441 int mp_reduce_is_2k(mp_int *a);
455 int mp_reduce_is_2k(const mp_int *a);
442456
443457 /* determines k value for 2k reduction */
444 int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
458 int mp_reduce_2k_setup(const mp_int *a, mp_digit *d);
445459
446460 /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
447 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
461 int mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d);
448462
449463 /* returns true if a can be reduced with mp_reduce_2k_l */
450 int mp_reduce_is_2k_l(mp_int *a);
464 int mp_reduce_is_2k_l(const mp_int *a);
451465
452466 /* determines k value for 2k reduction */
453 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
467 int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d);
454468
455469 /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
456 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
457
458 /* d = a**b (mod c) */
459 int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
470 int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d);
471
472 /* Y = G**X (mod P) */
473 int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y);
460474
461475 /* ---> Primes <--- */
462476
463477 /* number of primes */
464478 #ifdef MP_8BIT
465 #define PRIME_SIZE 31
479 # define PRIME_SIZE 31
466480 #else
467 #define PRIME_SIZE 256
481 # define PRIME_SIZE 256
468482 #endif
469483
470484 /* table of first PRIME_SIZE primes */
471485 extern const mp_digit ltm_prime_tab[PRIME_SIZE];
472486
473487 /* result=1 if a is divisible by one of the first PRIME_SIZE primes */
474 int mp_prime_is_divisible(mp_int *a, int *result);
488 int mp_prime_is_divisible(const mp_int *a, int *result);
475489
476490 /* performs one Fermat test of "a" using base "b".
477491 * Sets result to 0 if composite or 1 if probable prime
478492 */
479 int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
493 int mp_prime_fermat(const mp_int *a, const mp_int *b, int *result);
480494
481495 /* performs one Miller-Rabin test of "a" using base "b".
482496 * Sets result to 0 if composite or 1 if probable prime
483497 */
484 int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
498 int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result);
485499
486500 /* This gives [for a given bit size] the number of trials required
487501 * such that Miller-Rabin gives a prob of failure lower than 2^-96
495509 *
496510 * Sets result to 1 if probably prime, 0 otherwise
497511 */
498 int mp_prime_is_prime(mp_int *a, int t, int *result);
512 int mp_prime_is_prime(const mp_int *a, int t, int *result);
499513
500514 /* finds the next prime after the number "a" using "t" trials
501515 * of Miller-Rabin.
531545 int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
532546
533547 /* ---> radix conversion <--- */
534 int mp_count_bits(mp_int *a);
535
536 int mp_unsigned_bin_size(mp_int *a);
548 int mp_count_bits(const mp_int *a);
549
550 int mp_unsigned_bin_size(const mp_int *a);
537551 int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
538 int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
539 int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
540
541 int mp_signed_bin_size(mp_int *a);
552 int mp_to_unsigned_bin(const mp_int *a, unsigned char *b);
553 int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen);
554
555 int mp_signed_bin_size(const mp_int *a);
542556 int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
543 int mp_to_signed_bin(mp_int *a, unsigned char *b);
544 int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
557 int mp_to_signed_bin(const mp_int *a, unsigned char *b);
558 int mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen);
545559
546560 int mp_read_radix(mp_int *a, const char *str, int radix);
547 int mp_toradix(mp_int *a, char *str, int radix);
548 int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
549 int mp_radix_size(mp_int *a, int radix, int *size);
561 int mp_toradix(const mp_int *a, char *str, int radix);
562 int mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen);
563 int mp_radix_size(const mp_int *a, int radix, int *size);
550564
551565 #ifndef LTM_NO_FILE
552566 int mp_fread(mp_int *a, int radix, FILE *stream);
553 int mp_fwrite(mp_int *a, int radix, FILE *stream);
567 int mp_fwrite(const mp_int *a, int radix, FILE *stream);
554568 #endif
555569
556570 #define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
566580 #define mp_tohex(M, S) mp_toradix((M), (S), 16)
567581
568582 #ifdef __cplusplus
569 }
570 #endif
571
572 #endif
573
574
575 /* $Source$ */
576 /* $Revision$ */
577 /* $Date$ */
583 }
584 #endif
585
586 #endif
587
588
589 /* ref: $Format:%D$ */
590 /* git commit: $Format:%H$ */
591 /* commit time: $Format:%ai$ */
00 #if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
11 #if defined(LTM2)
2 #define LTM3
2 # define LTM3
33 #endif
44 #if defined(LTM1)
5 #define LTM2
5 # define LTM2
66 #endif
77 #define LTM1
88
99 #if defined(LTM_ALL)
10 #define BN_ERROR_C
11 #define BN_FAST_MP_INVMOD_C
12 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
13 #define BN_FAST_S_MP_MUL_DIGS_C
14 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
15 #define BN_FAST_S_MP_SQR_C
16 #define BN_MP_2EXPT_C
17 #define BN_MP_ABS_C
18 #define BN_MP_ADD_C
19 #define BN_MP_ADD_D_C
20 #define BN_MP_ADDMOD_C
21 #define BN_MP_AND_C
22 #define BN_MP_CLAMP_C
23 #define BN_MP_CLEAR_C
24 #define BN_MP_CLEAR_MULTI_C
25 #define BN_MP_CMP_C
26 #define BN_MP_CMP_D_C
27 #define BN_MP_CMP_MAG_C
28 #define BN_MP_CNT_LSB_C
29 #define BN_MP_COPY_C
30 #define BN_MP_COUNT_BITS_C
31 #define BN_MP_DIV_C
32 #define BN_MP_DIV_2_C
33 #define BN_MP_DIV_2D_C
34 #define BN_MP_DIV_3_C
35 #define BN_MP_DIV_D_C
36 #define BN_MP_DR_IS_MODULUS_C
37 #define BN_MP_DR_REDUCE_C
38 #define BN_MP_DR_SETUP_C
39 #define BN_MP_EXCH_C
40 #define BN_MP_EXPORT_C
41 #define BN_MP_EXPT_D_C
42 #define BN_MP_EXPT_D_EX_C
43 #define BN_MP_EXPTMOD_C
44 #define BN_MP_EXPTMOD_FAST_C
45 #define BN_MP_EXTEUCLID_C
46 #define BN_MP_FREAD_C
47 #define BN_MP_FWRITE_C
48 #define BN_MP_GCD_C
49 #define BN_MP_GET_INT_C
50 #define BN_MP_GET_LONG_C
51 #define BN_MP_GET_LONG_LONG_C
52 #define BN_MP_GROW_C
53 #define BN_MP_IMPORT_C
54 #define BN_MP_INIT_C
55 #define BN_MP_INIT_COPY_C
56 #define BN_MP_INIT_MULTI_C
57 #define BN_MP_INIT_SET_C
58 #define BN_MP_INIT_SET_INT_C
59 #define BN_MP_INIT_SIZE_C
60 #define BN_MP_INVMOD_C
61 #define BN_MP_INVMOD_SLOW_C
62 #define BN_MP_IS_SQUARE_C
63 #define BN_MP_JACOBI_C
64 #define BN_MP_KARATSUBA_MUL_C
65 #define BN_MP_KARATSUBA_SQR_C
66 #define BN_MP_LCM_C
67 #define BN_MP_LSHD_C
68 #define BN_MP_MOD_C
69 #define BN_MP_MOD_2D_C
70 #define BN_MP_MOD_D_C
71 #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
72 #define BN_MP_MONTGOMERY_REDUCE_C
73 #define BN_MP_MONTGOMERY_SETUP_C
74 #define BN_MP_MUL_C
75 #define BN_MP_MUL_2_C
76 #define BN_MP_MUL_2D_C
77 #define BN_MP_MUL_D_C
78 #define BN_MP_MULMOD_C
79 #define BN_MP_N_ROOT_C
80 #define BN_MP_N_ROOT_EX_C
81 #define BN_MP_NEG_C
82 #define BN_MP_OR_C
83 #define BN_MP_PRIME_FERMAT_C
84 #define BN_MP_PRIME_IS_DIVISIBLE_C
85 #define BN_MP_PRIME_IS_PRIME_C
86 #define BN_MP_PRIME_MILLER_RABIN_C
87 #define BN_MP_PRIME_NEXT_PRIME_C
88 #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
89 #define BN_MP_PRIME_RANDOM_EX_C
90 #define BN_MP_RADIX_SIZE_C
91 #define BN_MP_RADIX_SMAP_C
92 #define BN_MP_RAND_C
93 #define BN_MP_READ_RADIX_C
94 #define BN_MP_READ_SIGNED_BIN_C
95 #define BN_MP_READ_UNSIGNED_BIN_C
96 #define BN_MP_REDUCE_C
97 #define BN_MP_REDUCE_2K_C
98 #define BN_MP_REDUCE_2K_L_C
99 #define BN_MP_REDUCE_2K_SETUP_C
100 #define BN_MP_REDUCE_2K_SETUP_L_C
101 #define BN_MP_REDUCE_IS_2K_C
102 #define BN_MP_REDUCE_IS_2K_L_C
103 #define BN_MP_REDUCE_SETUP_C
104 #define BN_MP_RSHD_C
105 #define BN_MP_SET_C
106 #define BN_MP_SET_INT_C
107 #define BN_MP_SET_LONG_C
108 #define BN_MP_SET_LONG_LONG_C
109 #define BN_MP_SHRINK_C
110 #define BN_MP_SIGNED_BIN_SIZE_C
111 #define BN_MP_SQR_C
112 #define BN_MP_SQRMOD_C
113 #define BN_MP_SQRT_C
114 #define BN_MP_SQRTMOD_PRIME_C
115 #define BN_MP_SUB_C
116 #define BN_MP_SUB_D_C
117 #define BN_MP_SUBMOD_C
118 #define BN_MP_TO_SIGNED_BIN_C
119 #define BN_MP_TO_SIGNED_BIN_N_C
120 #define BN_MP_TO_UNSIGNED_BIN_C
121 #define BN_MP_TO_UNSIGNED_BIN_N_C
122 #define BN_MP_TOOM_MUL_C
123 #define BN_MP_TOOM_SQR_C
124 #define BN_MP_TORADIX_C
125 #define BN_MP_TORADIX_N_C
126 #define BN_MP_UNSIGNED_BIN_SIZE_C
127 #define BN_MP_XOR_C
128 #define BN_MP_ZERO_C
129 #define BN_PRIME_TAB_C
130 #define BN_REVERSE_C
131 #define BN_S_MP_ADD_C
132 #define BN_S_MP_EXPTMOD_C
133 #define BN_S_MP_MUL_DIGS_C
134 #define BN_S_MP_MUL_HIGH_DIGS_C
135 #define BN_S_MP_SQR_C
136 #define BN_S_MP_SUB_C
137 #define BNCORE_C
10 # define BN_ERROR_C
11 # define BN_FAST_MP_INVMOD_C
12 # define BN_FAST_MP_MONTGOMERY_REDUCE_C
13 # define BN_FAST_S_MP_MUL_DIGS_C
14 # define BN_FAST_S_MP_MUL_HIGH_DIGS_C
15 # define BN_FAST_S_MP_SQR_C
16 # define BN_MP_2EXPT_C
17 # define BN_MP_ABS_C
18 # define BN_MP_ADD_C
19 # define BN_MP_ADD_D_C
20 # define BN_MP_ADDMOD_C
21 # define BN_MP_AND_C
22 # define BN_MP_CLAMP_C
23 # define BN_MP_CLEAR_C
24 # define BN_MP_CLEAR_MULTI_C
25 # define BN_MP_CMP_C
26 # define BN_MP_CMP_D_C
27 # define BN_MP_CMP_MAG_C
28 # define BN_MP_CNT_LSB_C
29 # define BN_MP_COPY_C
30 # define BN_MP_COUNT_BITS_C
31 # define BN_MP_DIV_C
32 # define BN_MP_DIV_2_C
33 # define BN_MP_DIV_2D_C
34 # define BN_MP_DIV_3_C
35 # define BN_MP_DIV_D_C
36 # define BN_MP_DR_IS_MODULUS_C
37 # define BN_MP_DR_REDUCE_C
38 # define BN_MP_DR_SETUP_C
39 # define BN_MP_EXCH_C
40 # define BN_MP_EXPORT_C
41 # define BN_MP_EXPT_D_C
42 # define BN_MP_EXPT_D_EX_C
43 # define BN_MP_EXPTMOD_C
44 # define BN_MP_EXPTMOD_FAST_C
45 # define BN_MP_EXTEUCLID_C
46 # define BN_MP_FREAD_C
47 # define BN_MP_FWRITE_C
48 # define BN_MP_GCD_C
49 # define BN_MP_GET_INT_C
50 # define BN_MP_GET_LONG_C
51 # define BN_MP_GET_LONG_LONG_C
52 # define BN_MP_GROW_C
53 # define BN_MP_IMPORT_C
54 # define BN_MP_INIT_C
55 # define BN_MP_INIT_COPY_C
56 # define BN_MP_INIT_MULTI_C
57 # define BN_MP_INIT_SET_C
58 # define BN_MP_INIT_SET_INT_C
59 # define BN_MP_INIT_SIZE_C
60 # define BN_MP_INVMOD_C
61 # define BN_MP_INVMOD_SLOW_C
62 # define BN_MP_IS_SQUARE_C
63 # define BN_MP_JACOBI_C
64 # define BN_MP_KARATSUBA_MUL_C
65 # define BN_MP_KARATSUBA_SQR_C
66 # define BN_MP_LCM_C
67 # define BN_MP_LSHD_C
68 # define BN_MP_MOD_C
69 # define BN_MP_MOD_2D_C
70 # define BN_MP_MOD_D_C
71 # define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
72 # define BN_MP_MONTGOMERY_REDUCE_C
73 # define BN_MP_MONTGOMERY_SETUP_C
74 # define BN_MP_MUL_C
75 # define BN_MP_MUL_2_C
76 # define BN_MP_MUL_2D_C
77 # define BN_MP_MUL_D_C
78 # define BN_MP_MULMOD_C
79 # define BN_MP_N_ROOT_C
80 # define BN_MP_N_ROOT_EX_C
81 # define BN_MP_NEG_C
82 # define BN_MP_OR_C
83 # define BN_MP_PRIME_FERMAT_C
84 # define BN_MP_PRIME_IS_DIVISIBLE_C
85 # define BN_MP_PRIME_IS_PRIME_C
86 # define BN_MP_PRIME_MILLER_RABIN_C
87 # define BN_MP_PRIME_NEXT_PRIME_C
88 # define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
89 # define BN_MP_PRIME_RANDOM_EX_C
90 # define BN_MP_RADIX_SIZE_C
91 # define BN_MP_RADIX_SMAP_C
92 # define BN_MP_RAND_C
93 # define BN_MP_READ_RADIX_C
94 # define BN_MP_READ_SIGNED_BIN_C
95 # define BN_MP_READ_UNSIGNED_BIN_C
96 # define BN_MP_REDUCE_C
97 # define BN_MP_REDUCE_2K_C
98 # define BN_MP_REDUCE_2K_L_C
99 # define BN_MP_REDUCE_2K_SETUP_C
100 # define BN_MP_REDUCE_2K_SETUP_L_C
101 # define BN_MP_REDUCE_IS_2K_C
102 # define BN_MP_REDUCE_IS_2K_L_C
103 # define BN_MP_REDUCE_SETUP_C
104 # define BN_MP_RSHD_C
105 # define BN_MP_SET_C
106 # define BN_MP_SET_INT_C
107 # define BN_MP_SET_LONG_C
108 # define BN_MP_SET_LONG_LONG_C
109 # define BN_MP_SHRINK_C
110 # define BN_MP_SIGNED_BIN_SIZE_C
111 # define BN_MP_SQR_C
112 # define BN_MP_SQRMOD_C
113 # define BN_MP_SQRT_C
114 # define BN_MP_SQRTMOD_PRIME_C
115 # define BN_MP_SUB_C
116 # define BN_MP_SUB_D_C
117 # define BN_MP_SUBMOD_C
118 # define BN_MP_TO_SIGNED_BIN_C
119 # define BN_MP_TO_SIGNED_BIN_N_C
120 # define BN_MP_TO_UNSIGNED_BIN_C
121 # define BN_MP_TO_UNSIGNED_BIN_N_C
122 # define BN_MP_TOOM_MUL_C
123 # define BN_MP_TOOM_SQR_C
124 # define BN_MP_TORADIX_C
125 # define BN_MP_TORADIX_N_C
126 # define BN_MP_UNSIGNED_BIN_SIZE_C
127 # define BN_MP_XOR_C
128 # define BN_MP_ZERO_C
129 # define BN_PRIME_TAB_C
130 # define BN_REVERSE_C
131 # define BN_S_MP_ADD_C
132 # define BN_S_MP_EXPTMOD_C
133 # define BN_S_MP_MUL_DIGS_C
134 # define BN_S_MP_MUL_HIGH_DIGS_C
135 # define BN_S_MP_SQR_C
136 # define BN_S_MP_SUB_C
137 # define BNCORE_C
138138 #endif
139139
140140 #if defined(BN_ERROR_C)
141 #define BN_MP_ERROR_TO_STRING_C
141 # define BN_MP_ERROR_TO_STRING_C
142142 #endif
143143
144144 #if defined(BN_FAST_MP_INVMOD_C)
145 #define BN_MP_ISEVEN_C
146 #define BN_MP_INIT_MULTI_C
147 #define BN_MP_COPY_C
148 #define BN_MP_MOD_C
149 #define BN_MP_SET_C
150 #define BN_MP_DIV_2_C
151 #define BN_MP_ISODD_C
152 #define BN_MP_SUB_C
153 #define BN_MP_CMP_C
154 #define BN_MP_ISZERO_C
155 #define BN_MP_CMP_D_C
156 #define BN_MP_ADD_C
157 #define BN_MP_EXCH_C
158 #define BN_MP_CLEAR_MULTI_C
145 # define BN_MP_ISEVEN_C
146 # define BN_MP_INIT_MULTI_C
147 # define BN_MP_COPY_C
148 # define BN_MP_MOD_C
149 # define BN_MP_SET_C
150 # define BN_MP_DIV_2_C
151 # define BN_MP_ISODD_C
152 # define BN_MP_SUB_C
153 # define BN_MP_CMP_C
154 # define BN_MP_ISZERO_C
155 # define BN_MP_CMP_D_C
156 # define BN_MP_ADD_C
157 # define BN_MP_EXCH_C
158 # define BN_MP_CLEAR_MULTI_C
159159 #endif
160160
161161 #if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
162 #define BN_MP_GROW_C
163 #define BN_MP_RSHD_C
164 #define BN_MP_CLAMP_C
165 #define BN_MP_CMP_MAG_C
166 #define BN_S_MP_SUB_C
162 # define BN_MP_GROW_C
163 # define BN_MP_RSHD_C
164 # define BN_MP_CLAMP_C
165 # define BN_MP_CMP_MAG_C
166 # define BN_S_MP_SUB_C
167167 #endif
168168
169169 #if defined(BN_FAST_S_MP_MUL_DIGS_C)
170 #define BN_MP_GROW_C
171 #define BN_MP_CLAMP_C
170 # define BN_MP_GROW_C
171 # define BN_MP_CLAMP_C
172172 #endif
173173
174174 #if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
175 #define BN_MP_GROW_C
176 #define BN_MP_CLAMP_C
175 # define BN_MP_GROW_C
176 # define BN_MP_CLAMP_C
177177 #endif
178178
179179 #if defined(BN_FAST_S_MP_SQR_C)
180 #define BN_MP_GROW_C
181 #define BN_MP_CLAMP_C
180 # define BN_MP_GROW_C
181 # define BN_MP_CLAMP_C
182182 #endif
183183
184184 #if defined(BN_MP_2EXPT_C)
185 #define BN_MP_ZERO_C
186 #define BN_MP_GROW_C
185 # define BN_MP_ZERO_C
186 # define BN_MP_GROW_C
187187 #endif
188188
189189 #if defined(BN_MP_ABS_C)
190 #define BN_MP_COPY_C
190 # define BN_MP_COPY_C
191191 #endif
192192
193193 #if defined(BN_MP_ADD_C)
194 #define BN_S_MP_ADD_C
195 #define BN_MP_CMP_MAG_C
196 #define BN_S_MP_SUB_C
194 # define BN_S_MP_ADD_C
195 # define BN_MP_CMP_MAG_C
196 # define BN_S_MP_SUB_C
197197 #endif
198198
199199 #if defined(BN_MP_ADD_D_C)
200 #define BN_MP_GROW_C
201 #define BN_MP_SUB_D_C
202 #define BN_MP_CLAMP_C
200 # define BN_MP_GROW_C
201 # define BN_MP_SUB_D_C
202 # define BN_MP_CLAMP_C
203203 #endif
204204
205205 #if defined(BN_MP_ADDMOD_C)
206 #define BN_MP_INIT_C
207 #define BN_MP_ADD_C
208 #define BN_MP_CLEAR_C
209 #define BN_MP_MOD_C
206 # define BN_MP_INIT_C
207 # define BN_MP_ADD_C
208 # define BN_MP_CLEAR_C
209 # define BN_MP_MOD_C
210210 #endif
211211
212212 #if defined(BN_MP_AND_C)
213 #define BN_MP_INIT_COPY_C
214 #define BN_MP_CLAMP_C
215 #define BN_MP_EXCH_C
216 #define BN_MP_CLEAR_C
213 # define BN_MP_INIT_COPY_C
214 # define BN_MP_CLAMP_C
215 # define BN_MP_EXCH_C
216 # define BN_MP_CLEAR_C
217217 #endif
218218
219219 #if defined(BN_MP_CLAMP_C)
223223 #endif
224224
225225 #if defined(BN_MP_CLEAR_MULTI_C)
226 #define BN_MP_CLEAR_C
226 # define BN_MP_CLEAR_C
227227 #endif
228228
229229 #if defined(BN_MP_CMP_C)
230 #define BN_MP_CMP_MAG_C
230 # define BN_MP_CMP_MAG_C
231231 #endif
232232
233233 #if defined(BN_MP_CMP_D_C)
237237 #endif
238238
239239 #if defined(BN_MP_CNT_LSB_C)
240 #define BN_MP_ISZERO_C
240 # define BN_MP_ISZERO_C
241241 #endif
242242
243243 #if defined(BN_MP_COPY_C)
244 #define BN_MP_GROW_C
244 # define BN_MP_GROW_C
245245 #endif
246246
247247 #if defined(BN_MP_COUNT_BITS_C)
248248 #endif
249249
250250 #if defined(BN_MP_DIV_C)
251 #define BN_MP_ISZERO_C
252 #define BN_MP_CMP_MAG_C
253 #define BN_MP_COPY_C
254 #define BN_MP_ZERO_C
255 #define BN_MP_INIT_MULTI_C
256 #define BN_MP_SET_C
257 #define BN_MP_COUNT_BITS_C
258 #define BN_MP_ABS_C
259 #define BN_MP_MUL_2D_C
260 #define BN_MP_CMP_C
261 #define BN_MP_SUB_C
262 #define BN_MP_ADD_C
263 #define BN_MP_DIV_2D_C
264 #define BN_MP_EXCH_C
265 #define BN_MP_CLEAR_MULTI_C
266 #define BN_MP_INIT_SIZE_C
267 #define BN_MP_INIT_C
268 #define BN_MP_INIT_COPY_C
269 #define BN_MP_LSHD_C
270 #define BN_MP_RSHD_C
271 #define BN_MP_MUL_D_C
272 #define BN_MP_CLAMP_C
273 #define BN_MP_CLEAR_C
251 # define BN_MP_ISZERO_C
252 # define BN_MP_CMP_MAG_C
253 # define BN_MP_COPY_C
254 # define BN_MP_ZERO_C
255 # define BN_MP_INIT_MULTI_C
256 # define BN_MP_SET_C
257 # define BN_MP_COUNT_BITS_C
258 # define BN_MP_ABS_C
259 # define BN_MP_MUL_2D_C
260 # define BN_MP_CMP_C
261 # define BN_MP_SUB_C
262 # define BN_MP_ADD_C
263 # define BN_MP_DIV_2D_C
264 # define BN_MP_EXCH_C
265 # define BN_MP_CLEAR_MULTI_C
266 # define BN_MP_INIT_SIZE_C
267 # define BN_MP_INIT_C
268 # define BN_MP_INIT_COPY_C
269 # define BN_MP_LSHD_C
270 # define BN_MP_RSHD_C
271 # define BN_MP_MUL_D_C
272 # define BN_MP_CLAMP_C
273 # define BN_MP_CLEAR_C
274274 #endif
275275
276276 #if defined(BN_MP_DIV_2_C)
277 #define BN_MP_GROW_C
278 #define BN_MP_CLAMP_C
277 # define BN_MP_GROW_C
278 # define BN_MP_CLAMP_C
279279 #endif
280280
281281 #if defined(BN_MP_DIV_2D_C)
282 #define BN_MP_COPY_C
283 #define BN_MP_ZERO_C
284 #define BN_MP_INIT_C
285 #define BN_MP_MOD_2D_C
286 #define BN_MP_CLEAR_C
287 #define BN_MP_RSHD_C
288 #define BN_MP_CLAMP_C
289 #define BN_MP_EXCH_C
282 # define BN_MP_COPY_C
283 # define BN_MP_ZERO_C
284 # define BN_MP_MOD_2D_C
285 # define BN_MP_RSHD_C
286 # define BN_MP_CLAMP_C
290287 #endif
291288
292289 #if defined(BN_MP_DIV_3_C)
293 #define BN_MP_INIT_SIZE_C
294 #define BN_MP_CLAMP_C
295 #define BN_MP_EXCH_C
296 #define BN_MP_CLEAR_C
290 # define BN_MP_INIT_SIZE_C
291 # define BN_MP_CLAMP_C
292 # define BN_MP_EXCH_C
293 # define BN_MP_CLEAR_C
297294 #endif
298295
299296 #if defined(BN_MP_DIV_D_C)
300 #define BN_MP_ISZERO_C
301 #define BN_MP_COPY_C
302 #define BN_MP_DIV_2D_C
303 #define BN_MP_DIV_3_C
304 #define BN_MP_INIT_SIZE_C
305 #define BN_MP_CLAMP_C
306 #define BN_MP_EXCH_C
307 #define BN_MP_CLEAR_C
297 # define BN_MP_ISZERO_C
298 # define BN_MP_COPY_C
299 # define BN_MP_DIV_2D_C
300 # define BN_MP_DIV_3_C
301 # define BN_MP_INIT_SIZE_C
302 # define BN_MP_CLAMP_C
303 # define BN_MP_EXCH_C
304 # define BN_MP_CLEAR_C
308305 #endif
309306
310307 #if defined(BN_MP_DR_IS_MODULUS_C)
311308 #endif
312309
313310 #if defined(BN_MP_DR_REDUCE_C)
314 #define BN_MP_GROW_C
315 #define BN_MP_CLAMP_C
316 #define BN_MP_CMP_MAG_C
317 #define BN_S_MP_SUB_C
311 # define BN_MP_GROW_C
312 # define BN_MP_CLAMP_C
313 # define BN_MP_CMP_MAG_C
314 # define BN_S_MP_SUB_C
318315 #endif
319316
320317 #if defined(BN_MP_DR_SETUP_C)
324321 #endif
325322
326323 #if defined(BN_MP_EXPORT_C)
327 #define BN_MP_INIT_COPY_C
328 #define BN_MP_COUNT_BITS_C
329 #define BN_MP_DIV_2D_C
330 #define BN_MP_CLEAR_C
324 # define BN_MP_INIT_COPY_C
325 # define BN_MP_COUNT_BITS_C
326 # define BN_MP_DIV_2D_C
327 # define BN_MP_CLEAR_C
331328 #endif
332329
333330 #if defined(BN_MP_EXPT_D_C)
334 #define BN_MP_EXPT_D_EX_C
331 # define BN_MP_EXPT_D_EX_C
335332 #endif
336333
337334 #if defined(BN_MP_EXPT_D_EX_C)
338 #define BN_MP_INIT_COPY_C
339 #define BN_MP_SET_C
340 #define BN_MP_MUL_C
341 #define BN_MP_CLEAR_C
342 #define BN_MP_SQR_C
335 # define BN_MP_INIT_COPY_C
336 # define BN_MP_SET_C
337 # define BN_MP_MUL_C
338 # define BN_MP_CLEAR_C
339 # define BN_MP_SQR_C
343340 #endif
344341
345342 #if defined(BN_MP_EXPTMOD_C)
346 #define BN_MP_INIT_C
347 #define BN_MP_INVMOD_C
348 #define BN_MP_CLEAR_C
349 #define BN_MP_ABS_C
350 #define BN_MP_CLEAR_MULTI_C
351 #define BN_MP_REDUCE_IS_2K_L_C
352 #define BN_S_MP_EXPTMOD_C
353 #define BN_MP_DR_IS_MODULUS_C
354 #define BN_MP_REDUCE_IS_2K_C
355 #define BN_MP_ISODD_C
356 #define BN_MP_EXPTMOD_FAST_C
343 # define BN_MP_INIT_C
344 # define BN_MP_INVMOD_C
345 # define BN_MP_CLEAR_C
346 # define BN_MP_ABS_C
347 # define BN_MP_CLEAR_MULTI_C
348 # define BN_MP_REDUCE_IS_2K_L_C
349 # define BN_S_MP_EXPTMOD_C
350 # define BN_MP_DR_IS_MODULUS_C
351 # define BN_MP_REDUCE_IS_2K_C
352 # define BN_MP_ISODD_C
353 # define BN_MP_EXPTMOD_FAST_C
357354 #endif
358355
359356 #if defined(BN_MP_EXPTMOD_FAST_C)
360 #define BN_MP_COUNT_BITS_C
361 #define BN_MP_INIT_C
362 #define BN_MP_CLEAR_C
363 #define BN_MP_MONTGOMERY_SETUP_C
364 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
365 #define BN_MP_MONTGOMERY_REDUCE_C
366 #define BN_MP_DR_SETUP_C
367 #define BN_MP_DR_REDUCE_C
368 #define BN_MP_REDUCE_2K_SETUP_C
369 #define BN_MP_REDUCE_2K_C
370 #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
371 #define BN_MP_MULMOD_C
372 #define BN_MP_SET_C
373 #define BN_MP_MOD_C
374 #define BN_MP_COPY_C
375 #define BN_MP_SQR_C
376 #define BN_MP_MUL_C
377 #define BN_MP_EXCH_C
357 # define BN_MP_COUNT_BITS_C
358 # define BN_MP_INIT_SIZE_C
359 # define BN_MP_CLEAR_C
360 # define BN_MP_MONTGOMERY_SETUP_C
361 # define BN_FAST_MP_MONTGOMERY_REDUCE_C
362 # define BN_MP_MONTGOMERY_REDUCE_C
363 # define BN_MP_DR_SETUP_C
364 # define BN_MP_DR_REDUCE_C
365 # define BN_MP_REDUCE_2K_SETUP_C
366 # define BN_MP_REDUCE_2K_C
367 # define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
368 # define BN_MP_MULMOD_C
369 # define BN_MP_SET_C
370 # define BN_MP_MOD_C
371 # define BN_MP_COPY_C
372 # define BN_MP_SQR_C
373 # define BN_MP_MUL_C
374 # define BN_MP_EXCH_C
378375 #endif
379376
380377 #if defined(BN_MP_EXTEUCLID_C)
381 #define BN_MP_INIT_MULTI_C
382 #define BN_MP_SET_C
383 #define BN_MP_COPY_C
384 #define BN_MP_ISZERO_C
385 #define BN_MP_DIV_C
386 #define BN_MP_MUL_C
387 #define BN_MP_SUB_C
388 #define BN_MP_NEG_C
389 #define BN_MP_EXCH_C
390 #define BN_MP_CLEAR_MULTI_C
378 # define BN_MP_INIT_MULTI_C
379 # define BN_MP_SET_C
380 # define BN_MP_COPY_C
381 # define BN_MP_ISZERO_C
382 # define BN_MP_DIV_C
383 # define BN_MP_MUL_C
384 # define BN_MP_SUB_C
385 # define BN_MP_NEG_C
386 # define BN_MP_EXCH_C
387 # define BN_MP_CLEAR_MULTI_C
391388 #endif
392389
393390 #if defined(BN_MP_FREAD_C)
394 #define BN_MP_ZERO_C
395 #define BN_MP_S_RMAP_C
396 #define BN_MP_MUL_D_C
397 #define BN_MP_ADD_D_C
398 #define BN_MP_CMP_D_C
391 # define BN_MP_ZERO_C
392 # define BN_MP_S_RMAP_C
393 # define BN_MP_MUL_D_C
394 # define BN_MP_ADD_D_C
395 # define BN_MP_CMP_D_C
399396 #endif
400397
401398 #if defined(BN_MP_FWRITE_C)
402 #define BN_MP_RADIX_SIZE_C
403 #define BN_MP_TORADIX_C
399 # define BN_MP_RADIX_SIZE_C
400 # define BN_MP_TORADIX_C
404401 #endif
405402
406403 #if defined(BN_MP_GCD_C)
407 #define BN_MP_ISZERO_C
408 #define BN_MP_ABS_C
409 #define BN_MP_INIT_COPY_C
410 #define BN_MP_CNT_LSB_C
411 #define BN_MP_DIV_2D_C
412 #define BN_MP_CMP_MAG_C
413 #define BN_MP_EXCH_C
414 #define BN_S_MP_SUB_C
415 #define BN_MP_MUL_2D_C
416 #define BN_MP_CLEAR_C
404 # define BN_MP_ISZERO_C
405 # define BN_MP_ABS_C
406 # define BN_MP_INIT_COPY_C
407 # define BN_MP_CNT_LSB_C
408 # define BN_MP_DIV_2D_C
409 # define BN_MP_CMP_MAG_C
410 # define BN_MP_EXCH_C
411 # define BN_S_MP_SUB_C
412 # define BN_MP_MUL_2D_C
413 # define BN_MP_CLEAR_C
417414 #endif
418415
419416 #if defined(BN_MP_GET_INT_C)
429426 #endif
430427
431428 #if defined(BN_MP_IMPORT_C)
432 #define BN_MP_ZERO_C
433 #define BN_MP_MUL_2D_C
434 #define BN_MP_CLAMP_C
429 # define BN_MP_ZERO_C
430 # define BN_MP_MUL_2D_C
431 # define BN_MP_CLAMP_C
435432 #endif
436433
437434 #if defined(BN_MP_INIT_C)
438435 #endif
439436
440437 #if defined(BN_MP_INIT_COPY_C)
441 #define BN_MP_INIT_SIZE_C
442 #define BN_MP_COPY_C
438 # define BN_MP_INIT_SIZE_C
439 # define BN_MP_COPY_C
440 # define BN_MP_CLEAR_C
443441 #endif
444442
445443 #if defined(BN_MP_INIT_MULTI_C)
446 #define BN_MP_ERR_C
447 #define BN_MP_INIT_C
448 #define BN_MP_CLEAR_C
444 # define BN_MP_ERR_C
445 # define BN_MP_INIT_C
446 # define BN_MP_CLEAR_C
449447 #endif
450448
451449 #if defined(BN_MP_INIT_SET_C)
452 #define BN_MP_INIT_C
453 #define BN_MP_SET_C
450 # define BN_MP_INIT_C
451 # define BN_MP_SET_C
454452 #endif
455453
456454 #if defined(BN_MP_INIT_SET_INT_C)
457 #define BN_MP_INIT_C
458 #define BN_MP_SET_INT_C
455 # define BN_MP_INIT_C
456 # define BN_MP_SET_INT_C
459457 #endif
460458
461459 #if defined(BN_MP_INIT_SIZE_C)
462 #define BN_MP_INIT_C
460 # define BN_MP_INIT_C
463461 #endif
464462
465463 #if defined(BN_MP_INVMOD_C)
466 #define BN_MP_ISZERO_C
467 #define BN_MP_ISODD_C
468 #define BN_FAST_MP_INVMOD_C
469 #define BN_MP_INVMOD_SLOW_C
464 # define BN_MP_ISZERO_C
465 # define BN_MP_ISODD_C
466 # define BN_MP_CMP_D_C
467 # define BN_FAST_MP_INVMOD_C
468 # define BN_MP_INVMOD_SLOW_C
470469 #endif
471470
472471 #if defined(BN_MP_INVMOD_SLOW_C)
473 #define BN_MP_ISZERO_C
474 #define BN_MP_INIT_MULTI_C
475 #define BN_MP_MOD_C
476 #define BN_MP_COPY_C
477 #define BN_MP_ISEVEN_C
478 #define BN_MP_SET_C
479 #define BN_MP_DIV_2_C
480 #define BN_MP_ISODD_C
481 #define BN_MP_ADD_C
482 #define BN_MP_SUB_C
483 #define BN_MP_CMP_C
484 #define BN_MP_CMP_D_C
485 #define BN_MP_CMP_MAG_C
486 #define BN_MP_EXCH_C
487 #define BN_MP_CLEAR_MULTI_C
472 # define BN_MP_ISZERO_C
473 # define BN_MP_INIT_MULTI_C
474 # define BN_MP_MOD_C
475 # define BN_MP_COPY_C
476 # define BN_MP_ISEVEN_C
477 # define BN_MP_SET_C
478 # define BN_MP_DIV_2_C
479 # define BN_MP_ISODD_C
480 # define BN_MP_ADD_C
481 # define BN_MP_SUB_C
482 # define BN_MP_CMP_C
483 # define BN_MP_CMP_D_C
484 # define BN_MP_CMP_MAG_C
485 # define BN_MP_EXCH_C
486 # define BN_MP_CLEAR_MULTI_C
488487 #endif
489488
490489 #if defined(BN_MP_IS_SQUARE_C)
491 #define BN_MP_MOD_D_C
492 #define BN_MP_INIT_SET_INT_C
493 #define BN_MP_MOD_C
494 #define BN_MP_GET_INT_C
495 #define BN_MP_SQRT_C
496 #define BN_MP_SQR_C
497 #define BN_MP_CMP_MAG_C
498 #define BN_MP_CLEAR_C
490 # define BN_MP_MOD_D_C
491 # define BN_MP_INIT_SET_INT_C
492 # define BN_MP_MOD_C
493 # define BN_MP_GET_INT_C
494 # define BN_MP_SQRT_C
495 # define BN_MP_SQR_C
496 # define BN_MP_CMP_MAG_C
497 # define BN_MP_CLEAR_C
499498 #endif
500499
501500 #if defined(BN_MP_JACOBI_C)
502 #define BN_MP_CMP_D_C
503 #define BN_MP_ISZERO_C
504 #define BN_MP_INIT_COPY_C
505 #define BN_MP_CNT_LSB_C
506 #define BN_MP_DIV_2D_C
507 #define BN_MP_MOD_C
508 #define BN_MP_CLEAR_C
501 # define BN_MP_ISNEG_C
502 # define BN_MP_CMP_D_C
503 # define BN_MP_ISZERO_C
504 # define BN_MP_INIT_COPY_C
505 # define BN_MP_CNT_LSB_C
506 # define BN_MP_DIV_2D_C
507 # define BN_MP_MOD_C
508 # define BN_MP_CLEAR_C
509509 #endif
510510
511511 #if defined(BN_MP_KARATSUBA_MUL_C)
512 #define BN_MP_MUL_C
513 #define BN_MP_INIT_SIZE_C
514 #define BN_MP_CLAMP_C
515 #define BN_S_MP_ADD_C
516 #define BN_MP_ADD_C
517 #define BN_S_MP_SUB_C
518 #define BN_MP_LSHD_C
519 #define BN_MP_CLEAR_C
512 # define BN_MP_MUL_C
513 # define BN_MP_INIT_SIZE_C
514 # define BN_MP_CLAMP_C
515 # define BN_S_MP_ADD_C
516 # define BN_MP_ADD_C
517 # define BN_S_MP_SUB_C
518 # define BN_MP_LSHD_C
519 # define BN_MP_CLEAR_C
520520 #endif
521521
522522 #if defined(BN_MP_KARATSUBA_SQR_C)
523 #define BN_MP_INIT_SIZE_C
524 #define BN_MP_CLAMP_C
525 #define BN_MP_SQR_C
526 #define BN_S_MP_ADD_C
527 #define BN_S_MP_SUB_C
528 #define BN_MP_LSHD_C
529 #define BN_MP_ADD_C
530 #define BN_MP_CLEAR_C
523 # define BN_MP_INIT_SIZE_C
524 # define BN_MP_CLAMP_C
525 # define BN_MP_SQR_C
526 # define BN_S_MP_ADD_C
527 # define BN_S_MP_SUB_C
528 # define BN_MP_LSHD_C
529 # define BN_MP_ADD_C
530 # define BN_MP_CLEAR_C
531531 #endif
532532
533533 #if defined(BN_MP_LCM_C)
534 #define BN_MP_INIT_MULTI_C
535 #define BN_MP_GCD_C
536 #define BN_MP_CMP_MAG_C
537 #define BN_MP_DIV_C
538 #define BN_MP_MUL_C
539 #define BN_MP_CLEAR_MULTI_C
534 # define BN_MP_INIT_MULTI_C
535 # define BN_MP_GCD_C
536 # define BN_MP_CMP_MAG_C
537 # define BN_MP_DIV_C
538 # define BN_MP_MUL_C
539 # define BN_MP_CLEAR_MULTI_C
540540 #endif
541541
542542 #if defined(BN_MP_LSHD_C)
543 #define BN_MP_GROW_C
544 #define BN_MP_RSHD_C
543 # define BN_MP_GROW_C
544 # define BN_MP_RSHD_C
545545 #endif
546546
547547 #if defined(BN_MP_MOD_C)
548 #define BN_MP_INIT_C
549 #define BN_MP_DIV_C
550 #define BN_MP_CLEAR_C
551 #define BN_MP_ISZERO_C
552 #define BN_MP_EXCH_C
553 #define BN_MP_ADD_C
548 # define BN_MP_INIT_SIZE_C
549 # define BN_MP_DIV_C
550 # define BN_MP_CLEAR_C
551 # define BN_MP_ISZERO_C
552 # define BN_MP_EXCH_C
553 # define BN_MP_ADD_C
554554 #endif
555555
556556 #if defined(BN_MP_MOD_2D_C)
557 #define BN_MP_ZERO_C
558 #define BN_MP_COPY_C
559 #define BN_MP_CLAMP_C
557 # define BN_MP_ZERO_C
558 # define BN_MP_COPY_C
559 # define BN_MP_CLAMP_C
560560 #endif
561561
562562 #if defined(BN_MP_MOD_D_C)
563 #define BN_MP_DIV_D_C
563 # define BN_MP_DIV_D_C
564564 #endif
565565
566566 #if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
567 #define BN_MP_COUNT_BITS_C
568 #define BN_MP_2EXPT_C
569 #define BN_MP_SET_C
570 #define BN_MP_MUL_2_C
571 #define BN_MP_CMP_MAG_C
572 #define BN_S_MP_SUB_C
567 # define BN_MP_COUNT_BITS_C
568 # define BN_MP_2EXPT_C
569 # define BN_MP_SET_C
570 # define BN_MP_MUL_2_C
571 # define BN_MP_CMP_MAG_C
572 # define BN_S_MP_SUB_C
573573 #endif
574574
575575 #if defined(BN_MP_MONTGOMERY_REDUCE_C)
576 #define BN_FAST_MP_MONTGOMERY_REDUCE_C
577 #define BN_MP_GROW_C
578 #define BN_MP_CLAMP_C
579 #define BN_MP_RSHD_C
580 #define BN_MP_CMP_MAG_C
581 #define BN_S_MP_SUB_C
576 # define BN_FAST_MP_MONTGOMERY_REDUCE_C
577 # define BN_MP_GROW_C
578 # define BN_MP_CLAMP_C
579 # define BN_MP_RSHD_C
580 # define BN_MP_CMP_MAG_C
581 # define BN_S_MP_SUB_C
582582 #endif
583583
584584 #if defined(BN_MP_MONTGOMERY_SETUP_C)
585585 #endif
586586
587587 #if defined(BN_MP_MUL_C)
588 #define BN_MP_TOOM_MUL_C
589 #define BN_MP_KARATSUBA_MUL_C
590 #define BN_FAST_S_MP_MUL_DIGS_C
591 #define BN_S_MP_MUL_C
592 #define BN_S_MP_MUL_DIGS_C
588 # define BN_MP_TOOM_MUL_C
589 # define BN_MP_KARATSUBA_MUL_C
590 # define BN_FAST_S_MP_MUL_DIGS_C
591 # define BN_S_MP_MUL_C
592 # define BN_S_MP_MUL_DIGS_C
593593 #endif
594594
595595 #if defined(BN_MP_MUL_2_C)
596 #define BN_MP_GROW_C
596 # define BN_MP_GROW_C
597597 #endif
598598
599599 #if defined(BN_MP_MUL_2D_C)
600 #define BN_MP_COPY_C
601 #define BN_MP_GROW_C
602 #define BN_MP_LSHD_C
603 #define BN_MP_CLAMP_C
600 # define BN_MP_COPY_C
601 # define BN_MP_GROW_C
602 # define BN_MP_LSHD_C
603 # define BN_MP_CLAMP_C
604604 #endif
605605
606606 #if defined(BN_MP_MUL_D_C)
607 #define BN_MP_GROW_C
608 #define BN_MP_CLAMP_C
607 # define BN_MP_GROW_C
608 # define BN_MP_CLAMP_C
609609 #endif
610610
611611 #if defined(BN_MP_MULMOD_C)
612 #define BN_MP_INIT_C
613 #define BN_MP_MUL_C
614 #define BN_MP_CLEAR_C
615 #define BN_MP_MOD_C
612 # define BN_MP_INIT_SIZE_C
613 # define BN_MP_MUL_C
614 # define BN_MP_CLEAR_C
615 # define BN_MP_MOD_C
616616 #endif
617617
618618 #if defined(BN_MP_N_ROOT_C)
619 #define BN_MP_N_ROOT_EX_C
619 # define BN_MP_N_ROOT_EX_C
620620 #endif
621621
622622 #if defined(BN_MP_N_ROOT_EX_C)
623 #define BN_MP_INIT_C
624 #define BN_MP_SET_C
625 #define BN_MP_COPY_C
626 #define BN_MP_EXPT_D_EX_C
627 #define BN_MP_MUL_C
628 #define BN_MP_SUB_C
629 #define BN_MP_MUL_D_C
630 #define BN_MP_DIV_C
631 #define BN_MP_CMP_C
632 #define BN_MP_SUB_D_C
633 #define BN_MP_EXCH_C
634 #define BN_MP_CLEAR_C
623 # define BN_MP_INIT_C
624 # define BN_MP_SET_C
625 # define BN_MP_COPY_C
626 # define BN_MP_EXPT_D_EX_C
627 # define BN_MP_MUL_C
628 # define BN_MP_SUB_C
629 # define BN_MP_MUL_D_C
630 # define BN_MP_DIV_C
631 # define BN_MP_CMP_C
632 # define BN_MP_SUB_D_C
633 # define BN_MP_EXCH_C
634 # define BN_MP_CLEAR_C
635635 #endif
636636
637637 #if defined(BN_MP_NEG_C)
638 #define BN_MP_COPY_C
639 #define BN_MP_ISZERO_C
638 # define BN_MP_COPY_C
639 # define BN_MP_ISZERO_C
640640 #endif
641641
642642 #if defined(BN_MP_OR_C)
643 #define BN_MP_INIT_COPY_C
644 #define BN_MP_CLAMP_C
645 #define BN_MP_EXCH_C
646 #define BN_MP_CLEAR_C
643 # define BN_MP_INIT_COPY_C
644 # define BN_MP_CLAMP_C
645 # define BN_MP_EXCH_C
646 # define BN_MP_CLEAR_C
647647 #endif
648648
649649 #if defined(BN_MP_PRIME_FERMAT_C)
650 #define BN_MP_CMP_D_C
651 #define BN_MP_INIT_C
652 #define BN_MP_EXPTMOD_C
653 #define BN_MP_CMP_C
654 #define BN_MP_CLEAR_C
650 # define BN_MP_CMP_D_C
651 # define BN_MP_INIT_C
652 # define BN_MP_EXPTMOD_C
653 # define BN_MP_CMP_C
654 # define BN_MP_CLEAR_C
655655 #endif
656656
657657 #if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
658 #define BN_MP_MOD_D_C
658 # define BN_MP_MOD_D_C
659659 #endif
660660
661661 #if defined(BN_MP_PRIME_IS_PRIME_C)
662 #define BN_MP_CMP_D_C
663 #define BN_MP_PRIME_IS_DIVISIBLE_C
664 #define BN_MP_INIT_C
665 #define BN_MP_SET_C
666 #define BN_MP_PRIME_MILLER_RABIN_C
667 #define BN_MP_CLEAR_C
662 # define BN_MP_CMP_D_C
663 # define BN_MP_PRIME_IS_DIVISIBLE_C
664 # define BN_MP_INIT_C
665 # define BN_MP_SET_C
666 # define BN_MP_PRIME_MILLER_RABIN_C
667 # define BN_MP_CLEAR_C
668668 #endif
669669
670670 #if defined(BN_MP_PRIME_MILLER_RABIN_C)
671 #define BN_MP_CMP_D_C
672 #define BN_MP_INIT_COPY_C
673 #define BN_MP_SUB_D_C
674 #define BN_MP_CNT_LSB_C
675 #define BN_MP_DIV_2D_C
676 #define BN_MP_EXPTMOD_C
677 #define BN_MP_CMP_C
678 #define BN_MP_SQRMOD_C
679 #define BN_MP_CLEAR_C
671 # define BN_MP_CMP_D_C
672 # define BN_MP_INIT_COPY_C
673 # define BN_MP_SUB_D_C
674 # define BN_MP_CNT_LSB_C
675 # define BN_MP_DIV_2D_C
676 # define BN_MP_EXPTMOD_C
677 # define BN_MP_CMP_C
678 # define BN_MP_SQRMOD_C
679 # define BN_MP_CLEAR_C
680680 #endif
681681
682682 #if defined(BN_MP_PRIME_NEXT_PRIME_C)
683 #define BN_MP_CMP_D_C
684 #define BN_MP_SET_C
685 #define BN_MP_SUB_D_C
686 #define BN_MP_ISEVEN_C
687 #define BN_MP_MOD_D_C
688 #define BN_MP_INIT_C
689 #define BN_MP_ADD_D_C
690 #define BN_MP_PRIME_MILLER_RABIN_C
691 #define BN_MP_CLEAR_C
683 # define BN_MP_CMP_D_C
684 # define BN_MP_SET_C
685 # define BN_MP_SUB_D_C
686 # define BN_MP_ISEVEN_C
687 # define BN_MP_MOD_D_C
688 # define BN_MP_INIT_C
689 # define BN_MP_ADD_D_C
690 # define BN_MP_PRIME_MILLER_RABIN_C
691 # define BN_MP_CLEAR_C
692692 #endif
693693
694694 #if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
695695 #endif
696696
697697 #if defined(BN_MP_PRIME_RANDOM_EX_C)
698 #define BN_MP_READ_UNSIGNED_BIN_C
699 #define BN_MP_PRIME_IS_PRIME_C
700 #define BN_MP_SUB_D_C
701 #define BN_MP_DIV_2_C
702 #define BN_MP_MUL_2_C
703 #define BN_MP_ADD_D_C
698 # define BN_MP_READ_UNSIGNED_BIN_C
699 # define BN_MP_PRIME_IS_PRIME_C
700 # define BN_MP_SUB_D_C
701 # define BN_MP_DIV_2_C
702 # define BN_MP_MUL_2_C
703 # define BN_MP_ADD_D_C
704704 #endif
705705
706706 #if defined(BN_MP_RADIX_SIZE_C)
707 #define BN_MP_ISZERO_C
708 #define BN_MP_COUNT_BITS_C
709 #define BN_MP_INIT_COPY_C
710 #define BN_MP_DIV_D_C
711 #define BN_MP_CLEAR_C
707 # define BN_MP_ISZERO_C
708 # define BN_MP_COUNT_BITS_C
709 # define BN_MP_INIT_COPY_C
710 # define BN_MP_DIV_D_C
711 # define BN_MP_CLEAR_C
712712 #endif
713713
714714 #if defined(BN_MP_RADIX_SMAP_C)
715 #define BN_MP_S_RMAP_C
715 # define BN_MP_S_RMAP_C
716716 #endif
717717
718718 #if defined(BN_MP_RAND_C)
719 #define BN_MP_ZERO_C
720 #define BN_MP_ADD_D_C
721 #define BN_MP_LSHD_C
719 # define BN_MP_ZERO_C
720 # define BN_MP_ADD_D_C
721 # define BN_MP_LSHD_C
722722 #endif
723723
724724 #if defined(BN_MP_READ_RADIX_C)
725 #define BN_MP_ZERO_C
726 #define BN_MP_S_RMAP_C
727 #define BN_MP_MUL_D_C
728 #define BN_MP_ADD_D_C
729 #define BN_MP_ISZERO_C
725 # define BN_MP_ZERO_C
726 # define BN_MP_S_RMAP_C
727 # define BN_MP_MUL_D_C
728 # define BN_MP_ADD_D_C
729 # define BN_MP_ISZERO_C
730730 #endif
731731
732732 #if defined(BN_MP_READ_SIGNED_BIN_C)
733 #define BN_MP_READ_UNSIGNED_BIN_C
733 # define BN_MP_READ_UNSIGNED_BIN_C
734734 #endif
735735
736736 #if defined(BN_MP_READ_UNSIGNED_BIN_C)
737 #define BN_MP_GROW_C
738 #define BN_MP_ZERO_C
739 #define BN_MP_MUL_2D_C
740 #define BN_MP_CLAMP_C
737 # define BN_MP_GROW_C
738 # define BN_MP_ZERO_C
739 # define BN_MP_MUL_2D_C
740 # define BN_MP_CLAMP_C
741741 #endif
742742
743743 #if defined(BN_MP_REDUCE_C)
744 #define BN_MP_REDUCE_SETUP_C
745 #define BN_MP_INIT_COPY_C
746 #define BN_MP_RSHD_C
747 #define BN_MP_MUL_C
748 #define BN_S_MP_MUL_HIGH_DIGS_C
749 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
750 #define BN_MP_MOD_2D_C
751 #define BN_S_MP_MUL_DIGS_C
752 #define BN_MP_SUB_C
753 #define BN_MP_CMP_D_C
754 #define BN_MP_SET_C
755 #define BN_MP_LSHD_C
756 #define BN_MP_ADD_C
757 #define BN_MP_CMP_C
758 #define BN_S_MP_SUB_C
759 #define BN_MP_CLEAR_C
744 # define BN_MP_REDUCE_SETUP_C
745 # define BN_MP_INIT_COPY_C
746 # define BN_MP_RSHD_C
747 # define BN_MP_MUL_C
748 # define BN_S_MP_MUL_HIGH_DIGS_C
749 # define BN_FAST_S_MP_MUL_HIGH_DIGS_C
750 # define BN_MP_MOD_2D_C
751 # define BN_S_MP_MUL_DIGS_C
752 # define BN_MP_SUB_C
753 # define BN_MP_CMP_D_C
754 # define BN_MP_SET_C
755 # define BN_MP_LSHD_C
756 # define BN_MP_ADD_C
757 # define BN_MP_CMP_C
758 # define BN_S_MP_SUB_C
759 # define BN_MP_CLEAR_C
760760 #endif
761761
762762 #if defined(BN_MP_REDUCE_2K_C)
763 #define BN_MP_INIT_C
764 #define BN_MP_COUNT_BITS_C
765 #define BN_MP_DIV_2D_C
766 #define BN_MP_MUL_D_C
767 #define BN_S_MP_ADD_C
768 #define BN_MP_CMP_MAG_C
769 #define BN_S_MP_SUB_C
770 #define BN_MP_CLEAR_C
763 # define BN_MP_INIT_C
764 # define BN_MP_COUNT_BITS_C
765 # define BN_MP_DIV_2D_C
766 # define BN_MP_MUL_D_C
767 # define BN_S_MP_ADD_C
768 # define BN_MP_CMP_MAG_C
769 # define BN_S_MP_SUB_C
770 # define BN_MP_CLEAR_C
771771 #endif
772772
773773 #if defined(BN_MP_REDUCE_2K_L_C)
774 #define BN_MP_INIT_C
775 #define BN_MP_COUNT_BITS_C
776 #define BN_MP_DIV_2D_C
777 #define BN_MP_MUL_C
778 #define BN_S_MP_ADD_C
779 #define BN_MP_CMP_MAG_C
780 #define BN_S_MP_SUB_C
781 #define BN_MP_CLEAR_C
774 # define BN_MP_INIT_C
775 # define BN_MP_COUNT_BITS_C
776 # define BN_MP_DIV_2D_C
777 # define BN_MP_MUL_C
778 # define BN_S_MP_ADD_C
779 # define BN_MP_CMP_MAG_C
780 # define BN_S_MP_SUB_C
781 # define BN_MP_CLEAR_C
782782 #endif
783783
784784 #if defined(BN_MP_REDUCE_2K_SETUP_C)
785 #define BN_MP_INIT_C
786 #define BN_MP_COUNT_BITS_C
787 #define BN_MP_2EXPT_C
788 #define BN_MP_CLEAR_C
789 #define BN_S_MP_SUB_C
785 # define BN_MP_INIT_C
786 # define BN_MP_COUNT_BITS_C
787 # define BN_MP_2EXPT_C
788 # define BN_MP_CLEAR_C
789 # define BN_S_MP_SUB_C
790790 #endif
791791
792792 #if defined(BN_MP_REDUCE_2K_SETUP_L_C)
793 #define BN_MP_INIT_C
794 #define BN_MP_2EXPT_C
795 #define BN_MP_COUNT_BITS_C
796 #define BN_S_MP_SUB_C
797 #define BN_MP_CLEAR_C
793 # define BN_MP_INIT_C
794 # define BN_MP_2EXPT_C
795 # define BN_MP_COUNT_BITS_C
796 # define BN_S_MP_SUB_C
797 # define BN_MP_CLEAR_C
798798 #endif
799799
800800 #if defined(BN_MP_REDUCE_IS_2K_C)
801 #define BN_MP_REDUCE_2K_C
802 #define BN_MP_COUNT_BITS_C
801 # define BN_MP_REDUCE_2K_C
802 # define BN_MP_COUNT_BITS_C
803803 #endif
804804
805805 #if defined(BN_MP_REDUCE_IS_2K_L_C)
806806 #endif
807807
808808 #if defined(BN_MP_REDUCE_SETUP_C)
809 #define BN_MP_2EXPT_C
810 #define BN_MP_DIV_C
809 # define BN_MP_2EXPT_C
810 # define BN_MP_DIV_C
811811 #endif
812812
813813 #if defined(BN_MP_RSHD_C)
814 #define BN_MP_ZERO_C
814 # define BN_MP_ZERO_C
815815 #endif
816816
817817 #if defined(BN_MP_SET_C)
818 #define BN_MP_ZERO_C
818 # define BN_MP_ZERO_C
819819 #endif
820820
821821 #if defined(BN_MP_SET_INT_C)
822 #define BN_MP_ZERO_C
823 #define BN_MP_MUL_2D_C
824 #define BN_MP_CLAMP_C
822 # define BN_MP_ZERO_C
823 # define BN_MP_MUL_2D_C
824 # define BN_MP_CLAMP_C
825825 #endif
826826
827827 #if defined(BN_MP_SET_LONG_C)
834834 #endif
835835
836836 #if defined(BN_MP_SIGNED_BIN_SIZE_C)
837 #define BN_MP_UNSIGNED_BIN_SIZE_C
837 # define BN_MP_UNSIGNED_BIN_SIZE_C
838838 #endif
839839
840840 #if defined(BN_MP_SQR_C)
841 #define BN_MP_TOOM_SQR_C
842 #define BN_MP_KARATSUBA_SQR_C
843 #define BN_FAST_S_MP_SQR_C
844 #define BN_S_MP_SQR_C
841 # define BN_MP_TOOM_SQR_C
842 # define BN_MP_KARATSUBA_SQR_C
843 # define BN_FAST_S_MP_SQR_C
844 # define BN_S_MP_SQR_C
845845 #endif
846846
847847 #if defined(BN_MP_SQRMOD_C)
848 #define BN_MP_INIT_C
849 #define BN_MP_SQR_C
850 #define BN_MP_CLEAR_C
851 #define BN_MP_MOD_C
848 # define BN_MP_INIT_C
849 # define BN_MP_SQR_C
850 # define BN_MP_CLEAR_C
851 # define BN_MP_MOD_C
852852 #endif
853853
854854 #if defined(BN_MP_SQRT_C)
855 #define BN_MP_N_ROOT_C
856 #define BN_MP_ISZERO_C
857 #define BN_MP_ZERO_C
858 #define BN_MP_INIT_COPY_C
859 #define BN_MP_RSHD_C
860 #define BN_MP_DIV_C
861 #define BN_MP_ADD_C
862 #define BN_MP_DIV_2_C
863 #define BN_MP_CMP_MAG_C
864 #define BN_MP_EXCH_C
865 #define BN_MP_CLEAR_C
855 # define BN_MP_N_ROOT_C
856 # define BN_MP_ISZERO_C
857 # define BN_MP_ZERO_C
858 # define BN_MP_INIT_COPY_C
859 # define BN_MP_RSHD_C
860 # define BN_MP_DIV_C
861 # define BN_MP_ADD_C
862 # define BN_MP_DIV_2_C
863 # define BN_MP_CMP_MAG_C
864 # define BN_MP_EXCH_C
865 # define BN_MP_CLEAR_C
866866 #endif
867867
868868 #if defined(BN_MP_SQRTMOD_PRIME_C)
869 #define BN_MP_CMP_D_C
870 #define BN_MP_ZERO_C
871 #define BN_MP_JACOBI_C
872 #define BN_MP_INIT_MULTI_C
873 #define BN_MP_MOD_D_C
874 #define BN_MP_ADD_D_C
875 #define BN_MP_DIV_2_C
876 #define BN_MP_EXPTMOD_C
877 #define BN_MP_COPY_C
878 #define BN_MP_SUB_D_C
879 #define BN_MP_ISEVEN_C
880 #define BN_MP_SET_INT_C
881 #define BN_MP_SQRMOD_C
882 #define BN_MP_MULMOD_C
883 #define BN_MP_SET_C
884 #define BN_MP_CLEAR_MULTI_C
869 # define BN_MP_CMP_D_C
870 # define BN_MP_ZERO_C
871 # define BN_MP_JACOBI_C
872 # define BN_MP_INIT_MULTI_C
873 # define BN_MP_MOD_D_C
874 # define BN_MP_ADD_D_C
875 # define BN_MP_DIV_2_C
876 # define BN_MP_EXPTMOD_C
877 # define BN_MP_COPY_C
878 # define BN_MP_SUB_D_C
879 # define BN_MP_ISEVEN_C
880 # define BN_MP_SET_INT_C
881 # define BN_MP_SQRMOD_C
882 # define BN_MP_MULMOD_C
883 # define BN_MP_SET_C
884 # define BN_MP_CLEAR_MULTI_C
885885 #endif
886886
887887 #if defined(BN_MP_SUB_C)
888 #define BN_S_MP_ADD_C
889 #define BN_MP_CMP_MAG_C
890 #define BN_S_MP_SUB_C
888 # define BN_S_MP_ADD_C
889 # define BN_MP_CMP_MAG_C
890 # define BN_S_MP_SUB_C
891891 #endif
892892
893893 #if defined(BN_MP_SUB_D_C)
894 #define BN_MP_GROW_C
895 #define BN_MP_ADD_D_C
896 #define BN_MP_CLAMP_C
894 # define BN_MP_GROW_C
895 # define BN_MP_ADD_D_C
896 # define BN_MP_CLAMP_C
897897 #endif
898898
899899 #if defined(BN_MP_SUBMOD_C)
900 #define BN_MP_INIT_C
901 #define BN_MP_SUB_C
902 #define BN_MP_CLEAR_C
903 #define BN_MP_MOD_C
900 # define BN_MP_INIT_C
901 # define BN_MP_SUB_C
902 # define BN_MP_CLEAR_C
903 # define BN_MP_MOD_C
904904 #endif
905905
906906 #if defined(BN_MP_TO_SIGNED_BIN_C)
907 #define BN_MP_TO_UNSIGNED_BIN_C
907 # define BN_MP_TO_UNSIGNED_BIN_C
908908 #endif
909909
910910 #if defined(BN_MP_TO_SIGNED_BIN_N_C)
911 #define BN_MP_SIGNED_BIN_SIZE_C
912 #define BN_MP_TO_SIGNED_BIN_C
911 # define BN_MP_SIGNED_BIN_SIZE_C
912 # define BN_MP_TO_SIGNED_BIN_C
913913 #endif
914914
915915 #if defined(BN_MP_TO_UNSIGNED_BIN_C)
916 #define BN_MP_INIT_COPY_C
917 #define BN_MP_ISZERO_C
918 #define BN_MP_DIV_2D_C
919 #define BN_MP_CLEAR_C
916 # define BN_MP_INIT_COPY_C
917 # define BN_MP_ISZERO_C
918 # define BN_MP_DIV_2D_C
919 # define BN_MP_CLEAR_C
920920 #endif
921921
922922 #if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
923 #define BN_MP_UNSIGNED_BIN_SIZE_C
924 #define BN_MP_TO_UNSIGNED_BIN_C
923 # define BN_MP_UNSIGNED_BIN_SIZE_C
924 # define BN_MP_TO_UNSIGNED_BIN_C
925925 #endif
926926
927927 #if defined(BN_MP_TOOM_MUL_C)
928 #define BN_MP_INIT_MULTI_C
929 #define BN_MP_MOD_2D_C
930 #define BN_MP_COPY_C
931 #define BN_MP_RSHD_C
932 #define BN_MP_MUL_C
933 #define BN_MP_MUL_2_C
934 #define BN_MP_ADD_C
935 #define BN_MP_SUB_C
936 #define BN_MP_DIV_2_C
937 #define BN_MP_MUL_2D_C
938 #define BN_MP_MUL_D_C
939 #define BN_MP_DIV_3_C
940 #define BN_MP_LSHD_C
941 #define BN_MP_CLEAR_MULTI_C
928 # define BN_MP_INIT_MULTI_C
929 # define BN_MP_MOD_2D_C
930 # define BN_MP_COPY_C
931 # define BN_MP_RSHD_C
932 # define BN_MP_MUL_C
933 # define BN_MP_MUL_2_C
934 # define BN_MP_ADD_C
935 # define BN_MP_SUB_C
936 # define BN_MP_DIV_2_C
937 # define BN_MP_MUL_2D_C
938 # define BN_MP_MUL_D_C
939 # define BN_MP_DIV_3_C
940 # define BN_MP_LSHD_C
941 # define BN_MP_CLEAR_MULTI_C
942942 #endif
943943
944944 #if defined(BN_MP_TOOM_SQR_C)
945 #define BN_MP_INIT_MULTI_C
946 #define BN_MP_MOD_2D_C
947 #define BN_MP_COPY_C
948 #define BN_MP_RSHD_C
949 #define BN_MP_SQR_C
950 #define BN_MP_MUL_2_C
951 #define BN_MP_ADD_C
952 #define BN_MP_SUB_C
953 #define BN_MP_DIV_2_C
954 #define BN_MP_MUL_2D_C
955 #define BN_MP_MUL_D_C
956 #define BN_MP_DIV_3_C
957 #define BN_MP_LSHD_C
958 #define BN_MP_CLEAR_MULTI_C
945 # define BN_MP_INIT_MULTI_C
946 # define BN_MP_MOD_2D_C
947 # define BN_MP_COPY_C
948 # define BN_MP_RSHD_C
949 # define BN_MP_SQR_C
950 # define BN_MP_MUL_2_C
951 # define BN_MP_ADD_C
952 # define BN_MP_SUB_C
953 # define BN_MP_DIV_2_C
954 # define BN_MP_MUL_2D_C
955 # define BN_MP_MUL_D_C
956 # define BN_MP_DIV_3_C
957 # define BN_MP_LSHD_C
958 # define BN_MP_CLEAR_MULTI_C
959959 #endif
960960
961961 #if defined(BN_MP_TORADIX_C)
962 #define BN_MP_ISZERO_C
963 #define BN_MP_INIT_COPY_C
964 #define BN_MP_DIV_D_C
965 #define BN_MP_CLEAR_C
966 #define BN_MP_S_RMAP_C
962 # define BN_MP_ISZERO_C
963 # define BN_MP_INIT_COPY_C
964 # define BN_MP_DIV_D_C
965 # define BN_MP_CLEAR_C
966 # define BN_MP_S_RMAP_C
967967 #endif
968968
969969 #if defined(BN_MP_TORADIX_N_C)
970 #define BN_MP_ISZERO_C
971 #define BN_MP_INIT_COPY_C
972 #define BN_MP_DIV_D_C
973 #define BN_MP_CLEAR_C
974 #define BN_MP_S_RMAP_C
970 # define BN_MP_ISZERO_C
971 # define BN_MP_INIT_COPY_C
972 # define BN_MP_DIV_D_C
973 # define BN_MP_CLEAR_C
974 # define BN_MP_S_RMAP_C
975975 #endif
976976
977977 #if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
978 #define BN_MP_COUNT_BITS_C
978 # define BN_MP_COUNT_BITS_C
979979 #endif
980980
981981 #if defined(BN_MP_XOR_C)
982 #define BN_MP_INIT_COPY_C
983 #define BN_MP_CLAMP_C
984 #define BN_MP_EXCH_C
985 #define BN_MP_CLEAR_C
982 # define BN_MP_INIT_COPY_C
983 # define BN_MP_CLAMP_C
984 # define BN_MP_EXCH_C
985 # define BN_MP_CLEAR_C
986986 #endif
987987
988988 #if defined(BN_MP_ZERO_C)
995995 #endif
996996
997997 #if defined(BN_S_MP_ADD_C)
998 #define BN_MP_GROW_C
999 #define BN_MP_CLAMP_C
998 # define BN_MP_GROW_C
999 # define BN_MP_CLAMP_C
10001000 #endif
10011001
10021002 #if defined(BN_S_MP_EXPTMOD_C)
1003 #define BN_MP_COUNT_BITS_C
1004 #define BN_MP_INIT_C
1005 #define BN_MP_CLEAR_C
1006 #define BN_MP_REDUCE_SETUP_C
1007 #define BN_MP_REDUCE_C
1008 #define BN_MP_REDUCE_2K_SETUP_L_C
1009 #define BN_MP_REDUCE_2K_L_C
1010 #define BN_MP_MOD_C
1011 #define BN_MP_COPY_C
1012 #define BN_MP_SQR_C
1013 #define BN_MP_MUL_C
1014 #define BN_MP_SET_C
1015 #define BN_MP_EXCH_C
1003 # define BN_MP_COUNT_BITS_C
1004 # define BN_MP_INIT_C
1005 # define BN_MP_CLEAR_C
1006 # define BN_MP_REDUCE_SETUP_C
1007 # define BN_MP_REDUCE_C
1008 # define BN_MP_REDUCE_2K_SETUP_L_C
1009 # define BN_MP_REDUCE_2K_L_C
1010 # define BN_MP_MOD_C
1011 # define BN_MP_COPY_C
1012 # define BN_MP_SQR_C
1013 # define BN_MP_MUL_C
1014 # define BN_MP_SET_C
1015 # define BN_MP_EXCH_C
10161016 #endif
10171017
10181018 #if defined(BN_S_MP_MUL_DIGS_C)
1019 #define BN_FAST_S_MP_MUL_DIGS_C
1020 #define BN_MP_INIT_SIZE_C
1021 #define BN_MP_CLAMP_C
1022 #define BN_MP_EXCH_C
1023 #define BN_MP_CLEAR_C
1019 # define BN_FAST_S_MP_MUL_DIGS_C
1020 # define BN_MP_INIT_SIZE_C
1021 # define BN_MP_CLAMP_C
1022 # define BN_MP_EXCH_C
1023 # define BN_MP_CLEAR_C
10241024 #endif
10251025
10261026 #if defined(BN_S_MP_MUL_HIGH_DIGS_C)
1027 #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
1028 #define BN_MP_INIT_SIZE_C
1029 #define BN_MP_CLAMP_C
1030 #define BN_MP_EXCH_C
1031 #define BN_MP_CLEAR_C
1027 # define BN_FAST_S_MP_MUL_HIGH_DIGS_C
1028 # define BN_MP_INIT_SIZE_C
1029 # define BN_MP_CLAMP_C
1030 # define BN_MP_EXCH_C
1031 # define BN_MP_CLEAR_C
10321032 #endif
10331033
10341034 #if defined(BN_S_MP_SQR_C)
1035 #define BN_MP_INIT_SIZE_C
1036 #define BN_MP_CLAMP_C
1037 #define BN_MP_EXCH_C
1038 #define BN_MP_CLEAR_C
1035 # define BN_MP_INIT_SIZE_C
1036 # define BN_MP_CLAMP_C
1037 # define BN_MP_EXCH_C
1038 # define BN_MP_CLEAR_C
10391039 #endif
10401040
10411041 #if defined(BN_S_MP_SUB_C)
1042 #define BN_MP_GROW_C
1043 #define BN_MP_CLAMP_C
1042 # define BN_MP_GROW_C
1043 # define BN_MP_CLAMP_C
10441044 #endif
10451045
10461046 #if defined(BNCORE_C)
10471047 #endif
10481048
10491049 #ifdef LTM3
1050 #define LTM_LAST
1051 #endif
1050 # define LTM_LAST
1051 #endif
1052
10521053 #include <tommath_superclass.h>
10531054 #include <tommath_class.h>
10541055 #else
1055 #define LTM_LAST
1056 #endif
1056 # define LTM_LAST
1057 #endif
1818 #include <ctype.h>
1919
2020 #ifndef MIN
21 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
21 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
2222 #endif
2323
2424 #ifndef MAX
25 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
25 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
2626 #endif
2727
2828 #ifdef __cplusplus
2929 extern "C" {
3030
3131 /* C++ compilers don't like assigning void * to mp_digit * */
32 #define OPT_CAST(x) (x *)
32 #define OPT_CAST(x) (x *)
3333
3434 #else
3535
3636 /* C on the other hand doesn't care */
37 #define OPT_CAST(x)
37 #define OPT_CAST(x)
3838
3939 #endif
4040
4141 /* define heap macros */
4242 #ifndef XMALLOC
43 /* default to libc stuff */
44 #define XMALLOC malloc
45 #define XFREE free
46 #define XREALLOC realloc
47 #define XCALLOC calloc
43 /* default to libc stuff */
44 # define XMALLOC malloc
45 # define XFREE free
46 # define XREALLOC realloc
47 # define XCALLOC calloc
4848 #else
49 /* prototypes for our heap functions */
50 extern void *XMALLOC(size_t n);
51 extern void *XREALLOC(void *p, size_t n);
52 extern void *XCALLOC(size_t n, size_t s);
53 extern void XFREE(void *p);
49 /* prototypes for our heap functions */
50 extern void *XMALLOC(size_t n);
51 extern void *XREALLOC(void *p, size_t n);
52 extern void *XCALLOC(size_t n, size_t s);
53 extern void XFREE(void *p);
5454 #endif
5555
5656 /* lowlevel functions, do not call! */
57 int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
58 int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
57 int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c);
58 int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
5959 #define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
60 int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
61 int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
62 int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
63 int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
64 int fast_s_mp_sqr(mp_int *a, mp_int *b);
65 int s_mp_sqr(mp_int *a, mp_int *b);
66 int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
67 int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
68 int mp_karatsuba_sqr(mp_int *a, mp_int *b);
69 int mp_toom_sqr(mp_int *a, mp_int *b);
70 int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
71 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
72 int fast_mp_montgomery_reduce(mp_int *x, mp_int *n, mp_digit rho);
73 int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode);
74 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);
60 int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
61 int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
62 int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
63 int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs);
64 int fast_s_mp_sqr(const mp_int *a, mp_int *b);
65 int s_mp_sqr(const mp_int *a, mp_int *b);
66 int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c);
67 int mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c);
68 int mp_karatsuba_sqr(const mp_int *a, mp_int *b);
69 int mp_toom_sqr(const mp_int *a, mp_int *b);
70 int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c);
71 int mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c);
72 int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho);
73 int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode);
74 int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode);
7575 void bn_reverse(unsigned char *s, int len);
7676
7777 extern const char *mp_s_rmap;
78 extern const uint8_t mp_s_rmap_reverse[];
79 extern const size_t mp_s_rmap_reverse_sz;
7880
7981 /* Fancy macro to set an MPI from another type.
8082 * There are several things assumed:
98100 } \
99101 \
100102 /* OR in the top four bits of the source */ \
101 a->dp[0] |= (b >> ((sizeof(type) * 8u) - 4u)) & 15u; \
103 a->dp[0] |= (mp_digit)(b >> ((sizeof(type) * 8u) - 4u)) & 15uL;\
102104 \
103105 /* shift the source up to the next four bits */ \
104106 b <<= 4; \
111113 }
112114
113115 #ifdef __cplusplus
114 }
116 }
115117 #endif
116118
117119 #endif
118120
119121
120 /* $Source$ */
121 /* $Revision$ */
122 /* $Date$ */
122 /* ref: $Format:%D$ */
123 /* git commit: $Format:%H$ */
124 /* commit time: $Format:%ai$ */
1313
1414 /* Works for RSA only, mpi.o is 68KiB */
1515 #ifdef SC_RSA_1
16 #define BN_MP_SHRINK_C
17 #define BN_MP_LCM_C
18 #define BN_MP_PRIME_RANDOM_EX_C
19 #define BN_MP_INVMOD_C
20 #define BN_MP_GCD_C
21 #define BN_MP_MOD_C
22 #define BN_MP_MULMOD_C
23 #define BN_MP_ADDMOD_C
24 #define BN_MP_EXPTMOD_C
25 #define BN_MP_SET_INT_C
26 #define BN_MP_INIT_MULTI_C
27 #define BN_MP_CLEAR_MULTI_C
28 #define BN_MP_UNSIGNED_BIN_SIZE_C
29 #define BN_MP_TO_UNSIGNED_BIN_C
30 #define BN_MP_MOD_D_C
31 #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
32 #define BN_REVERSE_C
33 #define BN_PRIME_TAB_C
16 # define BN_MP_SHRINK_C
17 # define BN_MP_LCM_C
18 # define BN_MP_PRIME_RANDOM_EX_C
19 # define BN_MP_INVMOD_C
20 # define BN_MP_GCD_C
21 # define BN_MP_MOD_C
22 # define BN_MP_MULMOD_C
23 # define BN_MP_ADDMOD_C
24 # define BN_MP_EXPTMOD_C
25 # define BN_MP_SET_INT_C
26 # define BN_MP_INIT_MULTI_C
27 # define BN_MP_CLEAR_MULTI_C
28 # define BN_MP_UNSIGNED_BIN_SIZE_C
29 # define BN_MP_TO_UNSIGNED_BIN_C
30 # define BN_MP_MOD_D_C
31 # define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
32 # define BN_REVERSE_C
33 # define BN_PRIME_TAB_C
3434
35 /* other modifiers */
36 #define BN_MP_DIV_SMALL /* Slower division, not critical */
35 /* other modifiers */
36 # define BN_MP_DIV_SMALL /* Slower division, not critical */
3737
38 /* here we are on the last pass so we turn things off. The functions classes are still there
39 * but we remove them specifically from the build. This also invokes tweaks in functions
40 * like removing support for even moduli, etc...
41 */
42 #ifdef LTM_LAST
43 #undef BN_MP_TOOM_MUL_C
44 #undef BN_MP_TOOM_SQR_C
45 #undef BN_MP_KARATSUBA_MUL_C
46 #undef BN_MP_KARATSUBA_SQR_C
47 #undef BN_MP_REDUCE_C
48 #undef BN_MP_REDUCE_SETUP_C
49 #undef BN_MP_DR_IS_MODULUS_C
50 #undef BN_MP_DR_SETUP_C
51 #undef BN_MP_DR_REDUCE_C
52 #undef BN_MP_REDUCE_IS_2K_C
53 #undef BN_MP_REDUCE_2K_SETUP_C
54 #undef BN_MP_REDUCE_2K_C
55 #undef BN_S_MP_EXPTMOD_C
56 #undef BN_MP_DIV_3_C
57 #undef BN_S_MP_MUL_HIGH_DIGS_C
58 #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
59 #undef BN_FAST_MP_INVMOD_C
38 /* here we are on the last pass so we turn things off. The functions classes are still there
39 * but we remove them specifically from the build. This also invokes tweaks in functions
40 * like removing support for even moduli, etc...
41 */
42 # ifdef LTM_LAST
43 # undef BN_MP_TOOM_MUL_C
44 # undef BN_MP_TOOM_SQR_C
45 # undef BN_MP_KARATSUBA_MUL_C
46 # undef BN_MP_KARATSUBA_SQR_C
47 # undef BN_MP_REDUCE_C
48 # undef BN_MP_REDUCE_SETUP_C
49 # undef BN_MP_DR_IS_MODULUS_C
50 # undef BN_MP_DR_SETUP_C
51 # undef BN_MP_DR_REDUCE_C
52 # undef BN_MP_REDUCE_IS_2K_C
53 # undef BN_MP_REDUCE_2K_SETUP_C
54 # undef BN_MP_REDUCE_2K_C
55 # undef BN_S_MP_EXPTMOD_C
56 # undef BN_MP_DIV_3_C
57 # undef BN_S_MP_MUL_HIGH_DIGS_C
58 # undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
59 # undef BN_FAST_MP_INVMOD_C
6060
61 /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
62 * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
63 * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
64 * trouble.
65 */
66 #undef BN_S_MP_MUL_DIGS_C
67 #undef BN_S_MP_SQR_C
68 #undef BN_MP_MONTGOMERY_REDUCE_C
69 #endif
61 /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
62 * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
63 * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
64 * trouble.
65 */
66 # undef BN_S_MP_MUL_DIGS_C
67 # undef BN_S_MP_SQR_C
68 # undef BN_MP_MONTGOMERY_REDUCE_C
69 # endif
7070
7171 #endif
7272
73 /* $Source$ */
74 /* $Revision$ */
75 /* $Date$ */
73 /* ref: $Format:%D$ */
74 /* git commit: $Format:%H$ */
75 /* commit time: $Format:%ai$ */
88 my $ok;
99 END { die "Could not load all modules" unless $ok }
1010
11 use CryptX;
11 use Crypt::AuthEnc::CCM;
12 use Crypt::AuthEnc::ChaCha20Poly1305;
13 use Crypt::AuthEnc::EAX;
14 use Crypt::AuthEnc::GCM;
15 use Crypt::AuthEnc::OCB;
16 use Crypt::AuthEnc;
17 use Crypt::Checksum::Adler32;
18 use Crypt::Checksum::CRC32;
19 use Crypt::Checksum;
1220 use Crypt::Cipher::AES;
1321 use Crypt::Cipher::Anubis;
1422 use Crypt::Cipher::Blowfish;
3543 use Crypt::Cipher::Twofish;
3644 use Crypt::Cipher::XTEA;
3745 use Crypt::Cipher;
46 use Crypt::Digest::BLAKE2b_160;
47 use Crypt::Digest::BLAKE2b_256;
48 use Crypt::Digest::BLAKE2b_384;
49 use Crypt::Digest::BLAKE2b_512;
50 use Crypt::Digest::BLAKE2s_128;
51 use Crypt::Digest::BLAKE2s_160;
52 use Crypt::Digest::BLAKE2s_224;
53 use Crypt::Digest::BLAKE2s_256;
3854 use Crypt::Digest::CHAES;
3955 use Crypt::Digest::MD2;
4056 use Crypt::Digest::MD4;
4763 use Crypt::Digest::SHA224;
4864 use Crypt::Digest::SHA256;
4965 use Crypt::Digest::SHA384;
66 use Crypt::Digest::SHA3_224;
67 use Crypt::Digest::SHA3_256;
68 use Crypt::Digest::SHA3_384;
69 use Crypt::Digest::SHA3_512;
5070 use Crypt::Digest::SHA512;
71 use Crypt::Digest::SHA512_224;
72 use Crypt::Digest::SHA512_256;
73 use Crypt::Digest::SHAKE;
5174 use Crypt::Digest::Tiger192;
5275 use Crypt::Digest::Whirlpool;
5376 use Crypt::Digest;
77 use Crypt::KeyDerivation;
78 use Crypt::Mac::BLAKE2b;
79 use Crypt::Mac::BLAKE2s;
5480 use Crypt::Mac::F9;
5581 use Crypt::Mac::HMAC;
5682 use Crypt::Mac::OMAC;
5783 use Crypt::Mac::Pelican;
5884 use Crypt::Mac::PMAC;
85 use Crypt::Mac::Poly1305;
5986 use Crypt::Mac::XCBC;
87 use Crypt::Mac;
88 use Crypt::Misc;
6089 use Crypt::Mode::CBC;
90 use Crypt::Mode::CFB;
91 use Crypt::Mode::CTR;
6192 use Crypt::Mode::ECB;
6293 use Crypt::Mode::OFB;
63 use Crypt::Mode::CFB;
64 use Crypt::Mode::CTR;
65 use Crypt::PK::RSA;
94 use Crypt::Mode;
95 use Crypt::PK::DH;
6696 use Crypt::PK::DSA;
6797 use Crypt::PK::ECC;
68 use Crypt::PK::DH;
69 use Crypt::Checksum;
70 use Crypt::Checksum::Adler32;
71 use Crypt::Checksum::CRC32;
98 use Crypt::PK::RSA;
99 use Crypt::PK;
100 use Crypt::PRNG::ChaCha20;
101 use Crypt::PRNG::Fortuna;
102 use Crypt::PRNG::RC4;
103 use Crypt::PRNG::Sober128;
104 use Crypt::PRNG::Yarrow;
105 use Crypt::PRNG;
106 use Crypt::Stream::ChaCha;
107 use Crypt::Stream::RC4;
108 use Crypt::Stream::Salsa20;
109 use Crypt::Stream::Sober128;
110 use Crypt::Stream::Sosemanuk;
111 use Crypt::Stream::Rabbit;
112 use CryptX;
113 use Math::BigInt::LTM;
72114
73115 diag( "osname = $Config{osname}" );
74116 diag( "myarchname = $Config{myarchname}" );
22
33 use Test::More;
44
5 plan skip_all => "set TEST_POD to enable this test (developer only!)" unless $ENV{TEST_POD};
56 plan skip_all => "File::Find not installed" unless eval { require File::Find };
67 plan tests => 1;
78
1415
1516 my @err;
1617 my $cryptx = _read("lib/CryptX.pm");
18 my $compile_t = _read("t/001_compile.t");
1719 my @files;
1820 File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib');
1921
2830 $m =~ s|[\\/]|::|g;
2931 $m =~ s|^lib::||;
3032 $m =~ s|\.pm$||;
31 push @err, "ERROR: '$m' is missing in CryptX" unless $cryptx =~ /L<$m>/s || $m =~ /^(CryptX|Math::BigInt::LTM|Crypt::(PK|Mode|Mac|AuthEnc))$/;
33 push @err, "ERROR: '$m' is missing in CryptX.pm" unless $cryptx =~ /L<$m>/s || $m =~ /^(CryptX|Math::BigInt::LTM|Crypt::(PK|Mode|Mac|AuthEnc))$/;
34 push @err, "ERROR: '$m' is missing in 001_compile.t" unless $compile_t =~ /\nuse $m;/s;
3235 eval "use $m; 1;" or push @err, "ERROR: 'use $m' failed";
3336 }
3437
55 plan skip_all => "set TEST_POD to enable this test (developer only!)" unless $ENV{TEST_POD};
66 plan skip_all => "File::Find not installed" unless eval { require File::Find };
77 plan skip_all => "Test::Pod not installed" unless eval { require Test::Pod };
8 plan tests => 102;
8 plan tests => 103;
99
1010 my @files;
1111 File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib');
99 Test::Pod::Spelling->import(
1010 spelling => {
1111 allow_words => [qw(
12 AES BLAKEb BLAKEs CPAN CRC ChaCha CryptX DCIT DER Diffie EAX ECCDH ECDH ECDSA Flickr HKDF JSON JWA JWK
12 ASN AES BLAKEb BLAKEs CPAN CRC ChaCha CryptX DCIT DER Diffie EAX ECCDH ECDH ECDSA Flickr HKDF JSON JWA JWK
1313 Karel Miko OCB OCBv OID OMAC OO OpenSSL PBKDF PEM PKCS RIPEMD Rijndael SHA UUID RFC
1414 decrypt decrypts interoperability cryptographically cryptographic octects
1515 libtomcrypt libtommath
2020 },
2121 );
2222
23 plan tests => 102;
23 plan tests => 103;
2424
2525 my @files;
2626 File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib');
55 plan skip_all => "set TEST_POD to enable this test (developer only!)" unless $ENV{TEST_POD};
66 plan skip_all => "Pod::Coverage not installed" unless eval { require Pod::Coverage };
77 plan skip_all => "File::Find not installed" unless eval { require File::Find };
8 plan tests => 102;
8 plan tests => 103;
99
1010 my @files;
1111 File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib');
00 use strict;
11 use warnings;
22
3 use Test::More tests => 14;
3 use Test::More tests => 20;
44
55 use Crypt::Stream::RC4;
66 use Crypt::Stream::Sober128;
77 use Crypt::Stream::ChaCha;
88 use Crypt::Stream::Salsa20;
9 use Crypt::Stream::Sosemanuk;
10 use Crypt::Stream::Rabbit;
911
1012 {
1113 my $key = pack("H*", "0123456789abcdef");
8385 is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::Sosemanuk decrypt (no IV)");
8486 }
8587
88 {
89 my $key = pack("H*", "74657374206b65792031323862697473");
90 my $iv = pack("H*", "1122334455");
91 my $ct = pack("H*", "91d4ba9044faa26e08db767d34b88d5cf4c884db");
92 my $pt = pack("H*", "0000000000000000000000000000000000000000");
93 my $enc = Crypt::Stream::Rabbit->new($key, $iv)->crypt($pt);
94 my $dec = Crypt::Stream::Rabbit->new($key, $iv)->crypt($ct);
95 is(unpack("H*", $enc), unpack("H*", $ct), "Crypt::Stream::Rabbit encrypt");
96 is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::Rabbit decrypt");
97 }
98 {
99 my $key = pack("H*", "74657374206b65792031323862697473");
100 my $ct = pack("H*", "e8c99affb8ffb7541b6da2e06887994e800b70c9");
101 my $pt = pack("H*", "0000000000000000000000000000000000000000");
102 my $enc = Crypt::Stream::Rabbit->new($key)->crypt($pt);
103 my $dec = Crypt::Stream::Rabbit->new($key)->crypt($ct);
104 is(unpack("H*", $enc), unpack("H*", $ct), "Crypt::Stream::Rabbit encrypt (no IV)");
105 is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::Rabbit decrypt (no IV)");
106 }
107 {
108 my $key = pack("H*", "74657374206b65792031323862697473");
109 my $ct = pack("H*", "442cf424c5da8d78000c6b874050260792ae8ce0");
110 my $pt = pack("H*", "0000000000000000000000000000000000000000");
111 my $enc = Crypt::Stream::Rabbit->new($key, "")->crypt($pt);
112 my $dec = Crypt::Stream::Rabbit->new($key, "")->crypt($ct);
113 is(unpack("H*", $enc), unpack("H*", $ct), "Crypt::Stream::Rabbit encrypt (empty IV)");
114 is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::Rabbit decrypt (empty IV)");
115 }
0 use strict;
1 use warnings;
2
3 use Test::More tests => 3;
4 use Crypt::Stream::Rabbit;
5
6 # https://metacpan.org/source/JCDUQUE/Crypt-Rabbit-1.0.0/t/02.t
7 # https://metacpan.org/source/JCDUQUE/Crypt-Rabbit-1.0.0/t/03.t
8 # https://metacpan.org/source/JCDUQUE/Crypt-Rabbit-1.0.0/t/04.t
9
10 {
11 my $key = pack "H32", 0;
12 my $cipher = Crypt::Stream::Rabbit->new($key);
13 my $ciphertext = pack "H64", "02f74a1c26456bf5ecd6a536f05457b1a78ac689476c697b390c9cc515d8e888";
14 my $plaintext = $cipher->crypt($ciphertext);
15 my $answer = unpack "H*", $plaintext;
16 is($answer, "0000000000000000000000000000000000000000000000000000000000000000");
17 }
18
19 {
20 my $key = pack "H32", "c21fcf3881cd5ee8628accb0a9890df8";
21 my $cipher = Crypt::Stream::Rabbit->new($key);
22 my $plaintext = pack "H64", 0;
23 my $ciphertext = $cipher->crypt($plaintext);
24 my $answer = unpack "H*", $ciphertext;
25 is($answer, "3d02e0c730559112b473b790dee018dfcd6d730ce54e19f0c35ec4790eb6c74a");
26 }
27
28 {
29 my $key = pack "H32", "1d272c6a2d8e3dfcac14056b78d633a0";
30 my $cipher = Crypt::Stream::Rabbit->new($key);
31 my $plaintext = pack "H72", 0;
32 my $ciphertext = $cipher->crypt($plaintext);
33 my $answer = unpack "H*", $ciphertext;
34 is($answer, "a3a97abb80393820b7e50c4abb53823dc4423799c2efc9ffb3a4125f1f4c99a8ae953e56");
35 }
2020 Crypt::Stream::RC4 T_PTROBJ
2121 Crypt::Stream::Sober128 T_PTROBJ
2222 Crypt::Stream::Sosemanuk T_PTROBJ
23 Crypt::Stream::Rabbit T_PTROBJ
2324
2425 Crypt::Mac::F9 T_PTROBJ
2526 Crypt::Mac::HMAC T_PTROBJ