diff options
Diffstat (limited to 'security/nss/tests/cipher')
-rwxr-xr-x | security/nss/tests/cipher/cipher.sh | 140 | ||||
-rw-r--r-- | security/nss/tests/cipher/cipher.txt | 57 | ||||
-rw-r--r-- | security/nss/tests/cipher/dsa.txt | 13 | ||||
-rw-r--r-- | security/nss/tests/cipher/gcm.txt | 16 | ||||
-rw-r--r-- | security/nss/tests/cipher/hash.txt | 11 | ||||
-rwxr-xr-x | security/nss/tests/cipher/performance.sh | 156 | ||||
-rw-r--r-- | security/nss/tests/cipher/rsa.txt | 11 | ||||
-rw-r--r-- | security/nss/tests/cipher/symmkey.txt | 36 |
8 files changed, 440 insertions, 0 deletions
diff --git a/security/nss/tests/cipher/cipher.sh b/security/nss/tests/cipher/cipher.sh new file mode 100755 index 000000000..1d2561d9c --- /dev/null +++ b/security/nss/tests/cipher/cipher.sh @@ -0,0 +1,140 @@ +#! /bin/bash +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +######################################################################## +# +# mozilla/security/nss/tests/cipher/cipher.sh +# +# Script to test NSS ciphers +# +# needs to work on all Unix and Windows platforms +# +# special strings +# --------------- +# FIXME ... known problems, search for this string +# NOTE .... unexpected behavior +# +######################################################################## + +############################## cipher_init ############################# +# local shell function to initialize this script +######################################################################## +cipher_init() +{ + SCRIPTNAME="cipher.sh" + if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for + CLEANUP="${SCRIPTNAME}" # cleaning this script will do it + fi + if [ -z "${INIT_SOURCED}" ] ; then + cd ../common + . ./init.sh + fi + SCRIPTNAME="cipher.sh" + html_head "Cipher Tests" + + CIPHERDIR=${HOSTDIR}/cipher + CIPHERTESTDIR=${QADIR}/../cmd/bltest + GCMTESTDIR=${QADIR}/../cmd/pk11gcmtest + D_CIPHER="Cipher.$version" + + CIPHER_TXT=${QADIR}/cipher/cipher.txt + GCM_TXT=${QADIR}/cipher/gcm.txt + + mkdir -p ${CIPHERDIR} + + cd ${CIPHERDIR} + P_CIPHER=. + if [ -n "${MULTIACCESS_DBM}" ]; then + P_CIPHER="multiaccess:${D_CIPHER}" + fi +} + +############################## cipher_main ############################# +# local shell function to test NSS ciphers +######################################################################## +cipher_main() +{ + while read EXP_RET PARAM TESTNAME + do + if [ -n "$EXP_RET" -a "$EXP_RET" != "#" ] ; then + PARAM=`echo $PARAM | sed -e "s/_-/ -/g"` + TESTNAME=`echo $TESTNAME | sed -e "s/_/ /g"` + echo "$SCRIPTNAME: $TESTNAME --------------------------------" + failedStr="" + inOff=0 + res=0 + while [ $inOff -lt 8 ] + do + outOff=0 + while [ $outOff -lt 8 ] + do + echo "bltest -T -m $PARAM -d $CIPHERTESTDIR -1 $inOff -2 $outOff" + ${PROFTOOL} ${BINDIR}/bltest${PROG_SUFFIX} -T -m $PARAM -d $CIPHERTESTDIR -1 $inOff -2 $outOff + if [ $? -ne 0 ]; then + failedStr="$failedStr[$inOff:$outOff]" + fi + outOff=`expr $outOff + 1` + done + inOff=`expr $inOff + 1` + done + if [ -n "$failedStr" ]; then + html_msg 1 $EXP_RET "$TESTNAME (Failed in/out offset pairs:" \ + " $failedStr)" + else + html_msg $res $EXP_RET "$TESTNAME" + fi + fi + done < ${CIPHER_TXT} +} + +############################## cipher_gcm ############################# +# local shell function to test NSS AES GCM +######################################################################## +cipher_gcm() +{ + while read EXP_RET INPUT_FILE TESTNAME + do + if [ -n "$EXP_RET" -a "$EXP_RET" != "#" ] ; then + TESTNAME=`echo $TESTNAME | sed -e "s/_/ /g"` + echo "$SCRIPTNAME: $TESTNAME --------------------------------" + echo "pk11gcmtest aes kat gcm $GCMTESTDIR/tests/$INPUT_FILE" + ${PROFTOOL} ${BINDIR}/pk11gcmtest aes kat gcm $GCMTESTDIR/tests/$INPUT_FILE + html_msg $? $EXP_RET "$TESTNAME" + fi + done < ${GCM_TXT} +} + +############################## cipher_cleanup ############################ +# local shell function to finish this script (no exit since it might be +# sourced) +######################################################################## +cipher_cleanup() +{ + html "</TABLE><BR>" + cd ${QADIR} + . common/cleanup.sh +} + +################## main ################################################# + +# When building without softoken, bltest isn't built. It was already +# built and the cipher suite run as part of an nss-softoken build. +if [ ! -x ${DIST}/${OBJDIR}/bin/bltest${PROG_SUFFIX} ]; then + echo "bltest not built, skipping this test." >> ${LOGFILE} + res=0 + html_msg $res $EXP_RET "$TESTNAME" + return 0 +fi +cipher_init +# Skip cipher_main if this an NSS without softoken build. +if [ "${NSS_BUILD_WITHOUT_SOFTOKEN}" != "1" ]; then + cipher_main +fi +# Skip cipher_gcm if this is a softoken only build. +if [ "${NSS_BUILD_SOFTOKEN_ONLY}" != "1" ]; then + cipher_gcm +fi +cipher_cleanup diff --git a/security/nss/tests/cipher/cipher.txt b/security/nss/tests/cipher/cipher.txt new file mode 100644 index 000000000..4e47a9f97 --- /dev/null +++ b/security/nss/tests/cipher/cipher.txt @@ -0,0 +1,57 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file defines the cipher tests +# +# expected +# return bltest Test Case name +# value params +# ------- ---------- --------------- + 0 des_ecb_-E DES_ECB_Encrypt + 0 des_ecb_-D DES_ECB_Decrypt + 0 des_cbc_-E DES_CBC_Encrypt + 0 des_cbc_-D DES_CBC_Decrypt + 0 des3_ecb_-E DES3_ECB_Encrypt + 0 des3_ecb_-D DES3_ECB_Decrypt + 0 des3_cbc_-E DES3_CBC_Encrypt + 0 des3_cbc_-D DES3_CBC_Decrypt + 0 aes_ecb_-E AES_ECB_Encrypt + 0 aes_ecb_-D AES_ECB_Decrypt + 0 aes_cbc_-E AES_CBC_Encrypt + 0 aes_cbc_-D AES_CBC_Decrypt + 0 aes_ctr AES_CTR + 0 aes_cts AES_CTS + 0 aes_gcm AES_GCM + 0 camellia_ecb_-E Camellia_ECB_Encrypt + 0 camellia_ecb_-D Camellia_ECB_Decrypt + 0 camellia_cbc_-E Camellia_CBC_Encrypt + 0 camellia_cbc_-D Camellia_CBC_Decrypt + 0 seed_ecb_-E SEED_ECB_Encrypt + 0 seed_ecb_-D SEED_ECB_Decrypt + 0 seed_cbc_-E SEED_CBC_Encrypt + 0 seed_cbc_-D SEED_CBC_Decrypt + 0 chacha20_poly1305_-E ChaCha20_Poly1305_Encrypt + 0 chacha20_poly1305_-D ChaCha20_Poly1305_Decrypt + 0 rc2_ecb_-E RC2_ECB_Encrypt + 0 rc2_ecb_-D RC2_ECB_Decrypt + 0 rc2_cbc_-E RC2_CBC_Encrypt + 0 rc2_cbc_-D RC2_CBC_Decrypt + 0 rc4_-E RC4_Encrypt + 0 rc4_-D RC4_Decrypt + 0 rsa_-E RSA_Encrypt + 0 rsa_-D RSA_Decrypt + 0 rsa_oaep_-E RSA_EncryptOAEP + 0 rsa_oaep_-D RSA_DecryptOAEP + 0 rsa_pss_-S RSA_SignPSS + 0 rsa_pss_-V RSA_CheckSignPSS + 0 rsa_-K RSA_Populate + 0 dsa_-S DSA_Sign + 0 dsa_-V DSA_Verify + 0 md2_-H MD2_Hash + 0 md5_-H MD5_Hash + 0 sha1_-H SHA1_Hash + 0 sha224_-H SHA224_Hash + 0 sha256_-H SHA256_Hash + 0 sha384_-H SHA384_Hash + 0 sha512_-H SHA512_Hash diff --git a/security/nss/tests/cipher/dsa.txt b/security/nss/tests/cipher/dsa.txt new file mode 100644 index 000000000..f2d3401f4 --- /dev/null +++ b/security/nss/tests/cipher/dsa.txt @@ -0,0 +1,13 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file enables test coverage of the dsa performance tests +# +# +# mode keysize bufsize repetitions cxrepetitions + dsa 64 20 200 5 + dsa 96 20 200 3 + dsa 128 20 200 3 + dsa 256 20 200 3 + dsa 384 20 200 3 diff --git a/security/nss/tests/cipher/gcm.txt b/security/nss/tests/cipher/gcm.txt new file mode 100644 index 000000000..4550faf49 --- /dev/null +++ b/security/nss/tests/cipher/gcm.txt @@ -0,0 +1,16 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file defines the AES GCM tests +# +# expected +# return pk11gcmtest Test Case name +# value input file +# ------- ---------------------- ----------------------- + 0 gcmDecrypt128.rsp NIST_AES128_GCM_Decrypt + 0 gcmDecrypt192.rsp NIST_AES192_GCM_Decrypt + 0 gcmDecrypt256.rsp NIST_AES256_GCM_Decrypt + 0 gcmEncryptExtIV128.rsp NIST_AES128_GCM_Encrypt + 0 gcmEncryptExtIV192.rsp NIST_AES192_GCM_Encrypt + 0 gcmEncryptExtIV256.rsp NIST_AES256_GCM_Encrypt diff --git a/security/nss/tests/cipher/hash.txt b/security/nss/tests/cipher/hash.txt new file mode 100644 index 000000000..9bee5ba11 --- /dev/null +++ b/security/nss/tests/cipher/hash.txt @@ -0,0 +1,11 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file enables test coverage of the cryptographic hash performance tests +# +# +# mode bufsize repetitions + md2 10240 5000 + md5 10240 100000 + sha1 10240 100000 diff --git a/security/nss/tests/cipher/performance.sh b/security/nss/tests/cipher/performance.sh new file mode 100755 index 000000000..dd7c74ee2 --- /dev/null +++ b/security/nss/tests/cipher/performance.sh @@ -0,0 +1,156 @@ +#!/bin/sh +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This is just a quick script so we can still run our testcases. +# Longer term we need a scriptable test environment.. +# +. ../common/init.sh +CURDIR=`pwd` +if [ "${OS_ARCH}" = "WINNT" -a "$OS_NAME" = "CYGWIN_NT" ]; then + CURDIR=`cygpath -m ${CURDIR}` +fi + +CIPHERDIR=${HOSTDIR}/cipher +SKTESTS=${CURDIR}/symmkey.txt +RSATESTS=${CURDIR}/rsa.txt +DSATESTS=${CURDIR}/dsa.txt +HASHTESTS=${CURDIR}/hash.txt +SKPERFOUT=${CIPHERDIR}/skperfout.data +RSAPERFOUT=${CIPHERDIR}/rsaperfout.data +DSAPERFOUT=${CIPHERDIR}/dsaperfout.data +HASHPERFOUT=${CIPHERDIR}/hashperfout.data +PERFRESULTS=${HOSTDIR}/performance.html + +echo "<HTML><BODY>" >> ${PERFRESULTS} + +mkdir -p ${CIPHERDIR} +cd ${CIPHERDIR} + +if [ -z $1 ]; then + TESTSET="all" +else + TESTSET=$1 +fi + +if [ $TESTSET = "all" -o $TESTSET = "symmkey" ]; then +echo "<TABLE BORDER=1><TR><TH COLSPAN=6>Symmetric Key Cipher Performance</TH></TR>" >> ${PERFRESULTS} +echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>SYMMETRIC KEY SIZE (bits)</TH><TH>REPETITIONS (cx/op)</TH><TH>CONTEXT CREATION TIME (ms)</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS} + +while read mode keysize bufsize reps cxreps +do + if [ $mode != "#" ]; then + echo "bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps" + ${BINDIR}/bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps >> ${SKPERFOUT} + mv "tmp.in.0" "$mode.in" + mv tmp.key $mode.key + if [ -f tmp.iv ]; then + mv tmp.iv $mode.iv + fi + echo "bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.out" + ${BINDIR}/bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.out >> ${SKPERFOUT} + echo "bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.inv" + ${BINDIR}/bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.inv >> ${SKPERFOUT} + fi +done < ${SKTESTS} + +while read md buf sk rps cxrps cx op +do + if [ $md != "#" ]; then + echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$sk</TD><TD align=right>$cxrps/$rps</TD><TD align=right>$cx</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS} + fi +done < ${SKPERFOUT} + +echo "</TABLE><BR>" >> ${PERFRESULTS} + +fi + +if [ $TESTSET = "all" -o $TESTSET = "rsa" ]; then +while read mode keysize bufsize exp reps cxreps +do + if [ $mode != "#" ]; then + echo "bltest -N -m $mode -b $bufsize -e $exp -g $keysize -u $cxreps" + ${BINDIR}/bltest -N -m $mode -b $bufsize -e $exp -g $keysize -u $cxreps >> ${RSAPERFOUT} + mv "tmp.in.0" "$mode.in" + mv tmp.key $mode.key + echo "bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out" + ${BINDIR}/bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out >> ${RSAPERFOUT} + echo "bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.inv" + ${BINDIR}/bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.inv >> ${RSAPERFOUT} + fi +done < ${RSATESTS} + +echo "<TABLE BORDER=1><TR><TH COLSPAN=7>RSA Cipher Performance</TH></TR>" >> ${PERFRESULTS} +echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>KEY SIZE (bits)</TH><TH>PUBLIC EXPONENT</TH><TH>REPETITIONS (cx/op)</TH><TH>CONTEXT CREATION TIME (ms)</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS} + +while read md buf mod pe rps cxrps cx op +do + if [ $md != "#" ]; then + echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$mod</TD><TD align=right>$pe</TD><TD align=right>$cxrps/$rps</TD><TD align=right>$cx</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS} + fi +done < ${RSAPERFOUT} + +echo "</TABLE><BR>" >> ${PERFRESULTS} +fi + +if [ $TESTSET = "all" -o $TESTSET = "dsa" ]; then + +while read mode keysize bufsize reps cxreps +do + if [ $mode != "#" ]; then + echo "bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps" + ${BINDIR}/bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps >> ${DSAPERFOUT} + mv "tmp.in.0" "$mode.in" + mv tmp.key $mode.key + rm -f $mode.out + echo "bltest -S -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out" + ${BINDIR}/bltest -S -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out >> ${DSAPERFOUT} + echo "bltest -V -m $mode -f ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -i ${CIPHERDIR}/$mode.in -o ${CIPHERDIR}/$mode.out" + ${BINDIR}/bltest -V -m $mode -f ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -i ${CIPHERDIR}/$mode.in -o ${CIPHERDIR}/$mode.out >> ${DSAPERFOUT} + fi +done < ${DSATESTS} + +echo "<TABLE BORDER=1><TR><TH COLSPAN=6>DSA Cipher Performance</TH></TR>" >> ${PERFRESULTS} +echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>KEY SIZE (bits)</TH><TH>REPETITIONS (cx/op)</TH><TH>CONTEXT CREATION TIME (ms)</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS} + +while read md buf mod rps cxrps cx op +do + if [ $md != "#" ]; then + echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$mod</TD><TD align=right>$cxrps/$rps</TD><TD align=right>$cx</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS} + fi +done < ${DSAPERFOUT} + +echo "</TABLE><BR>" >> ${PERFRESULTS} +fi + +if [ $TESTSET = "all" -o $TESTSET = "hash" ]; then +while read mode bufsize reps +do + if [ $mode != "#" ]; then + echo "bltest -N -m $mode -b $bufsize" + ${BINDIR}/bltest -N -m $mode -b $bufsize + mv "tmp.in.0" "$mode.in" + echo "bltest -H -m $mode -i ${CIPHERDIR}/$mode.in -p $reps -o ${CIPHERDIR}/$mode.out" + ${BINDIR}/bltest -H -m $mode -i ${CIPHERDIR}/$mode.in -p $reps -o ${CIPHERDIR}/$mode.out >> ${HASHPERFOUT} + fi +done < ${HASHTESTS} + +echo "<TABLE BORDER=1><TR><TH COLSPAN=6>Hash Cipher Performance</TH></TR>" >> ${PERFRESULTS} +echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>REPETITIONS</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS} + +while read md buf rps cxrps cx op +do + if [ $md != "#" ]; then + echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$rps</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS} + fi +done < ${HASHPERFOUT} + +echo "</TABLE><BR>" >> ${PERFRESULTS} +fi + +#rm -f ${TEMPFILES} +cd ${CURDIR} + +echo "</BODY></HTML>" >> ${PERFRESULTS} diff --git a/security/nss/tests/cipher/rsa.txt b/security/nss/tests/cipher/rsa.txt new file mode 100644 index 000000000..aad71261b --- /dev/null +++ b/security/nss/tests/cipher/rsa.txt @@ -0,0 +1,11 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file enables test coverage of the rsa performance tests +# +# +# mode keysize bufsize exponent repetitions cxrepetitions + rsa 32 32 17 1000 5 + rsa 64 64 3 500 3 + rsa 128 128 65537 200 3 diff --git a/security/nss/tests/cipher/symmkey.txt b/security/nss/tests/cipher/symmkey.txt new file mode 100644 index 000000000..ad4b11ab4 --- /dev/null +++ b/security/nss/tests/cipher/symmkey.txt @@ -0,0 +1,36 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file enables test coverage of the symmetric key performance tests +# +# +# mode keysize bufsize repetitions cxrepetitions + des_ecb 8 8192 1000 100000 + des_cbc 8 8192 1000 100000 + des3_ecb 24 8192 1000 100000 + des3_cbc 24 8192 1000 100000 + rc2_ecb 5 8192 1000 100000 + rc2_ecb 8 8192 1000 100000 + rc2_ecb 16 8192 1000 100000 + rc2_cbc 5 8192 1000 100000 + rc2_cbc 8 8192 1000 100000 + rc2_cbc 16 8192 1000 100000 + rc4 5 8192 10000 100000 + rc4 8 8192 10000 100000 + rc4 16 8192 10000 100000 + rc4 24 8192 10000 100000 + aes_ecb 16 8192 10000 100000 + aes_cbc 16 8192 10000 100000 + aes_ecb 32 8192 10000 100000 + aes_cbc 32 8192 10000 100000 + aes_ctr 16 8192 10000 100000 + aes_ctr 32 8192 10000 100000 + aes_gcm 16 8192 10000 100000 + aes_gcm 32 8192 10000 100000 + camellia_ecb 16 8192 10000 100000 + camellia_cbc 16 8192 10000 100000 + camellia_ecb 32 8192 10000 100000 + camellia_cbc 32 8192 10000 100000 + seed_ecb 16 8192 10000 100000 + seed_cbc 16 8192 10000 100000 |