Verifying DVDs

From RCS Wiki
Jump to navigation Jump to search

Verification of Recovery and Software DVDs

Raptor Computing Systems signs their source DVD images with a publicly available Firmware Signing GPG key. Verification of DVD contents is strongly recommended to ensure you have received an authentic copy of the software and information contained thereon. Shipments of the Talos II systems include both the source DVD and a letter with a QR Code containing the 40-character PGP Key Fingerprint of the firmware signing key, and a link to where the detached digital signature can be found.

Digital signatures offer sender authentication (a guarantee of who sent the message) as well as provide message integrity (a guarantee that the message has not been altered since the sender authorized it), on one crucial, pivotal condition: that the key itself can be verified to actually belong to who it purports to belong to. If this condition is not met, an adversary could simply change the keys and replace the signatures on a counterfeit disk with one of their own, then impersonate the sender to recipient or vice-versa.

PGP was originally designed with the implicit assumption that the sender and recipient would either be able to meet each other in person to determine the validity of their keys, or would know "trusted introducers" that they believed to be trustworthy that could do so on their behalf through the use of the PGP "Web Of Trust". This "Web Of Trust" model is impractical when the sender and recipient do not know each other and are not in a position where they could meet in person or have any trusted friends in common.

As an alternative to this, Raptor has included a letter marked "Important Information" that is included with all Talos IIs. This letter contains a QR code which encodes the PGP key fingerprint of the key used to sign the firmware. The QR code is marked with Raptor Computing System's logo and should be on the opposite side of the letter. When scanned with any QR Code reading application, it will contain the 40-character plain text hexadecimal SHA-1 fingerprint used to uniquely prove the key's uniqueness. Please note that this format is not compatible with Android OpenKeyChain's "Scan From QR Code" function, and simply gives the raw 40-character fingerprint without spaces or comma separation.

This forms something of a chain of trust that looks like the following:

  • You and the message you wish to verify, in this case Raptor's DVD;
  • Genuineness of the message attested by the Digital Signature;
  • Production of the Digital Signature using the Firmware Signing Key or by a Sales Key;
  • Validation of the Firmware Signing Key by the Umbrella Signing Key;
  • Security of where the Secret Key for Raptor's Umbrella Signing Key and cryptographic materials are stored.
  • Verification of the Hash of the Signing Key via the QR Code included in Raptor's "Important Information" Letter.

The theory behind this chain of trust is simple: Raptor is a large company and may require many different keys to be used for different reasons and different jobs. Rather than needing to verify many different keys out of band for everything manually, instead Raptor can generate one key that represents them, and digitally certifies all the keys that they use, then keep that one special umbrella signing key in an ultra-secure place. Users that wish to verify that a key really does belong to Raptor then only need to verify that one key at the end of the chain of trust, and if they trust it, all the keys that it validates may be assumed to actually belong to Raptor. This approach provides separation of duties by keeping different keys for different jobs, some amount of convenience by ensuring users only need to verify one key, and ensures that the Umbrella Key does not need to be entrusted to many different people. In turn, keeping the number of people who need to be trusted with the key reduces the likelihood that someone may mishandle it and allow it to leak. As a side-benefit, in the event that one of the keys it certified is stolen, Raptor can simply use the Umbrella key to revoke its certification to inform other people that the key has been compromised and is no longer valid, without having to start over from scratch with entirely new credentials and force everyone to go through the entire exercise of verifying all of the keys all again.

The detached digital signature files produced by the signing keys are available on Raptor's Website. Copies of the public keys may then be obtained from an untrusted source, such as via the outside, untrusted internet, as long as the Key Fingerprint matches and the package has not been disturbed or surreptitiously modified while in transit.

The Process Explained

What we will do:

  • We will first copy the CD image to someplace on your drive on your secure, trustworthy computer. Because signing and verification only works if the copying is exact, we will use the Unix utility "data definition" to do it after finding out the information on the image.
  • Once the drive is copied, we will scan the letter for its QR codes to obtain the PGP Key Fingerprints for the respective keys and copy them down.
  • With the PGP key fingerprints scanned, we will then retrieve the keys from Raptor's website or from a PGP Public Key server of our choice via the Internet.
  • We will then validate the Chain of Trust (see: Chain Of Trust, Section 2) to ensure that the key is genuine and valid, and opt to trust the key.
  • Once the chain of trust is valid, we will verify the digital signature on the CD image. If GnuPG verifies that the signature is valid and from a trusted key, we can be reasonably confident that Raptor authorized the sending of the CD image, and it has not been modified since.

In order to do it, you will need the following tools:

  • The isoinfo software package. This is a handy little utility which will print the image about a CD you will need to properly copy the disk in a condition where it will be in the exact condition that it was burned. isoinfo is included in the package manager of most Linux distributions.
  • The curl software application is highly recommended, but not essential. This utility is used to retrieve files from the Internet,
  • GnuPG, which is usually invoked from the commandline with the command gpg. By default, almost every Linux distribution should have GnuPG which provides the necessary functions for maintaining the PGP Public Key Infrastructure.
  • The letter marked "Important Information" that came in the box with your Talos II. This should have three QR codes on it, one at the front, and two at the back.
  • A computer system that you can trust to verify the integrity of the Talos. This could range from a simple computer that you believe to be reasonably trustworthy, an X60 Thinkpad Laptop from 2005 running coreboot or an X200 Laptop running Libreboot, another Talos II, or an elabourate setup consisting of multiple trustworthy computers that are physically separate from each other, including one which may have been purchased from a randomly selected brick-and-mortar store anonymously, paid in cash, running its operating system from a LiveCD verified on multiple different computers and never connected to any network to perform the verification nor used prior to this point.
  • An Internet connection.
  • A device that is capable of scanning QR codes that you trust. This could be an old Samsung Galaxy S2 running Replicant that has had cellular and wifi antennas physically removed from the phone to prevent compromise of the phone's baseband.

More information on GnuPG is available at the GnuPG Project Manual[1].

The Steps Detailed

Deterministic Copying Of The Disk

When the cd image was signed by Raptor, it was signed in a specific condition. You will need to reproduce this condition exactly right down to the last bit, or the verification will fail and produce a "Bad Signature" error. To do so, we will first need to obtain the information about the drive to supply the right parameters to copy the drive.

Heads-up! If you get an error that says isoinfo: command not found then the correct package has not been installed on your system. If you do not have it, on Debian-based systems such as Ubuntu or Linux Mint, you may obtain them with the command sudo apt install genisoimage which should automatically download and install isoinfo and its dependencies on your system.

This tutorial assumes that your cd rom device entry is listed as /dev/cdrom. However, some systems may not have the symbolic link of /dev/cdrom to /dev/sr0. You may check to see which device entry your DVD or BD ROM is by inserting the disk, and typing without any other arguments mount | grep udf which will display all the device entries associated with handling the currently inserted disks. The device entry will be the first entry listed, for example:

user@computer:~$ mount | grep udf
/dev/sr0 on /media/cdrom0 type udf 

In this tutorial, we will use /dev/sr0.

We will be looking for two specific items here: Logical Block Size, and Volume Size, which will become parameters will then pass on to Data Definition. To make this easier for the end user, we can use grep to search through the entire output text and only print the information we want with the following command This should return two lines, one number representing logical block size, and the other number representing the volume block size.

user@computer:~$ isoinfo -d -i /dev/sr0 | grep -E 'Logical block size|Volume size'
Logical block size is: 2048
Volume size is: 4135453

Alternatively, you can use the command isosize:

user@computer:~$ isosize -x /dev/sr0
sector count: 4135453, sector size: 2048

STOP! Do not simply enter the values obtained on the Wiki blindly. The values for Logical Block Size and Volume size shown here are listed as being for example only, and may change depending on which version of the disk you were supplied with. Always double check your command syntax prior to entering it. Each person's system will be slightly different, so ensure you do what is right for your system, not just what is listed on the wiki page.

With this information now known, we will now begin deterministing copying of the CD via the data definition (or define data) tool, dd. dd is a utility that has been a part of all Unix-like operating systems since approximately 1985. dd mainly utilizes two parameters, the input file, which is specified by "if", and the output file specified by "of", and will bitwise copy from the input file to the output file, along with any parameters we want to set, such as the block size, and the volume size. We will then set the parameters as such:

  • Input file, or if= The input file should be the device entry for your CD ROM, which we obtained earlier by searching for the mounted media of the type "udf". In our example, we are using /dev/sr0
  • Output file, or of= The output file is the clone we will copy to the disk to verify. Here, we will put it in your home directory, with the filename "raptordisk.iso" or the absolute filename "~/raptordisk.iso"
  • Block Size or bs= The block size will be the number indicated by "Logical block size" as given by isoinfo.
  • Volume Size, or count=The volume size is the exact size of the entire volume, in the number of blocks.

For our example, our command syntax will be the following. To include a progress meter, simply include "status=progress" to let the computer know you wish to view the progress of the copy being made in real time. This will produce an exact clone of the disk to your home directory under the name "raptordisk.iso".

dd if="/dev/sr0" of="~/raptordisk.iso" count=4135453 bs=2048 status=progress

STOP! dd is a powerful tool intended for low-level, bitwise copying of the actual ones and zeroes on the disk or media. The dd command is intended to restore backups and make exact clones of data, but can also be repurposed for secure erasure of hard drives. With great power comes great responsibility: ensure that the input file and output file denoted by if= and of= respectively are the files you really want to write. Never specify an output file to one you do not intend to overwrite!

If all has been done correctly, this will procedure should create a bit-wise (exact) clone of the disk image in your home directory, which will be called "raptordisk.iso." We will verify this clone shortly.

Obtaining and Trusting the Umbrella Signer Public Key

To obtain the Umbrella Signing Public Key, you may use the url included on the letter, which is also given as a QR-code that may be scanned by any QR-code reading software or by visiting the url below it. Although the download is made over Transport Layer Security (or SSL), the key should first be verified locally on your computer against the 40-character fingerprint obtained by scanning the QR code in the letter. To do this, we will check the key fingerprint of the key we receive

The public key will be available in ascii-armoured format and will be marked to note where the public key begins and ends. If your browser does not automatically download it, you may copy the page to your hard drive using wget or curl, and pass it to GnuPG with the following terminal command sequence. Note that if the url you receive on your letter is different from the one you see here, take the one on the letter to be correct.

If you do not have curl, you may install it using the command sudo apt install -y curl .

 user@computer:~$ curl | gpg --import 

You may see a screen that resembles something like this. (Please note that in this manual entry, the key fingerprint itself has been obscured to prevent confusion)

pub  rsa4096/████████████  created: 2018-04-16  expires: never
      Key fingerprint = ████ ████ ████ ████ ████  ████ ████ ████ ████ ████

     Raptor Computing Systems Primary Signer (Umbrella Signer) <>

Do you want to import this key? (y/N)

Compare this result displayed on your computer to the 40-character key fingerprint you obtained from scanning the QR-Code reader. It must match exactly to avoid obtaining a counterfeit key. If the 40-character key fingerprint matches exactly, you can sign it locally with one of your own keys, or you can take ownership of the key by setting its trust to ultimate.

If you miss this information the first time around, you may view it again with the command:

 user@computer:~$ gpg -k --with-fingerprint

First, we will edit the key with:

Heads Up! This tutorial assumes you have no ultimately trusted keys in your GnuPG trust database. The "Ultimate" trust level in GnuPG is intended for keys you own, and is required to validate other keys. Setting ultimate trust for a key you do not own is normally a very harmful use case, as an ultimately trusted key that you do not own can be used to issue counterfeit keys for your contacts and impersonate your contacts to you unless you decide to stop trusting it. After the key is no longer needed to be trusted, you should un-set its trust from Ultimate. You can avoid using these issues by locally signing Raptor's Umbrella key with an ultimately trusted key that you own using gpg --lsign-key.

 user@computer:~$ gpg --edit-key 0x337BF51F

This will bring us to the gpg> key editing dialogue.

pub  rsa4096/9B2BF5BD337BF51F
     created: 2018-04-16  expires: never       usage: SC  
     trust: unknown       validity: unknown
sub  rsa4096/366FA0E6B8EE80D8
     created: 2018-04-16  expires: never       usage: E   
[ unknown] (1). Raptor Computing Systems Primary Signer (Umbrella Signer) <>


At the prompt, type trust and press return to bring up the trust dialogue, allowing you to tell the computer how much you trust the user of this key to cryptographically attest to the validity of other keys.

gpg> trust

This will return the trust dialogue. If we do not have a key of our own to validate to its ownership, we will need to take ownership of it ourselves and pretend it is ours for the moment by setting it to ultimate trust.

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 

Enter 5 for ultimate and press return.

Please note that the shown key validity is not necessarily correct
unless you restart the program.


Type quit and press return, which should send you back to your terminal shell. We can verify that the command worked using gpg -k --with-fingerprint to check.

pub   rsa4096/9B2BF5BD337BF51F 2018-04-16 [SC]
      Key fingerprint = 9C2A 6E8F AEA7 EE92 1EFD  4891 9B2B F5BD 337B F51F
uid                 [ultimate] Raptor Computing Systems Primary Signer (Umbrella Signer) <>
sub   rsa4096/366FA0E6B8EE80D8 2018-04-16 [E]
      Key fingerprint = 83DA 26B4 FAC2 2215 832B  8894 366F A0E6 B8EE 80D8

Notice next to UID, the [ unknown] marker has been replaced to [ultimate]. The computer now trusts this key and its owner to be valid to the point where it will consider any keys that this key has certified to be fully valid as being verified to belong to who they really say they belong to, as long as this key itself is.

Retrieving the Detached Digital Signature

Retrieving the detached digital signature is simple, by either visiting the url shown below the QR code on the front of the Important Information letter, or by simply using curl to retrieve the detached digital signature file in the same manner the public key was retrieved. The command to do so should be similar to the following. Note that the version number of the command has been obscured. To determine the version of your recovery disk, look at the url on the letter.

 user@computer:~$ curl████.iso.asc

This should download the detached signature file to your computer.

Retrieving The Firmware Signing Key

The digital signature file and the Root Umbrella key however are not everything we need to verify the integrity of the disk. Attempting to verify the disk (more on that later) will yield the following error:

gpg: Signature made Tue 19 Jun 2018 06:05:04 PM EDT
gpg:                using RSA key 101A7EF8EF283DDC
gpg: key 101A7EF8EF283DDC: 1 signature not checked due to a missing key

This error message is simple: the signature was generated by an RSA key with the particular long key ID shown, but you do not have that public key in your keyring to verify the signature with. Two options present themselves:

  • If you have GnuPG configured to connect to the internet, you may get GnuPG to automatically connect to the Internet and fetch the missing key with the command below. If done without the aid of anonymizing proxy such as Tor, this approach may leak your IP address and your key request to the key server and possibly the rest of the Internet.
user@computer:~$ gpg --recv-keys 101A7EF8EF283DDC
  • If you do not have GnuPG configured for automatic key retrieval, you can go onto the PGP Key Server pool, such as to and seach via the web user interface by searching for the Long Key ID, copy the text of the key beginning with -----BEGIN PGP PUBLIC KEY BLOCK----- and ending with -----END PGP PUBLIC KEY BLOCK----- into a text file, and import it into your GPG keyring with gpg --import [path to file].
  • If you use a graphical frontend such as Gnu Privacy Assistant or Enigmail on your computer to manage keys, you may copy the keys from the clipboard.

After the key is imported, you may see a screen similar to this:

gpg: key 101A7EF8EF283DDC: public key "Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   9  signed:   5  trust: 0-, 0q, 0n, 0m, 0f, 9u
gpg: depth: 1  valid:   5  signed:   0  trust: 5-, 0q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2018-09-09

We may then check its validity. If all has gone right, since we chose to trust Raptor's Umbrella signing key "ultimately," should this be the real key, this key will immediately become fully valid thanks to Raptor's digital signature on it. We then check may the command with gpg -k EF283DDC --with-fingerprint and look for the trust level which should be indicated next to the symbol "uid".

user@computer:~$ gpg -k EF283DDC --with-fingerprint
pub   rsa4096/101A7EF8EF283DDC 2018-04-25 [SC] [expires: 2019-01-20]
      Key fingerprint = D7E9 CE35 33F1 938C 6F8E  F5FD 101A 7EF8 EF28 3DDC
uid                 [  full  ] Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>
sub   rsa4096/CE591B3C94F3C9EE 2018-04-25 [E] [expires: 2019-01-20]

Note that it says [ full ] next to the User ID. This indicates that the computer has found the keys as being authentic, as it has verified the chain of trust back to an ultimately trusted key that in the previous steps, we verified to be provably unique and identitical to the one listed on Raptor's letter. Because of this, the computer now considers the firmware signing key to be fully valid. We may now attempt to verify the DVD image with GnuPG.

WARNING! If the text in the brackets lists anything aside from [ full ], STOP IMMEDIATELY as the key has not validated. A failure for the key to validate may signify something benign, such as either obtaining the wrong key, or worse, a counterfeit. Note that Raptor maintains several keys: some are used for different projects, some are used for customer correspondence, and some are used for signing their Warrant Canary, all of which should be signed by the Umbrella Signer. Ensure you have gotten the one that is used for signing the firmware.

Verifying The Disk

With the chain of trust intact and the detached digital signature and a bitwise copy of the disk image, you may now verify the digital signature on the recovery and firmware disk. This tutorial assumes that you have saved both the recovery disk and detached digital signature file into your home directory, and named the image of the disk "raptordisk.iso" and the detached signature file "talos_recovery_disk_v████.iso.asc"

The command syntax to verify a detached signature file is: gpg --verify [path-to-signature-file] [path-to-file-being-verified]. For the purpose of this tutorial, the command is shown below with the version numbers hidden. Since the disk image itself will be as large as the recovery disk is (approximately 8.5GB) this command may take several minutes to complete, and will not display a progress indicator during this time.

 user@computer:~$ gpg --verify talos_recovery_disk_v████.iso.asc raptordisk.iso
gpg: Signature made Tue 19 Jun 2018 06:05:04 PM EDT
gpg:                using RSA key 101A7EF8EF283DDC
gpg: Good signature from "Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>" [full]
Primary key fingerprint: D7E9 CE35 33F1 938C 6F8E  F5FD 101A 7EF8 EF28 3DDC

If you see Good Signature, congratulations. The chain of trust has been verified to an ultimately trusted key, which has been compared to a tracked and insured letter directly from Raptor. You may wish to further check the validity of the key in other ways, including asking other people you know and trust over an end-to-end authenticated and secure channel to attest to the key fingerprint of the Umbrella Signing Key. Your disk is verified to have come from Raptor, and not been modified since.


If you get a Bad Signature warning, this may signify that the disk is no longer in the original condition that Raptor sent it in (and could represent the work of tampering or damage) or may be resultant of much more benign causes, such as selecting the wrong file for validation, or that the disk was not copied properly (a single flipped or extra bit will cause the validation to fail). If you get a Bad Signature error, ensure you have checked the commands properly and copied the disk properly using dd with the exact bit size and count according to the disk properties. This is the most common cause of false positives.

Prior to sounding an alarm, ensure the following conditions are met:

  • You have obtained the correct bit size for the disk and that the disk was copied with the correct bit size and count.
  • You have obtained the Firmware signing key, instead of a correspondence key or Canary signing key.
  • That the digital signature file is correct to the version of the disk you were supplied with. (Check the letter to be sure)
  • That the full 40-character fingerprint matches the one obtained.
  • The chain of trust is valid. Only the Umbrella signing key needs to be verified via the QR Code. All keys underneath it should validate automatically from being certified by the Umbrella key.

If you continue to experience issues, contact the IRC channel on Freenode. The name of the IRC channel on the Freenode IRC network is listed on the bottom of the letter. As Freenode has been under attack by spam lately, you may be required to register a your nickname on Freenode as a part of an antispam measure utilizing an E-mail address.

Quick Verification Guide for Advanced Users

This section contains a quick reference guide for the commands, and omits the rationale and theory.

Please note that this section is in progress and is incomplete.

Once created, you may verify the ISO with GPG:

gpg --verify <GPG signature file> source.iso

Verify Without Saving ISO:

gpg --verify talos_recovery_disk_v1.0x.iso.asc <(dd if=/dev/cdrom bs=<block size> count=<volume size>)


gpg --verify talos_recovery_disk_v1.02.iso.asc <(dd if=/dev/cdrom bs=2048 count=3861982)

Umbrella Key Fingerprint

Raptor Computing Systems Primary Signer (Umbrella Signer) <>
Fingerprint (9C2A 6E8F AEA7 EE92 1EFD 4891 9B2B F5BD 337B F51F)
(Verify this fingerprint matches multiple independent sources.)

Additional information on validating public keys:
The GNU Privacy Handbook: Validating other keys on your public keyring

How To

Get Block and Logical Volume Sizes (Needed Later)

isoinfo -d -i /dev/sr0 | grep -E 'Logical block size|Volume size'

Logical block size is: 2048
Volume size is: 3871504

Save ISO File (Optional)

dd if="/dev/sr0" of="source.iso" count=<volume size> bs=<block size>
dd if="/dev/sr0" of="source.iso" count=3871504 bs=2048

Download Signature File:

In this example we will be verifying a v1.03 disc.
Details may vary for other versions/keys, but they all should lead back to the Raptor Umbrella Signer.

Verifying ISO Signature:

Verifying ISO file:

gpg --verify talos_recover_disk_v.103.iso.asc source.iso

Verify without saving ISO (Optional):

gpg --verify talos_recovery_disk_v1.03.iso.asc <(dd if=/dev/cdrom bs=<block size> count=<volume size>)
gpg --verify talos_recovery_disk_v1.03.iso.asc <(dd if=/dev/cdrom bs=<2048> count=<3871504>)
If you see this, import the public key and verify again:
    gpg: Signature made Mon 30 Apr 2018 04:44:08 PM MDT
    gpg: using RSA key 101A7EF8EF283DDC
    gpg: Can't check signature: No public key
Importing a Key (If Applicable)
gpg --recv-keys 101A7EF8EF283DDC
    gpg: key 101A7EF8EF283DDC: public key "Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>" imported
    gpg: no ultimately trusted keys found
    gpg: Total number processed: 1
    gpg:               imported: 1
Successful Verification of Signed ISO
    gpg: Signature made Mon 30 Apr 2018 04:44:08 PM MDT
    gpg:                using RSA key 101A7EF8EF283DDC
    gpg: Good signature from "Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>" [marginal]
    gpg: Verified 1 signature in the past 10 days.  Encrypted 0 messages.
    gpg:          It is not certain that the signature belongs to the owner.
    Primary key fingerprint: D7E9 CE35 33F1 938C 6F8E  F5FD 101A 7EF8 EF28 3DDC
Verifing Keys

We've verified that source.iso was signed by 101A7EF8EF283DDC (2018 Firmware Signer) <>.
How do we verify that key really belongs to Raptor?
gpg --list-signatures 101A7EF8EF283DDC

    pub   rsa4096 2018-04-25 [SC] [expires: 2019-01-20]
    uid           [marginal] Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>
    sig 3        101A7EF8EF283DDC 2018-04-25  Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>
    sig          9B2BF5BD337BF51F 2018-04-25  Raptor Computing Systems Primary Signer (Umbrella Signer) <>
    sub   rsa4096 2018-04-25 [E] [expires: 2019-01-20]
    sig          101A7EF8EF283DDC 2018-04-25  Raptor Computing Systems Firmware Signer (2018) (2018 Firmware Signer) <>

101A7EF8EF283DDC was signed by 9B2BF5BD337BF51F
gpg --fingerprint 9B2BF5BD337BF51F

    pub   rsa4096 2018-04-16 [SC]
          9C2A 6E8F AEA7 EE92 1EFD  4891 9B2B F5BD 337B F51F
    uid           [marginal] Raptor Computing Systems Primary Signer (Umbrella Signer) <>
    sub   rsa4096 2018-04-16 [E]