Skip to content

Commit d018866

Browse files
jfougmagnumripper
authored andcommitted
Add support for sha256crypt & sha512crypt
1 parent f351cf8 commit d018866

7 files changed

+3129
-6
lines changed

JtrTestSuite.Manifest

+7-2
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,23 @@
101101
# PO now required a forced test (gost 'grabbed' it ;) )
102102
# Raw SHA1 required a forced test.
103103
# v1.12.2 Fixed sapG and added sapB (per magnum).
104-
# v1.12.3 Added gost, gost_cp, raw-sha1_ng (faster on some cpu's).
104+
# v1.12.3 Added gost, gost_cp, raw-sha1_ng (faster on some cpu's).
105105
# Added some extra test using crc32, for dupe suppression, and for files having
106106
# and lacking
107107
# final EOL in the file.
108-
# Numerous other changes (-enc:utf changed to --encode=utf)
108+
# Numerous other changes (-enc:utf changed to --encode=utf)
109109
# Changed the cut statement in .pot testing, adding the -s to only cut lines
110110
# with a : char.
111111
# v1.12.4 Added a bunch of new formats:
112112
# raw-ssh224, raw-ssh256, raw-sha384, raw-sha512, dragonfly3_32, dragonfly4_32,
113113
# hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, hmac-sha512,
114+
# -w= changed to --wordlist= and -enc:utf8 changed to --encoding=utf8. The
115+
# -w= change trigged a couple of bugs.
116+
# v1.12.5 Added sha256crypt and sha512crypt. Still had one more nit from the change from
117+
# -w= to --wordlist=
114118
# Todo (1.13)
115119
# Add tests for -pipe, files with \r\n \n \r and \r\r\n, which are 'real'
116120
# file formats seen in the wild. These tests are in -w= and -pipe modes
121+
# http://www.openwall.com/lists/john-dev/2012/06/29/39
117122
#--------------------------------------------------------------------
118123

SHA256crypt_tst.in

+1,501
Large diffs are not rendered by default.

SHA512crypt_tst.in

+1,501
Large diffs are not rendered by default.

gen_sha256_crypt.sh

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
./pass_gen.pl -salt=2flEgdKcQYXTiehg -dic=pw.dic -max=31 sha256crypt < pw_30.dic > sha256crypt_tst.in
2+
./pass_gen.pl -salt=Bv4Mw8lZ8kACyewP -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
3+
./pass_gen.pl -salt=Sxu0UG6Uub9lbu47 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
4+
./pass_gen.pl -salt=7VOKL4vqjt6Ntzdx -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
5+
./pass_gen.pl -salt=J90sruJAhwRay2WT -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
6+
./pass_gen.pl -salt=K4nKGE1pVoMfNvup -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
7+
./pass_gen.pl -salt=cvNgIqn2YOYb1z0z -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
8+
./pass_gen.pl -salt=KJvlTmwMpJTxrHpi -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
9+
./pass_gen.pl -salt=FuOtf6eNd7X6WTgX -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
10+
./pass_gen.pl -salt=d4SKkQVoiTYKUQtL -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
11+
./pass_gen.pl -salt=8xI2fjwOSR748L44 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
12+
./pass_gen.pl -salt=t0MxB7Yef4qH35kT -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
13+
./pass_gen.pl -salt=4H9ZUdCa63mCsUTA -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
14+
./pass_gen.pl -salt=G0LEGZGGtISIQEZr -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
15+
./pass_gen.pl -salt=f2vE86lZ21PvotBL -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
16+
./pass_gen.pl -salt=Pf0Gob7luCPHFjaA -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
17+
./pass_gen.pl -salt=vWoUo1Ni44W3uEkc -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
18+
./pass_gen.pl -salt=P7yvcGVUtmJLqhTY -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
19+
./pass_gen.pl -salt=RImp8Vr8TLqdYPJg -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
20+
./pass_gen.pl -salt=3cc2YFoMGqv1fKmu -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
21+
./pass_gen.pl -salt=9cw2nzAD03JjZQJn -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
22+
./pass_gen.pl -salt=1usuVJkCzCyaZT2e -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
23+
./pass_gen.pl -salt=bEu3J9di42nodHRI -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
24+
./pass_gen.pl -salt=o9YJpLcD7d20pBTd -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
25+
./pass_gen.pl -salt=tzVHFCjkKKHgYrV4 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
26+
./pass_gen.pl -salt=es5491eQIqKS5u5e -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
27+
./pass_gen.pl -salt=pPEtawc2ifBcKDlX -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
28+
./pass_gen.pl -salt=ePV/mpD4qfFLCSY/ -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
29+
./pass_gen.pl -salt=vkU6QuGNMA5BVmND -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
30+
./pass_gen.pl -salt=qZzBmtYkCi23AOvO -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
31+
./pass_gen.pl -salt=77ncpZGudoQsrzHB -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
32+
./pass_gen.pl -salt=0W7mogE4SQ9NaGWQ -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
33+
./pass_gen.pl -salt=CMF8M5Ql5Ugnr6AY -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
34+
./pass_gen.pl -salt=ZaxM/oTmsbIepBWu -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
35+
./pass_gen.pl -salt=6RQOmMopstYbDUDt -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
36+
./pass_gen.pl -salt=Shl53frWIwFAobD/ -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
37+
./pass_gen.pl -salt=HCmRbvOIz9VDwOg1 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
38+
./pass_gen.pl -salt=CEaoAl68Mm5cEK.E -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
39+
./pass_gen.pl -salt=tGMaA/swUyRXxS/U -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
40+
./pass_gen.pl -salt=MKSbIQqpnJrYiSp/ -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
41+
./pass_gen.pl -salt=L22tuHelhOpBQ06n -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
42+
./pass_gen.pl -salt=DR0u9HfeJYL3P4r9 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
43+
./pass_gen.pl -salt=1UGAo092e/mU7Bbj -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
44+
./pass_gen.pl -salt=HSlV9IDEhrXgoQpj -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
45+
./pass_gen.pl -salt=abhHF25znGTBgAz3 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
46+
./pass_gen.pl -salt=fkO3a1lrBKysl3Tl -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
47+
./pass_gen.pl -salt=qDUYppIWZccay1Vg -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
48+
./pass_gen.pl -salt=uYFAVDqoTHt8yOsD -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
49+
./pass_gen.pl -salt=dBRZGg1hppmcFSzc -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
50+
./pass_gen.pl -salt=5Tarv2OOayVYSi/R -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
51+
./pass_gen.pl -salt=fuhvG0Ssj3voMDo. -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
52+
./pass_gen.pl -salt=vBGBQOdGHD2jEZxu -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
53+
./pass_gen.pl -salt=CsriPpbGjoKKsE6z -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
54+
./pass_gen.pl -salt=MKSRn8nqPrRO5kR5 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
55+
./pass_gen.pl -salt=jQPS5ptzcLJxf3fP -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
56+
./pass_gen.pl -salt=MRuk6rjcSz1Kmyv7 -nocomment -max=31 sha256crypt < pw_30.dic >> sha256crypt_tst.in
57+

gen_sha512_crypt.sh

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
./pass_gen.pl -salt=2flEgdKcQYXTiehg -dic=pw.dic -max=31 sha512crypt < pw_30.dic > sha512crypt_tst.in
2+
./pass_gen.pl -salt=Bv4Mw8lZ8kACyewP -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
3+
./pass_gen.pl -salt=Sxu0UG6Uub9lbu47 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
4+
./pass_gen.pl -salt=7VOKL4vqjt6Ntzdx -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
5+
./pass_gen.pl -salt=J90sruJAhwRay2WT -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
6+
./pass_gen.pl -salt=K4nKGE1pVoMfNvup -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
7+
./pass_gen.pl -salt=cvNgIqn2YOYb1z0z -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
8+
./pass_gen.pl -salt=KJvlTmwMpJTxrHpi -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
9+
./pass_gen.pl -salt=FuOtf6eNd7X6WTgX -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
10+
./pass_gen.pl -salt=d4SKkQVoiTYKUQtL -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
11+
./pass_gen.pl -salt=8xI2fjwOSR748L44 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
12+
./pass_gen.pl -salt=t0MxB7Yef4qH35kT -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
13+
./pass_gen.pl -salt=4H9ZUdCa63mCsUTA -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
14+
./pass_gen.pl -salt=G0LEGZGGtISIQEZr -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
15+
./pass_gen.pl -salt=f2vE86lZ21PvotBL -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
16+
./pass_gen.pl -salt=Pf0Gob7luCPHFjaA -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
17+
./pass_gen.pl -salt=vWoUo1Ni44W3uEkc -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
18+
./pass_gen.pl -salt=P7yvcGVUtmJLqhTY -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
19+
./pass_gen.pl -salt=RImp8Vr8TLqdYPJg -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
20+
./pass_gen.pl -salt=3cc2YFoMGqv1fKmu -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
21+
./pass_gen.pl -salt=9cw2nzAD03JjZQJn -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
22+
./pass_gen.pl -salt=1usuVJkCzCyaZT2e -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
23+
./pass_gen.pl -salt=bEu3J9di42nodHRI -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
24+
./pass_gen.pl -salt=o9YJpLcD7d20pBTd -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
25+
./pass_gen.pl -salt=tzVHFCjkKKHgYrV4 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
26+
./pass_gen.pl -salt=es5491eQIqKS5u5e -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
27+
./pass_gen.pl -salt=pPEtawc2ifBcKDlX -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
28+
./pass_gen.pl -salt=ePV/mpD4qfFLCSY/ -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
29+
./pass_gen.pl -salt=vkU6QuGNMA5BVmND -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
30+
./pass_gen.pl -salt=qZzBmtYkCi23AOvO -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
31+
./pass_gen.pl -salt=77ncpZGudoQsrzHB -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
32+
./pass_gen.pl -salt=0W7mogE4SQ9NaGWQ -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
33+
./pass_gen.pl -salt=CMF8M5Ql5Ugnr6AY -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
34+
./pass_gen.pl -salt=ZaxM/oTmsbIepBWu -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
35+
./pass_gen.pl -salt=6RQOmMopstYbDUDt -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
36+
./pass_gen.pl -salt=Shl53frWIwFAobD/ -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
37+
./pass_gen.pl -salt=HCmRbvOIz9VDwOg1 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
38+
./pass_gen.pl -salt=CEaoAl68Mm5cEK.E -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
39+
./pass_gen.pl -salt=tGMaA/swUyRXxS/U -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
40+
./pass_gen.pl -salt=MKSbIQqpnJrYiSp/ -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
41+
./pass_gen.pl -salt=L22tuHelhOpBQ06n -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
42+
./pass_gen.pl -salt=DR0u9HfeJYL3P4r9 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
43+
./pass_gen.pl -salt=1UGAo092e/mU7Bbj -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
44+
./pass_gen.pl -salt=HSlV9IDEhrXgoQpj -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
45+
./pass_gen.pl -salt=abhHF25znGTBgAz3 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
46+
./pass_gen.pl -salt=fkO3a1lrBKysl3Tl -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
47+
./pass_gen.pl -salt=qDUYppIWZccay1Vg -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
48+
./pass_gen.pl -salt=uYFAVDqoTHt8yOsD -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
49+
./pass_gen.pl -salt=dBRZGg1hppmcFSzc -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
50+
./pass_gen.pl -salt=5Tarv2OOayVYSi/R -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
51+
./pass_gen.pl -salt=fuhvG0Ssj3voMDo. -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
52+
./pass_gen.pl -salt=vBGBQOdGHD2jEZxu -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
53+
./pass_gen.pl -salt=CsriPpbGjoKKsE6z -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
54+
./pass_gen.pl -salt=MKSRn8nqPrRO5kR5 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
55+
./pass_gen.pl -salt=jQPS5ptzcLJxf3fP -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
56+
./pass_gen.pl -salt=MRuk6rjcSz1Kmyv7 -nocomment -max=31 sha512crypt < pw_30.dic >> sha512crypt_tst.in
57+

jtrts.dat

+3-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
(raw-sha1)(sha)(sha1),(X),(jumbo),10000,rawsha1-ng,pw,rawsha1_tst.in,raw-sha1-ng,Y,X,(1430),(1430)
9696
(sha1-gens)(base)(sha)(sha1),(X),(jumbo),10000,sha1-gens,pw,sha1s_tst.in,sha1-gen,Y,X,(1500),(1500)
9797
(sha1-genp)(base)(sha)(sha1),(X),(jumbo),10000,sha1-genp,pw,sha1p_tst.in,sha1-gen,Y,X,(1500),(1500)
98-
# Data added June 28, 2112
98+
# Data added June 28 2012
9999
(base)(sha)(sha2),(X),(jumbo),10000,raw-sha224,pw,rawsha224_tst.in,raw-sha224,Y,X,(1500),(1500)
100100
(base)(sha)(sha2),(X),(jumbo),10000,raw-sha256,pw,rawsha256_tst.in,raw-sha256,Y,X,(1500),(1500)
101101
(base)(sha)(sha2),(X),(jumbo),10000,raw-sha384,pw,rawsha384_tst.in,raw-sha384,Y,X,(1500),(1500)
@@ -105,6 +105,8 @@
105105
(base)(sha)(sha2),(X),(jumbo),10000,hmac-sha256,pw,hmacSHA256_tst.in,hmac-sha256,Y,X,(1500),(1500)
106106
(base)(sha)(sha2),(X),(jumbo),10000,hmac-sha384,pw,hmacSHA384_tst.in,hmac-sha384,Y,X,(1500),(1500)
107107
(base)(sha)(sha2),(X),(jumbo),10000,hmac-sha512,pw,hmacSHA512_tst.in,hmac-sha512,Y,X,(1500),(1500)
108+
(base)(sha)(sha2),(X),(jumbo),40,sha256crypt,pw,SHA256crypt_tst.in,sha256crypt,Y,X,(1500),(1500)
109+
(base)(sha)(sha2),(X),(jumbo),40,sha512crypt,pw,SHA512crypt_tst.in,sha512crypt,Y,X,(1500),(1500)
108110
#
109111
(base),(X),(jumbo),10000,dragonfly3-32,pw,dragonfly3_32_tst.in,dragonfly3-32,Y,X,(1500),(1500)
110112
(base),(X),(jumbo),10000,dragonfly4-32,pw,dragonfly4_32_tst.in,dragonfly4-32,Y,X,(1500),(1500)

jtrts.pl

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
use Getopt::Long;
44
use jtrts_inc;
55

6-
my $VERSION = "1.12.4";
7-
my $RELEASE_DATE = "June 22, 2012";
6+
my $VERSION = "1.12.5";
7+
my $RELEASE_DATE = "June 29, 2012";
88
# how to do alpha character left, so next 'alpha', or beta release will be easy.
99
#use utf8;
1010
#my $VERSION = "1.10-\x{3B1}2"; # alpha-2
@@ -537,7 +537,7 @@ sub process {
537537
my @lines = <FILE>;
538538
close(FILE);
539539
$dict_name = "--wordlist=$ar[5]-$ar[3].dic";
540-
$dict_name_ex = substr($dict_name,3);
540+
$dict_name_ex = substr($dict_name,11);
541541
open (FILE, ">".substr($dict_name,11));
542542
my $i;
543543
for ($i = 0; $i < $ar[3]; $i += 1) {

0 commit comments

Comments
 (0)