diff --git a/nearby/service/java/com/android/server/nearby/presence/ExtendedAdvertisement.java b/nearby/service/java/com/android/server/nearby/presence/ExtendedAdvertisement.java
index 34a7514..c2304cc 100644
--- a/nearby/service/java/com/android/server/nearby/presence/ExtendedAdvertisement.java
+++ b/nearby/service/java/com/android/server/nearby/presence/ExtendedAdvertisement.java
@@ -16,22 +16,27 @@
 
 package com.android.server.nearby.presence;
 
+import static android.nearby.BroadcastRequest.PRESENCE_VERSION_V1;
+
 import static com.android.server.nearby.NearbyService.TAG;
+import static com.android.server.nearby.presence.EncryptionInfo.ENCRYPTION_INFO_LENGTH;
+import static com.android.server.nearby.presence.PresenceConstants.PRESENCE_UUID_BYTES;
 
 import android.annotation.Nullable;
-import android.nearby.BroadcastRequest;
+import android.nearby.BroadcastRequest.BroadcastVersion;
 import android.nearby.DataElement;
+import android.nearby.DataElement.DataType;
 import android.nearby.PresenceBroadcastRequest;
 import android.nearby.PresenceCredential;
 import android.nearby.PublicCredential;
 import android.util.Log;
 
+import com.android.server.nearby.util.ArrayUtils;
 import com.android.server.nearby.util.encryption.Cryptor;
-import com.android.server.nearby.util.encryption.CryptorImpFake;
-import com.android.server.nearby.util.encryption.CryptorImpIdentityV1;
-import com.android.server.nearby.util.encryption.CryptorImpV1;
+import com.android.server.nearby.util.encryption.CryptorMicImp;
 
 import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -51,37 +56,51 @@
  * The header contains:
  * version (3 bits) | 5 bit reserved for future use (RFU)
  */
-public class ExtendedAdvertisement extends Advertisement{
+public class ExtendedAdvertisement extends Advertisement {
 
     public static final int SALT_DATA_LENGTH = 2;
-
     static final int HEADER_LENGTH = 1;
 
     static final int IDENTITY_DATA_LENGTH = 16;
-
+    // Identity Index is always 2 .
+    // 0 is reserved, 1 is Salt or Credential Element.
+    private static final int CIPHER_START_INDEX = 2;
     private final List<DataElement> mDataElements;
+    private final byte[] mKeySeed;
 
-    private final byte[] mAuthenticityKey;
+    private final byte[] mData;
 
-    // All Data Elements including salt and identity.
-    // Each list item (byte array) is a Data Element (with its header).
-    private final List<byte[]> mCompleteDataElementsBytes;
-    // Signature generated from data elements.
-    private final byte[] mHmacTag;
+    private ExtendedAdvertisement(
+            @PresenceCredential.IdentityType int identityType,
+            byte[] identity,
+            byte[] salt,
+            byte[] keySeed,
+            List<Integer> actions,
+            List<DataElement> dataElements) {
+        this.mVersion = PRESENCE_VERSION_V1;
+        this.mIdentityType = identityType;
+        this.mIdentity = identity;
+        this.mSalt = salt;
+        this.mKeySeed = keySeed;
+        this.mDataElements = dataElements;
+        this.mActions = actions;
+        mData = toBytesInternal();
+    }
 
     /**
      * Creates an {@link ExtendedAdvertisement} from a Presence Broadcast Request.
+     *
      * @return {@link ExtendedAdvertisement} object. {@code null} when the request is illegal.
      */
     @Nullable
     public static ExtendedAdvertisement createFromRequest(PresenceBroadcastRequest request) {
-        if (request.getVersion() != BroadcastRequest.PRESENCE_VERSION_V1) {
+        if (request.getVersion() != PRESENCE_VERSION_V1) {
             Log.v(TAG, "ExtendedAdvertisement only supports V1 now.");
             return null;
         }
 
         byte[] salt = request.getSalt();
-        if (salt.length != SALT_DATA_LENGTH) {
+        if (salt.length != SALT_DATA_LENGTH && salt.length != ENCRYPTION_INFO_LENGTH - 1) {
             Log.v(TAG, "Salt does not match correct length");
             return null;
         }
@@ -94,12 +113,12 @@
         }
 
         List<Integer> actions = request.getActions();
-        if (actions.isEmpty()) {
-            Log.v(TAG, "ExtendedAdvertisement must contain at least one action");
-            return null;
-        }
-
         List<DataElement> dataElements = request.getExtendedProperties();
+        // DataElements should include actions.
+        for (int action : actions) {
+            dataElements.add(
+                    new DataElement(DataType.ACTION, new byte[]{(byte) action}));
+        }
         return new ExtendedAdvertisement(
                 request.getCredential().getIdentityType(),
                 identity,
@@ -109,149 +128,252 @@
                 dataElements);
     }
 
-    /** Serialize an {@link ExtendedAdvertisement} object into bytes with {@link DataElement}s */
-    @Nullable
-    public byte[] toBytes() {
-        ByteBuffer buffer = ByteBuffer.allocate(getLength());
-
-        // Header
-        buffer.put(ExtendedAdvertisementUtils.constructHeader(getVersion()));
-
-        // Salt
-        buffer.put(mCompleteDataElementsBytes.get(0));
-
-        // Identity
-        buffer.put(mCompleteDataElementsBytes.get(1));
-
-        List<Byte> rawDataBytes = new ArrayList<>();
-        // Data Elements (Already includes salt and identity)
-        for (int i = 2; i < mCompleteDataElementsBytes.size(); i++) {
-            byte[] dataElementBytes = mCompleteDataElementsBytes.get(i);
-            for (Byte b : dataElementBytes) {
-                rawDataBytes.add(b);
-            }
-        }
-
-        byte[] dataElements = new byte[rawDataBytes.size()];
-        for (int i = 0; i < rawDataBytes.size(); i++) {
-            dataElements[i] = rawDataBytes.get(i);
-        }
-
-        buffer.put(
-                getCryptor(/* encrypt= */ true).encrypt(dataElements, getSalt(), mAuthenticityKey));
-
-        buffer.put(mHmacTag);
-
-        return buffer.array();
-    }
-
-    /** Deserialize from bytes into an {@link ExtendedAdvertisement} object.
-     * {@code null} when there is something when parsing.
+    /**
+     * Deserialize from bytes into an {@link ExtendedAdvertisement} object.
+     * Return {@code null} when there is an error in parsing.
      */
     @Nullable
-    public static ExtendedAdvertisement fromBytes(byte[] bytes, PublicCredential publicCredential) {
-        @BroadcastRequest.BroadcastVersion
+    public static ExtendedAdvertisement fromBytes(byte[] bytes, PublicCredential sharedCredential) {
+        @BroadcastVersion
         int version = ExtendedAdvertisementUtils.getVersion(bytes);
-        if (version != PresenceBroadcastRequest.PRESENCE_VERSION_V1) {
+        if (version != PRESENCE_VERSION_V1) {
             Log.v(TAG, "ExtendedAdvertisement is used in V1 only and version is " + version);
             return null;
         }
 
-        byte[] authenticityKey = publicCredential.getAuthenticityKey();
-
-        int index = HEADER_LENGTH;
-        // Salt
-        byte[] saltHeaderArray = ExtendedAdvertisementUtils.getDataElementHeader(bytes, index);
-        DataElementHeader saltHeader = DataElementHeader.fromBytes(version, saltHeaderArray);
-        if (saltHeader == null || saltHeader.getDataType() != DataElement.DataType.SALT) {
-            Log.v(TAG, "First data element has to be salt.");
+        byte[] keySeed = sharedCredential.getAuthenticityKey();
+        byte[] metadataEncryptionKeyUnsignedAdvTag = sharedCredential.getEncryptedMetadataKeyTag();
+        if (keySeed == null || metadataEncryptionKeyUnsignedAdvTag == null) {
             return null;
         }
-        index += saltHeaderArray.length;
-        byte[] salt = new byte[saltHeader.getDataLength()];
-        for (int i = 0; i < saltHeader.getDataLength(); i++) {
-            salt[i] = bytes[index++];
-        }
 
-        // Identity
+        int index = 0;
+        // Header
+        byte[] header = new byte[]{bytes[index]};
+        index += HEADER_LENGTH;
+        // Section header
+        byte[] sectionHeader = new byte[]{bytes[index]};
+        index += HEADER_LENGTH;
+        // Salt or Encryption Info
+        byte[] firstHeaderArray = ExtendedAdvertisementUtils.getDataElementHeader(bytes, index);
+        DataElementHeader firstHeader = DataElementHeader.fromBytes(version, firstHeaderArray);
+        if (firstHeader == null) {
+            Log.v(TAG, "Cannot find salt.");
+            return null;
+        }
+        @DataType int firstType = firstHeader.getDataType();
+        if (firstType != DataType.SALT && firstType != DataType.ENCRYPTION_INFO) {
+            Log.v(TAG, "First data element has to be Salt or Encryption Info.");
+            return null;
+        }
+        index += firstHeaderArray.length;
+        byte[] firstDeBytes = new byte[firstHeader.getDataLength()];
+        for (int i = 0; i < firstHeader.getDataLength(); i++) {
+            firstDeBytes[i] = bytes[index++];
+        }
+        byte[] nonce = getNonce(firstType, firstDeBytes);
+        if (nonce == null) {
+            return null;
+        }
+        byte[] saltBytes = firstType == DataType.SALT
+                ? firstDeBytes : (new EncryptionInfo(firstDeBytes)).getSalt();
+
+        // Identity header
         byte[] identityHeaderArray = ExtendedAdvertisementUtils.getDataElementHeader(bytes, index);
         DataElementHeader identityHeader =
                 DataElementHeader.fromBytes(version, identityHeaderArray);
-        if (identityHeader == null) {
-            Log.v(TAG, "The second element has to be identity.");
+        if (identityHeader == null || identityHeader.getDataLength() != IDENTITY_DATA_LENGTH) {
+            Log.v(TAG, "The second element has to be a 16-bytes identity.");
             return null;
         }
         index += identityHeaderArray.length;
         @PresenceCredential.IdentityType int identityType =
                 toPresenceCredentialIdentityType(identityHeader.getDataType());
-        if (identityType == PresenceCredential.IDENTITY_TYPE_UNKNOWN) {
-            Log.v(TAG, "The identity type is unknown.");
+        if (identityType != PresenceCredential.IDENTITY_TYPE_PRIVATE
+                && identityType != PresenceCredential.IDENTITY_TYPE_TRUSTED) {
+            Log.v(TAG, "Only supports encrypted advertisement.");
             return null;
         }
-        byte[] encryptedIdentity = new byte[identityHeader.getDataLength()];
-        for (int i = 0; i < identityHeader.getDataLength(); i++) {
-            encryptedIdentity[i] = bytes[index++];
-        }
-        byte[] identity =
-                CryptorImpIdentityV1
-                        .getInstance().decrypt(encryptedIdentity, salt, authenticityKey);
-
-        Cryptor cryptor = getCryptor(/* encrypt= */ true);
-        byte[] encryptedDataElements =
-                new byte[bytes.length - index - cryptor.getSignatureLength()];
-        // Decrypt other data elements
-        System.arraycopy(bytes, index, encryptedDataElements, 0, encryptedDataElements.length);
-        byte[] decryptedDataElements =
-                cryptor.decrypt(encryptedDataElements, salt, authenticityKey);
-        if (decryptedDataElements == null) {
+        // Ciphertext
+        Cryptor cryptor = CryptorMicImp.getInstance();
+        byte[] ciphertext = new byte[bytes.length - index - cryptor.getSignatureLength()];
+        System.arraycopy(bytes, index, ciphertext, 0, ciphertext.length);
+        byte[] plaintext = cryptor.decrypt(ciphertext, nonce, keySeed);
+        if (plaintext == null) {
             return null;
         }
 
+        // Verification
+        // Verify the computed metadata encryption key tag
+        // First 16 bytes is metadata encryption key data
+        byte[] metadataEncryptionKey = new byte[IDENTITY_DATA_LENGTH];
+        System.arraycopy(plaintext, 0, metadataEncryptionKey, 0, IDENTITY_DATA_LENGTH);
+        // Verify metadata encryption key tag
+        byte[] computedMetadataEncryptionKeyTag =
+                CryptorMicImp.generateMetadataEncryptionKeyTag(metadataEncryptionKey,
+                        keySeed);
+        if (!Arrays.equals(computedMetadataEncryptionKeyTag, metadataEncryptionKeyUnsignedAdvTag)) {
+            Log.w(TAG,
+                    "The calculated metadata encryption key tag is different from the metadata "
+                            + "encryption key unsigned adv tag in the SharedCredential.");
+            return null;
+        }
         // Verify the computed HMAC tag is equal to HMAC tag in advertisement
-        if (cryptor.getSignatureLength() > 0) {
-            byte[] expectedHmacTag = new byte[cryptor.getSignatureLength()];
-            System.arraycopy(
-                    bytes, bytes.length - cryptor.getSignatureLength(),
-                    expectedHmacTag, 0, cryptor.getSignatureLength());
-            if (!cryptor.verify(decryptedDataElements, authenticityKey, expectedHmacTag)) {
-                Log.e(TAG, "HMAC tags not match.");
-                return null;
-            }
+        byte[] expectedHmacTag = new byte[cryptor.getSignatureLength()];
+        System.arraycopy(
+                bytes, bytes.length - cryptor.getSignatureLength(),
+                expectedHmacTag, 0, cryptor.getSignatureLength());
+        byte[] micInput =  ArrayUtils.concatByteArrays(
+                PRESENCE_UUID_BYTES, header, sectionHeader,
+                firstHeaderArray, firstDeBytes,
+                nonce, identityHeaderArray, ciphertext);
+        if (!cryptor.verify(micInput, keySeed, expectedHmacTag)) {
+            Log.e(TAG, "HMAC tag not match.");
+            return null;
         }
 
-        int dataElementArrayIndex = 0;
-        // Other Data Elements
-        List<Integer> actions = new ArrayList<>();
-        List<DataElement> dataElements = new ArrayList<>();
-        while (dataElementArrayIndex < decryptedDataElements.length) {
-            byte[] deHeaderArray = ExtendedAdvertisementUtils
-                    .getDataElementHeader(decryptedDataElements, dataElementArrayIndex);
-            DataElementHeader deHeader = DataElementHeader.fromBytes(version, deHeaderArray);
-            dataElementArrayIndex += deHeaderArray.length;
+        byte[] otherDataElements = new byte[plaintext.length - IDENTITY_DATA_LENGTH];
+        System.arraycopy(plaintext, IDENTITY_DATA_LENGTH,
+                otherDataElements, 0, otherDataElements.length);
+        List<DataElement> dataElements = getDataElementsFromBytes(version, otherDataElements);
+        if (dataElements.isEmpty()) {
+            return null;
+        }
+        List<Integer> actions = getActionsFromDataElements(dataElements);
+        if (actions == null) {
+            return null;
+        }
+        return new ExtendedAdvertisement(identityType, metadataEncryptionKey, saltBytes, keySeed,
+                actions, dataElements);
+    }
 
-            @DataElement.DataType int type = Objects.requireNonNull(deHeader).getDataType();
-            if (type == DataElement.DataType.ACTION) {
-                if (deHeader.getDataLength() != 1) {
-                    Log.v(TAG, "Action id should only 1 byte.");
+    @PresenceCredential.IdentityType
+    private static int toPresenceCredentialIdentityType(@DataType int type) {
+        switch (type) {
+            case DataType.PRIVATE_IDENTITY:
+                return PresenceCredential.IDENTITY_TYPE_PRIVATE;
+            case DataType.PROVISIONED_IDENTITY:
+                return PresenceCredential.IDENTITY_TYPE_PROVISIONED;
+            case DataType.TRUSTED_IDENTITY:
+                return PresenceCredential.IDENTITY_TYPE_TRUSTED;
+            case DataType.PUBLIC_IDENTITY:
+            default:
+                return PresenceCredential.IDENTITY_TYPE_UNKNOWN;
+        }
+    }
+
+    @DataType
+    private static int toDataType(@PresenceCredential.IdentityType int identityType) {
+        switch (identityType) {
+            case PresenceCredential.IDENTITY_TYPE_PRIVATE:
+                return DataType.PRIVATE_IDENTITY;
+            case PresenceCredential.IDENTITY_TYPE_PROVISIONED:
+                return DataType.PROVISIONED_IDENTITY;
+            case PresenceCredential.IDENTITY_TYPE_TRUSTED:
+                return DataType.TRUSTED_IDENTITY;
+            case PresenceCredential.IDENTITY_TYPE_UNKNOWN:
+            default:
+                return DataType.PUBLIC_IDENTITY;
+        }
+    }
+
+    /**
+     * Returns {@code true} if the given {@link DataType} is salt, or one of the
+     * identities. Identities should be able to convert to {@link PresenceCredential.IdentityType}s.
+     */
+    private static boolean isSaltOrIdentity(@DataType int type) {
+        return type == DataType.SALT || type == DataType.ENCRYPTION_INFO
+                || type == DataType.PRIVATE_IDENTITY
+                || type == DataType.TRUSTED_IDENTITY
+                || type == DataType.PROVISIONED_IDENTITY
+                || type == DataType.PUBLIC_IDENTITY;
+    }
+
+    /** Serialize an {@link ExtendedAdvertisement} object into bytes with {@link DataElement}s */
+    @Nullable
+    public byte[] toBytes() {
+        return mData.clone();
+    }
+
+    /** Serialize an {@link ExtendedAdvertisement} object into bytes with {@link DataElement}s */
+    @Nullable
+    public byte[] toBytesInternal() {
+        int sectionLength = 0;
+        // Salt
+        DataElement saltDe;
+        byte[] nonce;
+        try {
+            switch (mSalt.length) {
+                case SALT_DATA_LENGTH:
+                    saltDe = new DataElement(DataType.SALT, mSalt);
+                    nonce = CryptorMicImp.generateAdvNonce(mSalt);
+                    break;
+                case ENCRYPTION_INFO_LENGTH - 1:
+                    saltDe = new DataElement(DataType.ENCRYPTION_INFO,
+                            EncryptionInfo.toByte(EncryptionInfo.EncodingScheme.MIC, mSalt));
+                    nonce = CryptorMicImp.generateAdvNonce(mSalt, CIPHER_START_INDEX);
+                    break;
+                default:
+                    Log.w(TAG, "Invalid salt size.");
                     return null;
-                }
-                actions.add((int) decryptedDataElements[dataElementArrayIndex++]);
-            } else {
-                if (isSaltOrIdentity(type)) {
-                    Log.v(TAG, "Type " + type + " is duplicated. There should be only one salt"
-                            + " and one identity in the advertisement.");
-                    return null;
-                }
-                byte[] deData = new byte[deHeader.getDataLength()];
-                for (int i = 0; i < deHeader.getDataLength(); i++) {
-                    deData[i] = decryptedDataElements[dataElementArrayIndex++];
-                }
-                dataElements.add(new DataElement(type, deData));
             }
+        } catch (GeneralSecurityException e) {
+            Log.w(TAG, "Failed to generate the IV for encryption.", e);
+            return null;
         }
 
-        return new ExtendedAdvertisement(identityType, identity, salt, authenticityKey, actions,
-                dataElements);
+        byte[] saltOrEncryptionInfoBytes =
+                ExtendedAdvertisementUtils.convertDataElementToBytes(saltDe);
+        sectionLength += saltOrEncryptionInfoBytes.length;
+        // 16 bytes encrypted identity
+        @DataType int identityDataType = toDataType(getIdentityType());
+        byte[] identityHeaderBytes = new DataElementHeader(PRESENCE_VERSION_V1,
+                identityDataType, mIdentity.length).toBytes();
+        sectionLength += identityHeaderBytes.length;
+        final List<DataElement> dataElementList = getDataElements();
+        byte[] ciphertext = getCiphertext(nonce, dataElementList);
+        if (ciphertext == null) {
+            return null;
+        }
+        sectionLength += ciphertext.length;
+        // mic
+        sectionLength += CryptorMicImp.MIC_LENGTH;
+        mLength = sectionLength;
+        // header
+        byte header = ExtendedAdvertisementUtils.constructHeader(getVersion());
+        mLength += HEADER_LENGTH;
+        // section header
+        if (sectionLength > 255) {
+            Log.e(TAG, "A section should be shorter than 255 bytes.");
+            return null;
+        }
+        byte sectionHeader = (byte) sectionLength;
+        mLength += HEADER_LENGTH;
+
+        // generates mic
+        ByteBuffer micInputBuffer = ByteBuffer.allocate(
+                mLength + PRESENCE_UUID_BYTES.length + nonce.length - CryptorMicImp.MIC_LENGTH);
+        micInputBuffer.put(PRESENCE_UUID_BYTES);
+        micInputBuffer.put(header);
+        micInputBuffer.put(sectionHeader);
+        micInputBuffer.put(saltOrEncryptionInfoBytes);
+        micInputBuffer.put(nonce);
+        micInputBuffer.put(identityHeaderBytes);
+        micInputBuffer.put(ciphertext);
+        byte[] micInput = micInputBuffer.array();
+        byte[] mic = CryptorMicImp.getInstance().sign(micInput, mKeySeed);
+        if (mic == null) {
+            return null;
+        }
+
+        ByteBuffer buffer = ByteBuffer.allocate(mLength);
+        buffer.put(header);
+        buffer.put(sectionHeader);
+        buffer.put(saltOrEncryptionInfoBytes);
+        buffer.put(identityHeaderBytes);
+        buffer.put(ciphertext);
+        buffer.put(mic);
+        return buffer.array();
     }
 
     /** Returns the {@link DataElement}s in the advertisement. */
@@ -260,7 +382,7 @@
     }
 
     /** Returns the {@link DataElement}s in the advertisement according to the key. */
-    public List<DataElement> getDataElements(@DataElement.DataType int key) {
+    public List<DataElement> getDataElements(@DataType int key) {
         List<DataElement> res = new ArrayList<>();
         for (DataElement dataElement : mDataElements) {
             if (key == dataElement.getKey()) {
@@ -285,125 +407,86 @@
                 getActions());
     }
 
-    ExtendedAdvertisement(
-            @PresenceCredential.IdentityType int identityType,
-            byte[] identity,
-            byte[] salt,
-            byte[] authenticityKey,
-            List<Integer> actions,
-            List<DataElement> dataElements) {
-        this.mVersion = BroadcastRequest.PRESENCE_VERSION_V1;
-        this.mIdentityType = identityType;
-        this.mIdentity = identity;
-        this.mSalt = salt;
-        this.mAuthenticityKey = authenticityKey;
-        this.mActions = actions;
-        this.mDataElements = dataElements;
-        this.mCompleteDataElementsBytes = new ArrayList<>();
+    @Nullable
+    private byte[] getCiphertext(byte[] nonce, List<DataElement> dataElements) {
+        Cryptor cryptor = CryptorMicImp.getInstance();
+        byte[] rawDeBytes = mIdentity;
+        for (DataElement dataElement : dataElements) {
+            rawDeBytes = ArrayUtils.concatByteArrays(rawDeBytes,
+                    ExtendedAdvertisementUtils.convertDataElementToBytes(dataElement));
+        }
+        return cryptor.encrypt(rawDeBytes, nonce, mKeySeed);
+    }
 
-        int length = HEADER_LENGTH; // header
+    private static List<DataElement> getDataElementsFromBytes(
+            @BroadcastVersion int version, byte[] bytes) {
+        List<DataElement> res = new ArrayList<>();
+        if (ArrayUtils.isEmpty(bytes)) {
+            return res;
+        }
+        int index = 0;
+        while (index < bytes.length) {
+            byte[] deHeaderArray = ExtendedAdvertisementUtils
+                    .getDataElementHeader(bytes, index);
+            DataElementHeader deHeader = DataElementHeader.fromBytes(version, deHeaderArray);
+            index += deHeaderArray.length;
+            @DataType int type = Objects.requireNonNull(deHeader).getDataType();
+            if (isSaltOrIdentity(type)) {
+                Log.v(TAG, "Type " + type + " is duplicated. There should be only one salt"
+                        + " and one identity in the advertisement.");
+                return new ArrayList<>();
+            }
+            byte[] deData = new byte[deHeader.getDataLength()];
+            for (int i = 0; i < deHeader.getDataLength(); i++) {
+                deData[i] = bytes[index++];
+            }
+            res.add(new DataElement(type, deData));
+        }
+        return res;
+    }
 
-        // Salt
-        DataElement saltElement = new DataElement(DataElement.DataType.SALT, salt);
-        byte[] saltByteArray = ExtendedAdvertisementUtils.convertDataElementToBytes(saltElement);
-        mCompleteDataElementsBytes.add(saltByteArray);
-        length += saltByteArray.length;
+    @Nullable
+    private static byte[] getNonce(@DataType int type, byte[] data) {
+        try {
+            if (type == DataType.SALT) {
+                if (data.length != SALT_DATA_LENGTH) {
+                    Log.v(TAG, "Salt DataElement needs to be 2 bytes.");
+                    return null;
+                }
+                return CryptorMicImp.generateAdvNonce(data);
+            } else if (type == DataType.ENCRYPTION_INFO) {
+                try {
+                    EncryptionInfo info = new EncryptionInfo(data);
+                    if (info.getEncodingScheme() != EncryptionInfo.EncodingScheme.MIC) {
+                        Log.v(TAG, "Not support Signature yet.");
+                        return null;
+                    }
+                    return CryptorMicImp.generateAdvNonce(info.getSalt(), CIPHER_START_INDEX);
+                } catch (IllegalArgumentException e) {
+                    Log.w(TAG, "Salt DataElement needs to be 17 bytes.", e);
+                    return null;
+                }
+            }
+        }  catch (GeneralSecurityException e) {
+            Log.w(TAG, "Failed to decrypt metadata encryption key.", e);
+            return null;
+        }
+        return null;
+    }
 
-        // Identity
-        byte[] encryptedIdentity =
-                CryptorImpIdentityV1.getInstance().encrypt(identity, salt, authenticityKey);
-        DataElement identityElement = new DataElement(toDataType(identityType), encryptedIdentity);
-        byte[] identityByteArray =
-                ExtendedAdvertisementUtils.convertDataElementToBytes(identityElement);
-        mCompleteDataElementsBytes.add(identityByteArray);
-        length += identityByteArray.length;
-
-        List<Byte> dataElementBytes = new ArrayList<>();
-        // Intents
-        for (int action : mActions) {
-            DataElement actionElement = new DataElement(DataElement.DataType.ACTION,
-                    new byte[] {(byte) action});
-            byte[] intentByteArray =
-                    ExtendedAdvertisementUtils.convertDataElementToBytes(actionElement);
-            mCompleteDataElementsBytes.add(intentByteArray);
-            for (Byte b : intentByteArray) {
-                dataElementBytes.add(b);
+    @Nullable
+    private static List<Integer> getActionsFromDataElements(List<DataElement> dataElements) {
+        List<Integer> actions = new ArrayList<>();
+        for (DataElement dataElement : dataElements) {
+            if (dataElement.getKey() == DataElement.DataType.ACTION) {
+                byte[] value = dataElement.getValue();
+                if (value.length != 1) {
+                    Log.w(TAG, "Action should be only 1 byte.");
+                    return null;
+                }
+                actions.add(Byte.toUnsignedInt(value[0]));
             }
         }
-
-        // Data Elements (Extended properties)
-        for (DataElement dataElement : mDataElements) {
-            byte[] deByteArray = ExtendedAdvertisementUtils.convertDataElementToBytes(dataElement);
-            mCompleteDataElementsBytes.add(deByteArray);
-            for (Byte b : deByteArray) {
-                dataElementBytes.add(b);
-            }
-        }
-
-        byte[] data = new byte[dataElementBytes.size()];
-        for (int i = 0; i < dataElementBytes.size(); i++) {
-            data[i] = dataElementBytes.get(i);
-        }
-        Cryptor cryptor = getCryptor(/* encrypt= */ true);
-        byte[] encryptedDeBytes = cryptor.encrypt(data, salt, authenticityKey);
-
-        length += encryptedDeBytes.length;
-
-        // Signature
-        byte[] hmacTag = Objects.requireNonNull(cryptor.sign(data, authenticityKey));
-        mHmacTag = hmacTag;
-        length += hmacTag.length;
-
-        this.mLength = length;
-    }
-
-    @PresenceCredential.IdentityType
-    private static int toPresenceCredentialIdentityType(@DataElement.DataType int type) {
-        switch (type) {
-            case DataElement.DataType.PRIVATE_IDENTITY:
-                return PresenceCredential.IDENTITY_TYPE_PRIVATE;
-            case DataElement.DataType.PROVISIONED_IDENTITY:
-                return PresenceCredential.IDENTITY_TYPE_PROVISIONED;
-            case DataElement.DataType.TRUSTED_IDENTITY:
-                return PresenceCredential.IDENTITY_TYPE_TRUSTED;
-            case DataElement.DataType.PUBLIC_IDENTITY:
-            default:
-                return PresenceCredential.IDENTITY_TYPE_UNKNOWN;
-        }
-    }
-
-    @DataElement.DataType
-    private static int toDataType(@PresenceCredential.IdentityType int identityType) {
-        switch (identityType) {
-            case PresenceCredential.IDENTITY_TYPE_PRIVATE:
-                return DataElement.DataType.PRIVATE_IDENTITY;
-            case PresenceCredential.IDENTITY_TYPE_PROVISIONED:
-                return DataElement.DataType.PROVISIONED_IDENTITY;
-            case PresenceCredential.IDENTITY_TYPE_TRUSTED:
-                return DataElement.DataType.TRUSTED_IDENTITY;
-            case PresenceCredential.IDENTITY_TYPE_UNKNOWN:
-            default:
-                return DataElement.DataType.PUBLIC_IDENTITY;
-        }
-    }
-
-    /**
-     * Returns {@code true} if the given {@link DataElement.DataType} is salt, or one of the
-     * identities. Identities should be able to convert to {@link PresenceCredential.IdentityType}s.
-     */
-    private static boolean isSaltOrIdentity(@DataElement.DataType int type) {
-        return type == DataElement.DataType.SALT || type == DataElement.DataType.PRIVATE_IDENTITY
-                || type == DataElement.DataType.TRUSTED_IDENTITY
-                || type == DataElement.DataType.PROVISIONED_IDENTITY
-                || type == DataElement.DataType.PUBLIC_IDENTITY;
-    }
-
-    private static Cryptor getCryptor(boolean encrypt) {
-        if (encrypt) {
-            Log.d(TAG, "get V1 Cryptor");
-            return CryptorImpV1.getInstance();
-        }
-        Log.d(TAG, "get fake Cryptor");
-        return CryptorImpFake.getInstance();
+        return actions;
     }
 }
diff --git a/nearby/service/java/com/android/server/nearby/presence/PresenceConstants.java b/nearby/service/java/com/android/server/nearby/presence/PresenceConstants.java
index 54264f7..50dada2 100644
--- a/nearby/service/java/com/android/server/nearby/presence/PresenceConstants.java
+++ b/nearby/service/java/com/android/server/nearby/presence/PresenceConstants.java
@@ -18,10 +18,15 @@
 
 import android.os.ParcelUuid;
 
+import com.android.server.nearby.util.ArrayUtils;
+
 /**
  * Constants for Nearby Presence operations.
  */
 public class PresenceConstants {
+    /** The Presence UUID value in byte array format. */
+    public static final byte[] PRESENCE_UUID_BYTES = ArrayUtils.intToByteArray(0xFCF1);
+
     /** Presence advertisement service data uuid. */
     public static final ParcelUuid PRESENCE_UUID =
             ParcelUuid.fromString("0000fcf1-0000-1000-8000-00805f9b34fb");
diff --git a/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
index 355f7cf..9dd07a4 100644
--- a/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
@@ -45,7 +45,6 @@
 import com.android.server.nearby.presence.ExtendedAdvertisement;
 import com.android.server.nearby.util.ArrayUtils;
 import com.android.server.nearby.util.ForegroundThread;
-import com.android.server.nearby.util.encryption.CryptorImpIdentityV1;
 
 import com.google.common.annotations.VisibleForTesting;
 
@@ -133,10 +132,6 @@
                         .addMedium(NearbyDevice.Medium.BLE)
                         .setName(deviceName)
                         .setRssi(rssi);
-        for (int i : advertisement.getActions()) {
-            builder.addExtendedProperty(new DataElement(DataElement.DataType.ACTION,
-                    new byte[]{(byte) i}));
-        }
         for (DataElement dataElement : advertisement.getDataElements()) {
             builder.addExtendedProperty(dataElement);
         }
@@ -284,17 +279,13 @@
                         if (advertisement == null) {
                             continue;
                         }
-                        if (CryptorImpIdentityV1.getInstance().verify(
-                                advertisement.getIdentity(),
-                                credential.getEncryptedMetadataKeyTag())) {
-                            builder.setPresenceDevice(getPresenceDevice(advertisement, deviceName,
-                                    rssi));
-                            builder.setEncryptionKeyTag(credential.getEncryptedMetadataKeyTag());
-                            if (!ArrayUtils.isEmpty(credential.getSecretId())) {
-                                builder.setDeviceId(Arrays.hashCode(credential.getSecretId()));
-                            }
-                            return;
+                        builder.setPresenceDevice(getPresenceDevice(advertisement, deviceName,
+                                rssi));
+                        builder.setEncryptionKeyTag(credential.getEncryptedMetadataKeyTag());
+                        if (!ArrayUtils.isEmpty(credential.getSecretId())) {
+                            builder.setDeviceId(Arrays.hashCode(credential.getSecretId()));
                         }
+                        return;
                     }
                 }
             }
diff --git a/nearby/tests/unit/src/com/android/server/nearby/presence/ExtendedAdvertisementTest.java b/nearby/tests/unit/src/com/android/server/nearby/presence/ExtendedAdvertisementTest.java
index 895df69..3f00a42 100644
--- a/nearby/tests/unit/src/com/android/server/nearby/presence/ExtendedAdvertisementTest.java
+++ b/nearby/tests/unit/src/com/android/server/nearby/presence/ExtendedAdvertisementTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.nearby.presence;
 
+import static com.android.server.nearby.presence.PresenceConstants.PRESENCE_UUID_BYTES;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.nearby.BroadcastRequest;
@@ -25,19 +27,22 @@
 import android.nearby.PrivateCredential;
 import android.nearby.PublicCredential;
 
-import com.android.server.nearby.util.encryption.CryptorImpIdentityV1;
-import com.android.server.nearby.util.encryption.CryptorImpV1;
+import com.android.server.nearby.util.ArrayUtils;
+import com.android.server.nearby.util.encryption.CryptorMicImp;
 
 import org.junit.Before;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
 public class ExtendedAdvertisementTest {
+    private static final int EXTENDED_ADVERTISEMENT_BYTE_LENGTH = 67;
     private static final int IDENTITY_TYPE = PresenceCredential.IDENTITY_TYPE_PRIVATE;
+    private static final int DATA_TYPE_ACTION = 6;
     private static final int DATA_TYPE_MODEL_ID = 7;
     private static final int DATA_TYPE_BLE_ADDRESS = 101;
     private static final int DATA_TYPE_PUBLIC_IDENTITY = 3;
@@ -49,18 +54,23 @@
     private static final DataElement BLE_ADDRESS_ELEMENT =
             new DataElement(DATA_TYPE_BLE_ADDRESS, BLE_ADDRESS);
 
-    private static final byte[] IDENTITY =
-            new byte[]{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
+    private static final byte[] METADATA_ENCRYPTION_KEY =
+            new byte[]{-39, -55, 115, 78, -57, 40, 115, 0, -112, 86, -86, 7, -42, 68, 11, 12};
     private static final int MEDIUM_TYPE_BLE = 0;
     private static final byte[] SALT = {2, 3};
+
     private static final int PRESENCE_ACTION_1 = 1;
     private static final int PRESENCE_ACTION_2 = 2;
+    private static final DataElement PRESENCE_ACTION_DE_1 =
+            new DataElement(DATA_TYPE_ACTION, new byte[]{PRESENCE_ACTION_1});
+    private static final DataElement PRESENCE_ACTION_DE_2 =
+            new DataElement(DATA_TYPE_ACTION, new byte[]{PRESENCE_ACTION_2});
 
     private static final byte[] SECRET_ID = new byte[]{1, 2, 3, 4};
     private static final byte[] AUTHENTICITY_KEY =
             new byte[]{-97, 10, 107, -86, 25, 65, -54, -95, -72, 59, 54, 93, 9, 3, -24, -88};
     private static final byte[] PUBLIC_KEY =
-            new byte[] {
+            new byte[]{
                     48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61,
                     66, 0, 4, -56, -39, -92, 69, 0, 52, 23, 67, 83, -14, 75, 52, -14, -5, -41, 48,
                     -83, 31, 42, -39, 102, -13, 22, -73, -73, 86, 30, -96, -84, -13, 4, 122, 104,
@@ -68,7 +78,7 @@
                     123, 41, -119, -25, 1, -112, 112
             };
     private static final byte[] ENCRYPTED_METADATA_BYTES =
-            new byte[] {
+            new byte[]{
                     -44, -25, -95, -124, -7, 90, 116, -8, 7, -120, -23, -22, -106, -44, -19, 61,
                     -18, 39, 29, 78, 108, -11, -39, 85, -30, 64, -99, 102, 65, 37, -42, 114, -37,
                     88, -112, 8, -75, -53, 23, -16, -104, 67, 49, 48, -53, 73, -109, 44, -23, -11,
@@ -78,23 +88,65 @@
                     -4, -46, -30, -85, -50, 100, 46, -66, -128, 7, 66, 9, 88, 95, 12, -13, 81, -91,
             };
     private static final byte[] METADATA_ENCRYPTION_KEY_TAG =
-            new byte[] {-126, -104, 1, -1, 26, -46, -68, -86};
+            new byte[]{-100, 102, -35, -99, 66, -85, -55, -58, -52, 11, -74, 102, 109, -89, 1, -34,
+                    45, 43, 107, -60, 99, -21, 28, 34, 31, -100, -96, 108, 108, -18, 107, 5};
+
+    private static final String ENCODED_ADVERTISEMENT_ENCRYPTION_INFO =
+            "2091911000DE2A89ED98474AF3E41E48487E8AEBDE90014C18BCB9F9AAC5C11A1BE00A10A5DCD2C49A74BE"
+                    + "BAF0FE72FD5053B9DF8B9976C80BE0DCE8FEE83F1BFA9A89EB176CA48EE4ED5D15C6CDAD6B9E"
+                    + "41187AA6316D7BFD8E454A53971AC00836F7AB0771FF0534050037D49C6AEB18CF9F8590E5CD"
+                    + "EE2FBC330FCDC640C63F0735B7E3F02FE61A0496EF976A158AD3455D";
+    private static final byte[] METADATA_ENCRYPTION_KEY_TAG_2 =
+            new byte[]{-54, -39, 41, 16, 61, 79, -116, 14, 94, 0, 84, 45, 26, -108, 66, -48, 124,
+                    -81, 61, 56, -98, -47, 14, -19, 116, 106, -27, 123, -81, 49, 83, -42};
+
     private static final String DEVICE_NAME = "test_device";
 
+    private static final byte[] SALT_16 =
+            ArrayUtils.stringToBytes("DE2A89ED98474AF3E41E48487E8AEBDE");
+    private static final byte[] AUTHENTICITY_KEY_2 =  ArrayUtils.stringToBytes(
+            "959D2F3CAB8EE4A2DEB0255C03762CF5D39EB919300420E75A089050FB025E20");
+    private static final byte[] METADATA_ENCRYPTION_KEY_2 =  ArrayUtils.stringToBytes(
+            "EF5E9A0867560E52AE1F05FCA7E48D29");
+
+    private static final DataElement DE1 = new DataElement(571, ArrayUtils.stringToBytes(
+            "537F96FD94E13BE589F0141145CFC0EEC4F86FBDB2"));
+    private static final DataElement DE2 = new DataElement(541, ArrayUtils.stringToBytes(
+            "D301FFB24B5B"));
+    private static final DataElement DE3 = new DataElement(51, ArrayUtils.stringToBytes(
+            "EA95F07C25B75C04E1B2B8731F6A55BA379FB141"));
+    private static final DataElement DE4 = new DataElement(729, ArrayUtils.stringToBytes(
+            "2EFD3101E2311BBB108F0A7503907EAF0C2EAAA60CDA8D33A294C4CEACE0"));
+    private static final DataElement DE5 = new DataElement(411, ArrayUtils.stringToBytes("B0"));
+
     private PresenceBroadcastRequest.Builder mBuilder;
+    private PresenceBroadcastRequest.Builder mBuilderCredentialInfo;
     private PrivateCredential mPrivateCredential;
+    private PrivateCredential mPrivateCredential2;
+
     private PublicCredential mPublicCredential;
+    private PublicCredential mPublicCredential2;
 
     @Before
     public void setUp() {
         mPrivateCredential =
-                new PrivateCredential.Builder(SECRET_ID, AUTHENTICITY_KEY, IDENTITY, DEVICE_NAME)
+                new PrivateCredential.Builder(
+                        SECRET_ID, AUTHENTICITY_KEY, METADATA_ENCRYPTION_KEY, DEVICE_NAME)
+                        .setIdentityType(PresenceCredential.IDENTITY_TYPE_PRIVATE)
+                        .build();
+        mPrivateCredential2 =
+                new PrivateCredential.Builder(
+                        SECRET_ID, AUTHENTICITY_KEY_2, METADATA_ENCRYPTION_KEY_2, DEVICE_NAME)
                         .setIdentityType(PresenceCredential.IDENTITY_TYPE_PRIVATE)
                         .build();
         mPublicCredential =
                 new PublicCredential.Builder(SECRET_ID, AUTHENTICITY_KEY, PUBLIC_KEY,
                         ENCRYPTED_METADATA_BYTES, METADATA_ENCRYPTION_KEY_TAG)
                         .build();
+        mPublicCredential2 =
+                new PublicCredential.Builder(SECRET_ID, AUTHENTICITY_KEY_2, PUBLIC_KEY,
+                        ENCRYPTED_METADATA_BYTES, METADATA_ENCRYPTION_KEY_TAG_2)
+                        .build();
         mBuilder =
                 new PresenceBroadcastRequest.Builder(Collections.singletonList(MEDIUM_TYPE_BLE),
                         SALT, mPrivateCredential)
@@ -103,6 +155,16 @@
                         .addAction(PRESENCE_ACTION_2)
                         .addExtendedProperty(new DataElement(DATA_TYPE_BLE_ADDRESS, BLE_ADDRESS))
                         .addExtendedProperty(new DataElement(DATA_TYPE_MODEL_ID, MODE_ID_DATA));
+
+        mBuilderCredentialInfo =
+                new PresenceBroadcastRequest.Builder(Collections.singletonList(MEDIUM_TYPE_BLE),
+                        SALT_16, mPrivateCredential2)
+                        .setVersion(BroadcastRequest.PRESENCE_VERSION_V1)
+                        .addExtendedProperty(DE1)
+                        .addExtendedProperty(DE2)
+                        .addExtendedProperty(DE3)
+                        .addExtendedProperty(DE4)
+                        .addExtendedProperty(DE5);
     }
 
     @Test
@@ -112,36 +174,50 @@
 
         assertThat(originalAdvertisement.getActions())
                 .containsExactly(PRESENCE_ACTION_1, PRESENCE_ACTION_2);
-        assertThat(originalAdvertisement.getIdentity()).isEqualTo(IDENTITY);
+        assertThat(originalAdvertisement.getIdentity()).isEqualTo(METADATA_ENCRYPTION_KEY);
         assertThat(originalAdvertisement.getIdentityType()).isEqualTo(IDENTITY_TYPE);
-        assertThat(originalAdvertisement.getLength()).isEqualTo(66);
         assertThat(originalAdvertisement.getVersion()).isEqualTo(
                 BroadcastRequest.PRESENCE_VERSION_V1);
         assertThat(originalAdvertisement.getSalt()).isEqualTo(SALT);
         assertThat(originalAdvertisement.getDataElements())
-                .containsExactly(MODE_ID_ADDRESS_ELEMENT, BLE_ADDRESS_ELEMENT);
+                .containsExactly(PRESENCE_ACTION_DE_1, PRESENCE_ACTION_DE_2,
+                        MODE_ID_ADDRESS_ELEMENT, BLE_ADDRESS_ELEMENT);
+        assertThat(originalAdvertisement.getLength()).isEqualTo(EXTENDED_ADVERTISEMENT_BYTE_LENGTH);
+    }
+
+    @Test
+    public void test_createFromRequest_credentialInfo() {
+        ExtendedAdvertisement originalAdvertisement = ExtendedAdvertisement.createFromRequest(
+                mBuilderCredentialInfo.build());
+
+        assertThat(originalAdvertisement.getIdentity()).isEqualTo(METADATA_ENCRYPTION_KEY_2);
+        assertThat(originalAdvertisement.getIdentityType()).isEqualTo(IDENTITY_TYPE);
+        assertThat(originalAdvertisement.getVersion()).isEqualTo(
+                BroadcastRequest.PRESENCE_VERSION_V1);
+        assertThat(originalAdvertisement.getSalt()).isEqualTo(SALT_16);
+        assertThat(originalAdvertisement.getDataElements())
+                .containsExactly(DE1, DE2, DE3, DE4, DE5);
     }
 
     @Test
     public void test_createFromRequest_encodeAndDecode() {
         ExtendedAdvertisement originalAdvertisement = ExtendedAdvertisement.createFromRequest(
                 mBuilder.build());
-
         byte[] generatedBytes = originalAdvertisement.toBytes();
-
         ExtendedAdvertisement newAdvertisement =
                 ExtendedAdvertisement.fromBytes(generatedBytes, mPublicCredential);
 
         assertThat(newAdvertisement.getActions())
                 .containsExactly(PRESENCE_ACTION_1, PRESENCE_ACTION_2);
-        assertThat(newAdvertisement.getIdentity()).isEqualTo(IDENTITY);
+        assertThat(newAdvertisement.getIdentity()).isEqualTo(METADATA_ENCRYPTION_KEY);
         assertThat(newAdvertisement.getIdentityType()).isEqualTo(IDENTITY_TYPE);
-        assertThat(newAdvertisement.getLength()).isEqualTo(66);
+        assertThat(newAdvertisement.getLength()).isEqualTo(EXTENDED_ADVERTISEMENT_BYTE_LENGTH);
         assertThat(newAdvertisement.getVersion()).isEqualTo(
                 BroadcastRequest.PRESENCE_VERSION_V1);
         assertThat(newAdvertisement.getSalt()).isEqualTo(SALT);
         assertThat(newAdvertisement.getDataElements())
-                .containsExactly(MODE_ID_ADDRESS_ELEMENT, BLE_ADDRESS_ELEMENT);
+                .containsExactly(MODE_ID_ADDRESS_ELEMENT, BLE_ADDRESS_ELEMENT,
+                        PRESENCE_ACTION_DE_1, PRESENCE_ACTION_DE_2);
     }
 
     @Test
@@ -170,45 +246,77 @@
                         .setVersion(BroadcastRequest.PRESENCE_VERSION_V1)
                         .addAction(PRESENCE_ACTION_1);
         assertThat(ExtendedAdvertisement.createFromRequest(builder2.build())).isNull();
-
-        // empty action
-        PresenceBroadcastRequest.Builder builder3 =
-                new PresenceBroadcastRequest.Builder(Collections.singletonList(MEDIUM_TYPE_BLE),
-                        SALT, mPrivateCredential)
-                        .setVersion(BroadcastRequest.PRESENCE_VERSION_V1);
-        assertThat(ExtendedAdvertisement.createFromRequest(builder3.build())).isNull();
     }
 
     @Test
-    public void test_toBytes() {
+    public void test_toBytesSalt() throws Exception {
         ExtendedAdvertisement adv = ExtendedAdvertisement.createFromRequest(mBuilder.build());
         assertThat(adv.toBytes()).isEqualTo(getExtendedAdvertisementByteArray());
     }
 
     @Test
-    public void test_fromBytes() {
+    public void test_fromBytesSalt() throws Exception {
         byte[] originalBytes = getExtendedAdvertisementByteArray();
         ExtendedAdvertisement adv =
                 ExtendedAdvertisement.fromBytes(originalBytes, mPublicCredential);
 
         assertThat(adv.getActions())
                 .containsExactly(PRESENCE_ACTION_1, PRESENCE_ACTION_2);
-        assertThat(adv.getIdentity()).isEqualTo(IDENTITY);
+        assertThat(adv.getIdentity()).isEqualTo(METADATA_ENCRYPTION_KEY);
         assertThat(adv.getIdentityType()).isEqualTo(IDENTITY_TYPE);
-        assertThat(adv.getLength()).isEqualTo(66);
+        assertThat(adv.getLength()).isEqualTo(EXTENDED_ADVERTISEMENT_BYTE_LENGTH);
         assertThat(adv.getVersion()).isEqualTo(
                 BroadcastRequest.PRESENCE_VERSION_V1);
         assertThat(adv.getSalt()).isEqualTo(SALT);
         assertThat(adv.getDataElements())
-                .containsExactly(MODE_ID_ADDRESS_ELEMENT, BLE_ADDRESS_ELEMENT);
+                .containsExactly(MODE_ID_ADDRESS_ELEMENT, BLE_ADDRESS_ELEMENT,
+                        PRESENCE_ACTION_DE_1, PRESENCE_ACTION_DE_2);
+    }
+
+    @Test
+    public void test_toBytesCredentialElement() {
+        ExtendedAdvertisement adv =
+                ExtendedAdvertisement.createFromRequest(mBuilderCredentialInfo.build());
+        assertThat(ArrayUtils.bytesToStringUppercase(adv.toBytes())).isEqualTo(
+                ENCODED_ADVERTISEMENT_ENCRYPTION_INFO);
+    }
+
+    @Test
+    public void test_fromBytesCredentialElement() {
+        ExtendedAdvertisement adv =
+                ExtendedAdvertisement.fromBytes(
+                        ArrayUtils.stringToBytes(ENCODED_ADVERTISEMENT_ENCRYPTION_INFO),
+                        mPublicCredential2);
+        assertThat(adv.getIdentity()).isEqualTo(METADATA_ENCRYPTION_KEY_2);
+        assertThat(adv.getIdentityType()).isEqualTo(IDENTITY_TYPE);
+        assertThat(adv.getVersion()).isEqualTo(BroadcastRequest.PRESENCE_VERSION_V1);
+        assertThat(adv.getSalt()).isEqualTo(SALT_16);
+        assertThat(adv.getDataElements()).containsExactly(DE1, DE2, DE3, DE4, DE5);
+    }
+
+    @Test
+    public void test_fromBytes_metadataTagNotMatched_fail() throws Exception {
+        byte[] originalBytes = getExtendedAdvertisementByteArray();
+        PublicCredential credential =
+                new PublicCredential.Builder(SECRET_ID, AUTHENTICITY_KEY, PUBLIC_KEY,
+                        ENCRYPTED_METADATA_BYTES,
+                        new byte[]{113, 90, -55, 73, 25, -9, 55, -44, 102, 44, 81, -68, 101, 21, 32,
+                                92, -107, 3, 108, 90, 28, -73, 16, 49, -95, -121, 8, -45, -27, 16,
+                                6, 108})
+                        .build();
+        ExtendedAdvertisement adv =
+                ExtendedAdvertisement.fromBytes(originalBytes, credential);
+        assertThat(adv).isNull();
     }
 
     @Test
     public void test_toString() {
         ExtendedAdvertisement adv = ExtendedAdvertisement.createFromRequest(mBuilder.build());
         assertThat(adv.toString()).isEqualTo("ExtendedAdvertisement:"
-                + "<VERSION: 1, length: 66, dataElementCount: 2, identityType: 1, "
-                + "identity: [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], salt: [2, 3],"
+                + "<VERSION: 1, length: " + EXTENDED_ADVERTISEMENT_BYTE_LENGTH
+                + ", dataElementCount: 4, identityType: 1, "
+                + "identity: " + Arrays.toString(METADATA_ENCRYPTION_KEY)
+                + ", salt: [2, 3],"
                 + " actions: [1, 2]>");
     }
 
@@ -222,26 +330,22 @@
         assertThat(adv.getDataElements(DATA_TYPE_PUBLIC_IDENTITY)).isEmpty();
     }
 
-    private static byte[] getExtendedAdvertisementByteArray() {
-        ByteBuffer buffer = ByteBuffer.allocate(66);
+    private static byte[] getExtendedAdvertisementByteArray() throws Exception {
+        CryptorMicImp cryptor = CryptorMicImp.getInstance();
+        ByteBuffer buffer = ByteBuffer.allocate(EXTENDED_ADVERTISEMENT_BYTE_LENGTH);
         buffer.put((byte) 0b00100000); // Header V1
-        buffer.put((byte) 0b00100000); // Salt header: length 2, type 0
+        buffer.put(
+                (byte) (EXTENDED_ADVERTISEMENT_BYTE_LENGTH - 2)); // Section header (section length)
+
         // Salt data
-        buffer.put(SALT);
+        // Salt header: length 2, type 0
+        byte[] saltBytes = ArrayUtils.concatByteArrays(new byte[]{(byte) 0b00100000}, SALT);
+        buffer.put(saltBytes);
         // Identity header: length 16, type 1 (private identity)
-        buffer.put(new byte[]{(byte) 0b10010000, (byte) 0b00000001});
-        // Identity data
-        buffer.put(CryptorImpIdentityV1.getInstance().encrypt(IDENTITY, SALT, AUTHENTICITY_KEY));
+        byte[] identityHeader = new byte[]{(byte) 0b10010000, (byte) 0b00000001};
+        buffer.put(identityHeader);
 
         ByteBuffer deBuffer = ByteBuffer.allocate(28);
-        // Action1 header: length 1, type 6
-        deBuffer.put(new byte[]{(byte) 0b00010110});
-        // Action1 data
-        deBuffer.put((byte) PRESENCE_ACTION_1);
-        // Action2 header: length 1, type 6
-        deBuffer.put(new byte[]{(byte) 0b00010110});
-        // Action2 data
-        deBuffer.put((byte) PRESENCE_ACTION_2);
         // Ble address header: length 7, type 102
         deBuffer.put(new byte[]{(byte) 0b10000111, (byte) 0b01100101});
         // Ble address data
@@ -250,11 +354,30 @@
         deBuffer.put(new byte[]{(byte) 0b10001101, (byte) 0b00000111});
         // model id data
         deBuffer.put(MODE_ID_DATA);
+        // Action1 header: length 1, type 6
+        deBuffer.put(new byte[]{(byte) 0b00010110});
+        // Action1 data
+        deBuffer.put((byte) PRESENCE_ACTION_1);
+        // Action2 header: length 1, type 6
+        deBuffer.put(new byte[]{(byte) 0b00010110});
+        // Action2 data
+        deBuffer.put((byte) PRESENCE_ACTION_2);
+        byte[] deBytes = deBuffer.array();
+        byte[] nonce = CryptorMicImp.generateAdvNonce(SALT);
+        byte[] ciphertext =
+                cryptor.encrypt(
+                        ArrayUtils.concatByteArrays(METADATA_ENCRYPTION_KEY, deBytes),
+                        nonce, AUTHENTICITY_KEY);
+        buffer.put(ciphertext);
 
-        byte[] data = deBuffer.array();
-        CryptorImpV1 cryptor = CryptorImpV1.getInstance();
-        buffer.put(cryptor.encrypt(data, SALT, AUTHENTICITY_KEY));
-        buffer.put(cryptor.sign(data, AUTHENTICITY_KEY));
+        byte[] dataToSign = ArrayUtils.concatByteArrays(
+                PRESENCE_UUID_BYTES, /* UUID */
+                new byte[]{(byte) 0b00100000}, /* header */
+                new byte[]{(byte) (EXTENDED_ADVERTISEMENT_BYTE_LENGTH - 2)} /* sectionHeader */,
+                saltBytes, /* salt */
+                nonce, identityHeader, ciphertext);
+        byte[] mic = cryptor.sign(dataToSign, AUTHENTICITY_KEY);
+        buffer.put(mic);
 
         return buffer.array();
     }
