diff --git a/identity/TEST_MAPPING b/identity/TEST_MAPPING
index 87707a8..6444c56 100644
--- a/identity/TEST_MAPPING
+++ b/identity/TEST_MAPPING
@@ -2,6 +2,9 @@
   "presubmit": [
     {
       "name": "CtsIdentityTestCases"
+    },
+    {
+      "name": "identity-credential-util-tests"
     }
   ]
 }
diff --git a/identity/util/Android.bp b/identity/util/Android.bp
new file mode 100644
index 0000000..71d7718
--- /dev/null
+++ b/identity/util/Android.bp
@@ -0,0 +1,42 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "identity-credential-util",
+    srcs: [
+        "src/java/**/*.java",
+    ],
+    static_libs: [
+        "androidx.annotation_annotation",
+        "bouncycastle-unbundled",
+        "cbor-java",
+    ],
+}
+
+android_test {
+    name: "identity-credential-util-tests",
+    test_suites: ["general-tests"],
+    srcs: [
+        "test/java/**/*.java",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "identity-credential-util",
+        "junit",
+    ],
+}
diff --git a/identity/util/AndroidManifest.xml b/identity/util/AndroidManifest.xml
new file mode 100644
index 0000000..eece4dc
--- /dev/null
+++ b/identity/util/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.security.identity.internal">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.security.identity.internal"
+        android:label="Unit tests for com.android.security.identity.internal"/>
+
+</manifest>
+
diff --git a/identity/util/AndroidTest.xml b/identity/util/AndroidTest.xml
new file mode 100644
index 0000000..345460f
--- /dev/null
+++ b/identity/util/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for identity cred support library tests">
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="identity-credential-util-tests.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+        <option name="package" value="com.android.security.identity.internal" />
+    </test>
+</configuration>
diff --git a/identity/util/src/java/com/android/security/identity/internal/Util.java b/identity/util/src/java/com/android/security/identity/internal/Util.java
new file mode 100644
index 0000000..cd74059
--- /dev/null
+++ b/identity/util/src/java/com/android/security/identity/internal/Util.java
@@ -0,0 +1,1308 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.security.identity.internal;
+
+import android.security.identity.ResultData;
+import android.security.identity.IdentityCredentialStore;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.FeatureInfo;
+import android.os.SystemProperties;
+import android.security.keystore.KeyProperties;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.ECGenParameterSpec;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Formatter;
+import java.util.Map;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECPoint;
+
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1OctetString;
+
+import co.nstant.in.cbor.CborBuilder;
+import co.nstant.in.cbor.CborDecoder;
+import co.nstant.in.cbor.CborEncoder;
+import co.nstant.in.cbor.CborException;
+import co.nstant.in.cbor.builder.ArrayBuilder;
+import co.nstant.in.cbor.builder.MapBuilder;
+import co.nstant.in.cbor.model.AbstractFloat;
+import co.nstant.in.cbor.model.Array;
+import co.nstant.in.cbor.model.ByteString;
+import co.nstant.in.cbor.model.DataItem;
+import co.nstant.in.cbor.model.DoublePrecisionFloat;
+import co.nstant.in.cbor.model.MajorType;
+import co.nstant.in.cbor.model.NegativeInteger;
+import co.nstant.in.cbor.model.SimpleValue;
+import co.nstant.in.cbor.model.SimpleValueType;
+import co.nstant.in.cbor.model.SpecialType;
+import co.nstant.in.cbor.model.UnicodeString;
+import co.nstant.in.cbor.model.UnsignedInteger;
+
+public class Util {
+    private static final String TAG = "Util";
+
+    public static byte[] canonicalizeCbor(byte[] encodedCbor) throws CborException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(encodedCbor);
+        List<DataItem> dataItems = new CborDecoder(bais).decode();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        for(DataItem dataItem : dataItems) {
+            CborEncoder encoder = new CborEncoder(baos);
+            encoder.encode(dataItem);
+        }
+        return baos.toByteArray();
+    }
+
+
+    public static String cborPrettyPrint(byte[] encodedBytes) throws CborException {
+        StringBuilder sb = new StringBuilder();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(encodedBytes);
+        List<DataItem> dataItems = new CborDecoder(bais).decode();
+        int count = 0;
+        for (DataItem dataItem : dataItems) {
+            if (count > 0) {
+                sb.append(",\n");
+            }
+            cborPrettyPrintDataItem(sb, 0, dataItem);
+            count++;
+        }
+
+        return sb.toString();
+    }
+
+    // Returns true iff all elements in |items| are not compound (e.g. an array or a map).
+    static boolean cborAreAllDataItemsNonCompound(List<DataItem> items) {
+        for (DataItem item : items) {
+            switch (item.getMajorType()) {
+                case ARRAY:
+                case MAP:
+                    return false;
+                default:
+                    // continue inspecting other data items
+            }
+        }
+        return true;
+    }
+
+    public static void cborPrettyPrintDataItem(StringBuilder sb, int indent, DataItem dataItem) {
+        StringBuilder indentBuilder = new StringBuilder();
+        for (int n = 0; n < indent; n++) {
+            indentBuilder.append(' ');
+        }
+        String indentString = indentBuilder.toString();
+
+        if (dataItem.hasTag()) {
+            sb.append(String.format("tag %d ", dataItem.getTag().getValue()));
+        }
+
+        switch (dataItem.getMajorType()) {
+            case INVALID:
+                // TODO: throw
+                sb.append("<invalid>");
+                break;
+            case UNSIGNED_INTEGER: {
+                // Major type 0: an unsigned integer.
+                BigInteger value = ((UnsignedInteger) dataItem).getValue();
+                sb.append(value);
+            }
+            break;
+            case NEGATIVE_INTEGER: {
+                // Major type 1: a negative integer.
+                BigInteger value = ((NegativeInteger) dataItem).getValue();
+                sb.append(value);
+            }
+            break;
+            case BYTE_STRING: {
+                // Major type 2: a byte string.
+                byte[] value = ((ByteString) dataItem).getBytes();
+                sb.append("[");
+                int count = 0;
+                for (byte b : value) {
+                    if (count > 0) {
+                        sb.append(", ");
+                    }
+                    sb.append(String.format("0x%02x", b));
+                    count++;
+                }
+                sb.append("]");
+            }
+            break;
+            case UNICODE_STRING: {
+                // Major type 3: string of Unicode characters that is encoded as UTF-8 [RFC3629].
+                String value = ((UnicodeString) dataItem).getString();
+                // TODO: escape ' in |value|
+                sb.append("'" + value + "'");
+            }
+            break;
+            case ARRAY: {
+                // Major type 4: an array of data items.
+                List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
+                if (items.size() == 0) {
+                    sb.append("[]");
+                } else if (cborAreAllDataItemsNonCompound(items)) {
+                    // The case where everything fits on one line.
+                    sb.append("[");
+                    int count = 0;
+                    for (DataItem item : items) {
+                        cborPrettyPrintDataItem(sb, indent, item);
+                        if (++count < items.size()) {
+                            sb.append(", ");
+                        }
+                    }
+                    sb.append("]");
+                } else {
+                    sb.append("[\n" + indentString);
+                    int count = 0;
+                    for (DataItem item : items) {
+                        sb.append("  ");
+                        cborPrettyPrintDataItem(sb, indent + 2, item);
+                        if (++count < items.size()) {
+                            sb.append(",");
+                        }
+                        sb.append("\n" + indentString);
+                    }
+                    sb.append("]");
+                }
+            }
+            break;
+            case MAP: {
+                // Major type 5: a map of pairs of data items.
+                Collection<DataItem> keys = ((co.nstant.in.cbor.model.Map) dataItem).getKeys();
+                if (keys.size() == 0) {
+                    sb.append("{}");
+                } else {
+                    sb.append("{\n" + indentString);
+                    int count = 0;
+                    for (DataItem key : keys) {
+                        sb.append("  ");
+                        DataItem value = ((co.nstant.in.cbor.model.Map) dataItem).get(key);
+                        cborPrettyPrintDataItem(sb, indent + 2, key);
+                        sb.append(" : ");
+                        cborPrettyPrintDataItem(sb, indent + 2, value);
+                        if (++count < keys.size()) {
+                            sb.append(",");
+                        }
+                        sb.append("\n" + indentString);
+                    }
+                    sb.append("}");
+                }
+            }
+            break;
+            case TAG:
+                // Major type 6: optional semantic tagging of other major types
+                //
+                // We never encounter this one since it's automatically handled via the
+                // DataItem that is tagged.
+                throw new RuntimeException("Semantic tag data item not expected");
+
+            case SPECIAL:
+                // Major type 7: floating point numbers and simple data types that need no
+                // content, as well as the "break" stop code.
+                if (dataItem instanceof SimpleValue) {
+                    switch (((SimpleValue) dataItem).getSimpleValueType()) {
+                        case FALSE:
+                            sb.append("false");
+                            break;
+                        case TRUE:
+                            sb.append("true");
+                            break;
+                        case NULL:
+                            sb.append("null");
+                            break;
+                        case UNDEFINED:
+                            sb.append("undefined");
+                            break;
+                        case RESERVED:
+                            sb.append("reserved");
+                            break;
+                        case UNALLOCATED:
+                            sb.append("unallocated");
+                            break;
+                    }
+                } else if (dataItem instanceof DoublePrecisionFloat) {
+                    DecimalFormat df = new DecimalFormat("0",
+                            DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+                    df.setMaximumFractionDigits(340);
+                    sb.append(df.format(((DoublePrecisionFloat) dataItem).getValue()));
+                } else if (dataItem instanceof AbstractFloat) {
+                    DecimalFormat df = new DecimalFormat("0",
+                            DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+                    df.setMaximumFractionDigits(340);
+                    sb.append(df.format(((AbstractFloat) dataItem).getValue()));
+                } else {
+                    sb.append("break");
+                }
+                break;
+        }
+    }
+
+    public static byte[] encodeCbor(List<DataItem> dataItems) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        CborEncoder encoder = new CborEncoder(baos);
+        try {
+            encoder.encode(dataItems);
+        } catch (CborException e) {
+            throw new RuntimeException("Error encoding data", e);
+        }
+        return baos.toByteArray();
+    }
+
+    public static byte[] coseBuildToBeSigned(byte[] encodedProtectedHeaders,
+            byte[] payload,
+            byte[] detachedContent) {
+        CborBuilder sigStructure = new CborBuilder();
+        ArrayBuilder<CborBuilder> array = sigStructure.addArray();
+
+        array.add("Signature1");
+        array.add(encodedProtectedHeaders);
+
+        // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+        // so external_aad is the empty bstr
+        byte emptyExternalAad[] = new byte[0];
+        array.add(emptyExternalAad);
+
+        // Next field is the payload, independently of how it's transported (RFC
+        // 8152 section 4.4). Since our API specifies only one of |data| and
+        // |detachedContent| can be non-empty, it's simply just the non-empty one.
+        if (payload != null && payload.length > 0) {
+            array.add(payload);
+        } else {
+            array.add(detachedContent);
+        }
+        array.end();
+        return encodeCbor(sigStructure.build());
+    }
+
+    private static final int COSE_LABEL_ALG = 1;
+    private static final int COSE_LABEL_X5CHAIN = 33;  // temporary identifier
+
+    // From "COSE Algorithms" registry
+    private static final int COSE_ALG_ECDSA_256 = -7;
+    private static final int COSE_ALG_HMAC_256_256 = 5;
+
+    private static byte[] signatureDerToCose(byte[] signature) {
+        if (signature.length > 128) {
+            throw new RuntimeException("Unexpected length " + signature.length
+                    + ", expected less than 128");
+        }
+        if (signature[0] != 0x30) {
+            throw new RuntimeException("Unexpected first byte " + signature[0]
+                    + ", expected 0x30");
+        }
+        if ((signature[1] & 0x80) != 0x00) {
+            throw new RuntimeException("Unexpected second byte " + signature[1]
+                    + ", bit 7 shouldn't be set");
+        }
+        int rOffset = 2;
+        int rSize = signature[rOffset + 1];
+        byte[] rBytes = stripLeadingZeroes(
+            Arrays.copyOfRange(signature,rOffset + 2, rOffset + rSize + 2));
+
+        int sOffset = rOffset + 2 + rSize;
+        int sSize = signature[sOffset + 1];
+        byte[] sBytes = stripLeadingZeroes(
+            Arrays.copyOfRange(signature, sOffset + 2, sOffset + sSize + 2));
+
+        if (rBytes.length > 32) {
+            throw new RuntimeException("rBytes.length is " + rBytes.length + " which is > 32");
+        }
+        if (sBytes.length > 32) {
+            throw new RuntimeException("sBytes.length is " + sBytes.length + " which is > 32");
+        }
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            for (int n = 0; n < 32 - rBytes.length; n++) {
+                baos.write(0x00);
+            }
+            baos.write(rBytes);
+            for (int n = 0; n < 32 - sBytes.length; n++) {
+                baos.write(0x00);
+            }
+            baos.write(sBytes);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+        return baos.toByteArray();
+    }
+
+    // Adds leading 0x00 if the first encoded byte MSB is set.
+    private static byte[] encodePositiveBigInteger(BigInteger i) {
+        byte[] bytes = i.toByteArray();
+        if ((bytes[0] & 0x80) != 0) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try {
+                baos.write(0x00);
+                baos.write(bytes);
+            } catch (IOException e) {
+                e.printStackTrace();
+                throw new RuntimeException("Failed writing data", e);
+            }
+            bytes = baos.toByteArray();
+        }
+        return bytes;
+    }
+
+    private static byte[] signatureCoseToDer(byte[] signature) {
+        if (signature.length != 64) {
+            throw new RuntimeException("signature.length is " + signature.length + ", expected 64");
+        }
+        BigInteger r = new BigInteger(Arrays.copyOfRange(signature, 0, 32));
+        BigInteger s = new BigInteger(Arrays.copyOfRange(signature, 32, 64));
+        byte[] rBytes = encodePositiveBigInteger(r);
+        byte[] sBytes = encodePositiveBigInteger(s);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            baos.write(0x30);
+            baos.write(2 + rBytes.length + 2 + sBytes.length);
+            baos.write(0x02);
+            baos.write(rBytes.length);
+            baos.write(rBytes);
+            baos.write(0x02);
+            baos.write(sBytes.length);
+            baos.write(sBytes);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+        return baos.toByteArray();
+    }
+
+    public static byte[] coseSign1Sign(PrivateKey key,
+            @Nullable byte[] data,
+            byte[] detachedContent,
+            @Nullable Collection<X509Certificate> certificateChain)
+            throws NoSuchAlgorithmException, InvalidKeyException, CertificateEncodingException {
+
+        int dataLen = (data != null ? data.length : 0);
+        int detachedContentLen = (detachedContent != null ? detachedContent.length : 0);
+        if (dataLen > 0 && detachedContentLen > 0) {
+            throw new RuntimeException("data and detachedContent cannot both be non-empty");
+        }
+
+        CborBuilder protectedHeaders = new CborBuilder();
+        MapBuilder<CborBuilder> protectedHeadersMap = protectedHeaders.addMap();
+        protectedHeadersMap.put(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
+        byte[] protectedHeadersBytes = encodeCbor(protectedHeaders.build());
+
+        byte[] toBeSigned = coseBuildToBeSigned(protectedHeadersBytes, data, detachedContent);
+
+        byte[] coseSignature = null;
+        try {
+            Signature s = Signature.getInstance("SHA256withECDSA");
+            s.initSign(key);
+            s.update(toBeSigned);
+            byte[] derSignature = s.sign();
+            coseSignature = signatureDerToCose(derSignature);
+        } catch (SignatureException e) {
+            throw new RuntimeException("Error signing data");
+        }
+
+        CborBuilder builder = new CborBuilder();
+        ArrayBuilder<CborBuilder> array = builder.addArray();
+        array.add(protectedHeadersBytes);
+        MapBuilder<ArrayBuilder<CborBuilder>> unprotectedHeaders = array.addMap();
+        if (certificateChain != null && certificateChain.size() > 0) {
+            if (certificateChain.size() == 1) {
+                X509Certificate cert = certificateChain.iterator().next();
+                unprotectedHeaders.put(COSE_LABEL_X5CHAIN, cert.getEncoded());
+            } else {
+                ArrayBuilder<MapBuilder<ArrayBuilder<CborBuilder>>> x5chainsArray =
+                        unprotectedHeaders.putArray(COSE_LABEL_X5CHAIN);
+                for (X509Certificate cert : certificateChain) {
+                    x5chainsArray.add(cert.getEncoded());
+                }
+            }
+        }
+        if (data == null || data.length == 0) {
+            array.add(new SimpleValue(SimpleValueType.NULL));
+        } else {
+            array.add(data);
+        }
+        array.add(coseSignature);
+
+        return encodeCbor(builder.build());
+    }
+
+    public static boolean coseSign1CheckSignature(byte[] signatureCose1,
+            byte[] detachedContent,
+            PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(signatureCose1);
+        List<DataItem> dataItems = null;
+        try {
+            dataItems = new CborDecoder(bais).decode();
+        } catch (CborException e) {
+            throw new RuntimeException("Given signature is not valid CBOR", e);
+        }
+        if (dataItems.size() != 1) {
+            throw new RuntimeException("Expected just one data item");
+        }
+        DataItem dataItem = dataItems.get(0);
+        if (dataItem.getMajorType() != MajorType.ARRAY) {
+            throw new RuntimeException("Data item is not an array");
+        }
+        List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
+        if (items.size() < 4) {
+            throw new RuntimeException("Expected at least four items in COSE_Sign1 array");
+        }
+        if (items.get(0).getMajorType() != MajorType.BYTE_STRING) {
+            throw new RuntimeException("Item 0 (protected headers) is not a byte-string");
+        }
+        byte[] encodedProtectedHeaders =
+                ((co.nstant.in.cbor.model.ByteString) items.get(0)).getBytes();
+        byte[] payload = new byte[0];
+        if (items.get(2).getMajorType() == MajorType.SPECIAL) {
+            if (((co.nstant.in.cbor.model.Special) items.get(2)).getSpecialType()
+                != SpecialType.SIMPLE_VALUE) {
+                throw new RuntimeException("Item 2 (payload) is a special but not a simple value");
+            }
+            SimpleValue simple = (co.nstant.in.cbor.model.SimpleValue) items.get(2);
+            if (simple.getSimpleValueType() != SimpleValueType.NULL) {
+                throw new RuntimeException("Item 2 (payload) is a simple but not the value null");
+            }
+        } else if (items.get(2).getMajorType() == MajorType.BYTE_STRING) {
+            payload = ((co.nstant.in.cbor.model.ByteString) items.get(2)).getBytes();
+        } else {
+            throw new RuntimeException("Item 2 (payload) is not nil or byte-string");
+        }
+        if (items.get(3).getMajorType() != MajorType.BYTE_STRING) {
+            throw new RuntimeException("Item 3 (signature) is not a byte-string");
+        }
+        byte[] coseSignature = ((co.nstant.in.cbor.model.ByteString) items.get(3)).getBytes();
+
+        byte[] derSignature = signatureCoseToDer(coseSignature);
+
+        int dataLen = payload.length;
+        int detachedContentLen = (detachedContent != null ? detachedContent.length : 0);
+        if (dataLen > 0 && detachedContentLen > 0) {
+            throw new RuntimeException("data and detachedContent cannot both be non-empty");
+        }
+
+        byte[] toBeSigned = Util.coseBuildToBeSigned(encodedProtectedHeaders,
+                payload, detachedContent);
+
+        try {
+            Signature verifier = Signature.getInstance("SHA256withECDSA");
+            verifier.initVerify(publicKey);
+            verifier.update(toBeSigned);
+            return verifier.verify(derSignature);
+        } catch (SignatureException e) {
+            throw new RuntimeException("Error verifying signature");
+        }
+    }
+
+    // Returns the empty byte-array if no data is included in the structure.
+    //
+    // Throws RuntimeException if the given bytes aren't valid COSE_Sign1.
+    //
+    public static byte[] coseSign1GetData(byte[] signatureCose1) {
+        ByteArrayInputStream bais = new ByteArrayInputStream(signatureCose1);
+        List<DataItem> dataItems = null;
+        try {
+            dataItems = new CborDecoder(bais).decode();
+        } catch (CborException e) {
+            throw new RuntimeException("Given signature is not valid CBOR", e);
+        }
+        if (dataItems.size() != 1) {
+            throw new RuntimeException("Expected just one data item");
+        }
+        DataItem dataItem = dataItems.get(0);
+        if (dataItem.getMajorType() != MajorType.ARRAY) {
+            throw new RuntimeException("Data item is not an array");
+        }
+        List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
+        if (items.size() < 4) {
+            throw new RuntimeException("Expected at least four items in COSE_Sign1 array");
+        }
+        byte[] payload = new byte[0];
+        if (items.get(2).getMajorType() == MajorType.SPECIAL) {
+            if (((co.nstant.in.cbor.model.Special) items.get(2)).getSpecialType()
+                != SpecialType.SIMPLE_VALUE) {
+                throw new RuntimeException("Item 2 (payload) is a special but not a simple value");
+            }
+            SimpleValue simple = (co.nstant.in.cbor.model.SimpleValue) items.get(2);
+            if (simple.getSimpleValueType() != SimpleValueType.NULL) {
+                throw new RuntimeException("Item 2 (payload) is a simple but not the value null");
+            }
+        } else if (items.get(2).getMajorType() == MajorType.BYTE_STRING) {
+            payload = ((co.nstant.in.cbor.model.ByteString) items.get(2)).getBytes();
+        } else {
+            throw new RuntimeException("Item 2 (payload) is not nil or byte-string");
+        }
+        return payload;
+    }
+
+    // Returns the empty collection if no x5chain is included in the structure.
+    //
+    // Throws RuntimeException if the given bytes aren't valid COSE_Sign1.
+    //
+    public static Collection<X509Certificate> coseSign1GetX5Chain(byte[] signatureCose1)
+            throws CertificateException {
+        ArrayList<X509Certificate> ret = new ArrayList<>();
+        ByteArrayInputStream bais = new ByteArrayInputStream(signatureCose1);
+        List<DataItem> dataItems = null;
+        try {
+            dataItems = new CborDecoder(bais).decode();
+        } catch (CborException e) {
+            throw new RuntimeException("Given signature is not valid CBOR", e);
+        }
+        if (dataItems.size() != 1) {
+            throw new RuntimeException("Expected just one data item");
+        }
+        DataItem dataItem = dataItems.get(0);
+        if (dataItem.getMajorType() != MajorType.ARRAY) {
+            throw new RuntimeException("Data item is not an array");
+        }
+        List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
+        if (items.size() < 4) {
+            throw new RuntimeException("Expected at least four items in COSE_Sign1 array");
+        }
+        if (items.get(1).getMajorType() != MajorType.MAP) {
+            throw new RuntimeException("Item 1 (unprocted headers) is not a map");
+        }
+        co.nstant.in.cbor.model.Map map = (co.nstant.in.cbor.model.Map) items.get(1);
+        DataItem x5chainItem = map.get(new UnsignedInteger(COSE_LABEL_X5CHAIN));
+        if (x5chainItem != null) {
+            CertificateFactory factory = CertificateFactory.getInstance("X.509");
+            if (x5chainItem instanceof ByteString) {
+                ByteArrayInputStream certBais =
+                        new ByteArrayInputStream(((ByteString) x5chainItem).getBytes());
+                ret.add((X509Certificate) factory.generateCertificate(certBais));
+            } else if (x5chainItem instanceof Array) {
+                for (DataItem certItem : ((Array) x5chainItem).getDataItems()) {
+                    if (!(certItem instanceof ByteString)) {
+                        throw new RuntimeException(
+                            "Unexpected type for array item in x5chain value");
+                    }
+                    ByteArrayInputStream certBais =
+                            new ByteArrayInputStream(((ByteString) certItem).getBytes());
+                    ret.add((X509Certificate) factory.generateCertificate(certBais));
+                }
+            } else {
+                throw new RuntimeException("Unexpected type for x5chain value");
+            }
+        }
+        return ret;
+    }
+
+    public static byte[] coseBuildToBeMACed(byte[] encodedProtectedHeaders,
+            byte[] payload,
+            byte[] detachedContent) {
+        CborBuilder macStructure = new CborBuilder();
+        ArrayBuilder<CborBuilder> array = macStructure.addArray();
+
+        array.add("MAC0");
+        array.add(encodedProtectedHeaders);
+
+        // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+        // so external_aad is the empty bstr
+        byte emptyExternalAad[] = new byte[0];
+        array.add(emptyExternalAad);
+
+        // Next field is the payload, independently of how it's transported (RFC
+        // 8152 section 4.4). Since our API specifies only one of |data| and
+        // |detachedContent| can be non-empty, it's simply just the non-empty one.
+        if (payload != null && payload.length > 0) {
+            array.add(payload);
+        } else {
+            array.add(detachedContent);
+        }
+
+        return encodeCbor(macStructure.build());
+    }
+
+    public static byte[] coseMac0(SecretKey key,
+            @Nullable byte[] data,
+            byte[] detachedContent)
+            throws NoSuchAlgorithmException, InvalidKeyException, CertificateEncodingException {
+
+        int dataLen = (data != null ? data.length : 0);
+        int detachedContentLen = (detachedContent != null ? detachedContent.length : 0);
+        if (dataLen > 0 && detachedContentLen > 0) {
+            throw new RuntimeException("data and detachedContent cannot both be non-empty");
+        }
+
+        CborBuilder protectedHeaders = new CborBuilder();
+        MapBuilder<CborBuilder> protectedHeadersMap = protectedHeaders.addMap();
+        protectedHeadersMap.put(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
+        byte[] protectedHeadersBytes = encodeCbor(protectedHeaders.build());
+
+        byte[] toBeMACed = coseBuildToBeMACed(protectedHeadersBytes, data, detachedContent);
+
+        byte[] mac = null;
+        Mac m = Mac.getInstance("HmacSHA256");
+        m.init(key);
+        m.update(toBeMACed);
+        mac = m.doFinal();
+
+        CborBuilder builder = new CborBuilder();
+        ArrayBuilder<CborBuilder> array = builder.addArray();
+        array.add(protectedHeadersBytes);
+        MapBuilder<ArrayBuilder<CborBuilder>> unprotectedHeaders = array.addMap();
+        if (data == null || data.length == 0) {
+            array.add(new SimpleValue(SimpleValueType.NULL));
+        } else {
+            array.add(data);
+        }
+        array.add(mac);
+
+        return encodeCbor(builder.build());
+    }
+
+    public static String replaceLine(String text, int lineNumber, String replacementLine) {
+        String[] lines = text.split("\n");
+        int numLines = lines.length;
+        if (lineNumber < 0) {
+            lineNumber = numLines - (-lineNumber);
+        }
+        StringBuilder sb = new StringBuilder();
+        for (int n = 0; n < numLines; n++) {
+            if (n == lineNumber) {
+                sb.append(replacementLine);
+            } else {
+                sb.append(lines[n]);
+            }
+            // Only add terminating newline if passed-in string ends in a newline.
+            if (n == numLines - 1) {
+                if (text.endsWith(("\n"))) {
+                    sb.append('\n');
+                }
+            } else {
+                sb.append('\n');
+            }
+        }
+        return sb.toString();
+    }
+
+    public static byte[] cborEncode(DataItem dataItem) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            new CborEncoder(baos).encode(dataItem);
+        } catch (CborException e) {
+            // This should never happen and we don't want cborEncode() to throw since that
+            // would complicate all callers. Log it instead.
+            e.printStackTrace();
+            Log.e(TAG, "Error encoding DataItem");
+        }
+        return baos.toByteArray();
+    }
+
+    public static byte[] cborEncodeBoolean(boolean value) {
+        return cborEncode(new CborBuilder().add(value).build().get(0));
+    }
+
+    public static byte[] cborEncodeString(@NonNull String value) {
+        return cborEncode(new CborBuilder().add(value).build().get(0));
+    }
+
+    public static byte[] cborEncodeBytestring(@NonNull byte[] value) {
+        return cborEncode(new CborBuilder().add(value).build().get(0));
+    }
+
+    public static byte[] cborEncodeInt(long value) {
+        return cborEncode(new CborBuilder().add(value).build().get(0));
+    }
+
+    static final int CBOR_SEMANTIC_TAG_ENCODED_CBOR = 24;
+
+    public static DataItem cborToDataItem(byte[] data) {
+        ByteArrayInputStream bais = new ByteArrayInputStream(data);
+        try {
+            List<DataItem> dataItems = new CborDecoder(bais).decode();
+            if (dataItems.size() != 1) {
+                throw new RuntimeException("Expected 1 item, found " + dataItems.size());
+            }
+            return dataItems.get(0);
+        } catch (CborException e) {
+            throw new RuntimeException("Error decoding data", e);
+        }
+    }
+
+    public static boolean cborDecodeBoolean(@NonNull byte[] data) {
+        return cborToDataItem(data) == SimpleValue.TRUE;
+    }
+
+    public static String cborDecodeString(@NonNull byte[] data) {
+        return ((co.nstant.in.cbor.model.UnicodeString) cborToDataItem(data)).getString();
+    }
+
+    public static long cborDecodeInt(@NonNull byte[] data) {
+        return ((co.nstant.in.cbor.model.Number) cborToDataItem(data)).getValue().longValue();
+    }
+
+    public static byte[] cborDecodeBytestring(@NonNull byte[] data) {
+        return ((co.nstant.in.cbor.model.ByteString) cborToDataItem(data)).getBytes();
+    }
+
+    public static String getStringEntry(ResultData data, String namespaceName, String name) {
+        return Util.cborDecodeString(data.getEntry(namespaceName, name));
+    }
+
+    public static boolean getBooleanEntry(ResultData data, String namespaceName, String name) {
+        return Util.cborDecodeBoolean(data.getEntry(namespaceName, name));
+    }
+
+    public static long getIntegerEntry(ResultData data, String namespaceName, String name) {
+        return Util.cborDecodeInt(data.getEntry(namespaceName, name));
+    }
+
+    public static byte[] getBytestringEntry(ResultData data, String namespaceName, String name) {
+        return Util.cborDecodeBytestring(data.getEntry(namespaceName, name));
+    }
+
+    /*
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: ecdsa-with-SHA256
+        Issuer: CN=fake
+        Validity
+            Not Before: Jan  1 00:00:00 1970 GMT
+            Not After : Jan  1 00:00:00 2048 GMT
+        Subject: CN=fake
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (256 bit)
+                00000000  04 9b 60 70 8a 99 b6 bf  e3 b8 17 02 9e 93 eb 48  |..`p...........H|
+                00000010  23 b9 39 89 d1 00 bf a0  0f d0 2f bd 6b 11 bc d1  |#.9......./.k...|
+                00000020  19 53 54 28 31 00 f5 49  db 31 fb 9f 7d 99 bf 23  |.ST(1..I.1..}..#|
+                00000030  fb 92 04 6b 23 63 55 98  ad 24 d2 68 c4 83 bf 99  |...k#cU..$.h....|
+                00000040  62                                                |b|
+    Signature Algorithm: ecdsa-with-SHA256
+         30:45:02:20:67:ad:d1:34:ed:a5:68:3f:5b:33:ee:b3:18:a2:
+         eb:03:61:74:0f:21:64:4a:a3:2e:82:b3:92:5c:21:0f:88:3f:
+         02:21:00:b7:38:5c:9b:f2:9c:b1:27:86:37:44:df:eb:4a:b2:
+         6c:11:9a:c1:ff:b2:80:95:ce:fc:5f:26:b4:20:6e:9b:0d
+     */
+
+
+    public static @NonNull X509Certificate signPublicKeyWithPrivateKey(String keyToSignAlias,
+            String keyToSignWithAlias) {
+
+        KeyStore ks = null;
+        try {
+            ks = KeyStore.getInstance("AndroidKeyStore");
+            ks.load(null);
+
+            /* First note that KeyStore.getCertificate() returns a self-signed X.509 certificate
+             * for the key in question. As per RFC 5280, section 4.1 an X.509 certificate has the
+             * following structure:
+             *
+             *   Certificate  ::=  SEQUENCE  {
+             *        tbsCertificate       TBSCertificate,
+             *        signatureAlgorithm   AlgorithmIdentifier,
+             *        signatureValue       BIT STRING  }
+             *
+             * Conveniently, the X509Certificate class has a getTBSCertificate() method which
+             * returns the tbsCertificate blob. So all we need to do is just sign that and build
+             * signatureAlgorithm and signatureValue and combine it with tbsCertificate. We don't
+             * need a full-blown ASN.1/DER encoder to do this.
+             */
+            X509Certificate selfSignedCert = (X509Certificate) ks.getCertificate(keyToSignAlias);
+            byte[] tbsCertificate = selfSignedCert.getTBSCertificate();
+
+            KeyStore.Entry keyToSignWithEntry = ks.getEntry(keyToSignWithAlias, null);
+            Signature s = Signature.getInstance("SHA256withECDSA");
+            s.initSign(((KeyStore.PrivateKeyEntry) keyToSignWithEntry).getPrivateKey());
+            s.update(tbsCertificate);
+            byte[] signatureValue = s.sign();
+
+            /* The DER encoding for a SEQUENCE of length 128-65536 - the length is updated below.
+             *
+             * We assume - and test for below - that the final length is always going to be in
+             * this range. This is a sound assumption given we're using 256-bit EC keys.
+             */
+            byte[] sequence = new byte[]{
+                    0x30, (byte) 0x82, 0x00, 0x00
+            };
+
+            /* The DER encoding for the ECDSA with SHA-256 signature algorithm:
+             *
+             *   SEQUENCE (1 elem)
+             *      OBJECT IDENTIFIER 1.2.840.10045.4.3.2 ecdsaWithSHA256 (ANSI X9.62 ECDSA
+             *      algorithm with SHA256)
+             */
+            byte[] signatureAlgorithm = new byte[]{
+                    0x30, 0x0a, 0x06, 0x08, 0x2a, (byte) 0x86, 0x48, (byte) 0xce, 0x3d, 0x04, 0x03,
+                    0x02
+            };
+
+            /* The DER encoding for a BIT STRING with one element - the length is updated below.
+             *
+             * We assume the length of signatureValue is always going to be less than 128. This
+             * assumption works since we know ecdsaWithSHA256 signatures are always 69, 70, or
+             * 71 bytes long when DER encoded.
+             */
+            byte[] bitStringForSignature = new byte[]{0x03, 0x00, 0x00};
+
+            // Calculate sequence length and set it in |sequence|.
+            int sequenceLength = tbsCertificate.length
+                    + signatureAlgorithm.length
+                    + bitStringForSignature.length
+                    + signatureValue.length;
+            if (sequenceLength < 128 || sequenceLength > 65535) {
+                throw new Exception("Unexpected sequenceLength " + sequenceLength);
+            }
+            sequence[2] = (byte) (sequenceLength >> 8);
+            sequence[3] = (byte) (sequenceLength & 0xff);
+
+            // Calculate signatureValue length and set it in |bitStringForSignature|.
+            int signatureValueLength = signatureValue.length + 1;
+            if (signatureValueLength >= 128) {
+                throw new Exception("Unexpected signatureValueLength " + signatureValueLength);
+            }
+            bitStringForSignature[1] = (byte) signatureValueLength;
+
+            // Finally concatenate everything together.
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            baos.write(sequence);
+            baos.write(tbsCertificate);
+            baos.write(signatureAlgorithm);
+            baos.write(bitStringForSignature);
+            baos.write(signatureValue);
+            byte[] resultingCertBytes = baos.toByteArray();
+
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            ByteArrayInputStream bais = new ByteArrayInputStream(resultingCertBytes);
+            X509Certificate result = (X509Certificate) cf.generateCertificate(bais);
+            return result;
+        } catch (Exception e) {
+            throw new RuntimeException("Error signing public key with private key", e);
+        }
+    }
+
+    public static byte[] buildDeviceAuthenticationCbor(String docType,
+            byte[] encodedSessionTranscript,
+            byte[] deviceNameSpacesBytes) {
+        ByteArrayOutputStream daBaos = new ByteArrayOutputStream();
+        try {
+            ByteArrayInputStream bais = new ByteArrayInputStream(encodedSessionTranscript);
+            List<DataItem> dataItems = null;
+            dataItems = new CborDecoder(bais).decode();
+            DataItem sessionTranscript = dataItems.get(0);
+            ByteString deviceNameSpacesBytesItem = new ByteString(deviceNameSpacesBytes);
+            deviceNameSpacesBytesItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+            new CborEncoder(daBaos).encode(new CborBuilder()
+                    .addArray()
+                    .add("DeviceAuthentication")
+                    .add(sessionTranscript)
+                    .add(docType)
+                    .add(deviceNameSpacesBytesItem)
+                    .end()
+                    .build());
+        } catch (CborException e) {
+            throw new RuntimeException("Error encoding DeviceAuthentication", e);
+        }
+        return daBaos.toByteArray();
+    }
+
+    public static byte[] buildReaderAuthenticationBytesCbor(
+            byte[] encodedSessionTranscript,
+            byte[] requestMessageBytes) {
+
+        ByteArrayOutputStream daBaos = new ByteArrayOutputStream();
+        try {
+            ByteArrayInputStream bais = new ByteArrayInputStream(encodedSessionTranscript);
+            List<DataItem> dataItems = null;
+            dataItems = new CborDecoder(bais).decode();
+            DataItem sessionTranscript = dataItems.get(0);
+            ByteString requestMessageBytesItem = new ByteString(requestMessageBytes);
+            requestMessageBytesItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+            new CborEncoder(daBaos).encode(new CborBuilder()
+                    .addArray()
+                    .add("ReaderAuthentication")
+                    .add(sessionTranscript)
+                    .add(requestMessageBytesItem)
+                    .end()
+                    .build());
+        } catch (CborException e) {
+            throw new RuntimeException("Error encoding ReaderAuthentication", e);
+        }
+        byte[] readerAuthentication = daBaos.toByteArray();
+        return Util.prependSemanticTagForEncodedCbor(readerAuthentication);
+    }
+
+    public static byte[] prependSemanticTagForEncodedCbor(byte[] encodedCbor) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            ByteString taggedBytestring = new ByteString(encodedCbor);
+            taggedBytestring.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+            new CborEncoder(baos).encode(taggedBytestring);
+        } catch (CborException e) {
+            throw new RuntimeException("Error encoding with semantic tag for CBOR encoding", e);
+        }
+        return baos.toByteArray();
+    }
+
+    public static byte[] concatArrays(byte[] a, byte[] b) {
+        byte[] ret = new byte[a.length + b.length];
+        System.arraycopy(a, 0, ret, 0, a.length);
+        System.arraycopy(b, 0, ret, a.length, b.length);
+        return ret;
+    }
+
+    public static SecretKey calcEMacKeyForReader(PublicKey authenticationPublicKey,
+            PrivateKey ephemeralReaderPrivateKey,
+            byte[] encodedSessionTranscript) {
+        try {
+            KeyAgreement ka = KeyAgreement.getInstance("ECDH");
+            ka.init(ephemeralReaderPrivateKey);
+            ka.doPhase(authenticationPublicKey, true);
+            byte[] sharedSecret = ka.generateSecret();
+
+            byte[] sessionTranscriptBytes =
+                    Util.prependSemanticTagForEncodedCbor(encodedSessionTranscript);
+
+            byte[] salt = MessageDigest.getInstance("SHA-256").digest(sessionTranscriptBytes);
+            byte[] info = new byte[] {'E', 'M', 'a', 'c', 'K', 'e', 'y'};
+            byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            SecretKey secretKey = new SecretKeySpec(derivedKey, "");
+            return secretKey;
+        } catch (InvalidKeyException
+                | NoSuchAlgorithmException e) {
+            throw new RuntimeException("Error performing key agreement", e);
+        }
+    }
+
+    /**
+     * Computes an HKDF.
+     *
+     * This is based on https://github.com/google/tink/blob/master/java/src/main/java/com/google
+     * /crypto/tink/subtle/Hkdf.java
+     * which is also Copyright (c) Google and also licensed under the Apache 2 license.
+     *
+     * @param macAlgorithm the MAC algorithm used for computing the Hkdf. I.e., "HMACSHA1" or
+     *                     "HMACSHA256".
+     * @param ikm          the input keying material.
+     * @param salt         optional salt. A possibly non-secret random value. If no salt is
+     *                     provided (i.e. if
+     *                     salt has length 0) then an array of 0s of the same size as the hash
+     *                     digest is used as salt.
+     * @param info         optional context and application specific information.
+     * @param size         The length of the generated pseudorandom string in bytes. The maximal
+     *                     size is
+     *                     255.DigestSize, where DigestSize is the size of the underlying HMAC.
+     * @return size pseudorandom bytes.
+     */
+    public static byte[] computeHkdf(
+            String macAlgorithm, final byte[] ikm, final byte[] salt, final byte[] info, int size) {
+        Mac mac = null;
+        try {
+            mac = Mac.getInstance(macAlgorithm);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("No such algorithm: " + macAlgorithm, e);
+        }
+        if (size > 255 * mac.getMacLength()) {
+            throw new RuntimeException("size too large");
+        }
+        try {
+            if (salt == null || salt.length == 0) {
+                // According to RFC 5869, Section 2.2 the salt is optional. If no salt is provided
+                // then HKDF uses a salt that is an array of zeros of the same length as the hash
+                // digest.
+                mac.init(new SecretKeySpec(new byte[mac.getMacLength()], macAlgorithm));
+            } else {
+                mac.init(new SecretKeySpec(salt, macAlgorithm));
+            }
+            byte[] prk = mac.doFinal(ikm);
+            byte[] result = new byte[size];
+            int ctr = 1;
+            int pos = 0;
+            mac.init(new SecretKeySpec(prk, macAlgorithm));
+            byte[] digest = new byte[0];
+            while (true) {
+                mac.update(digest);
+                mac.update(info);
+                mac.update((byte) ctr);
+                digest = mac.doFinal();
+                if (pos + digest.length < size) {
+                    System.arraycopy(digest, 0, result, pos, digest.length);
+                    pos += digest.length;
+                    ctr++;
+                } else {
+                    System.arraycopy(digest, 0, result, pos, size - pos);
+                    break;
+                }
+            }
+            return result;
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException("Error MACing", e);
+        }
+    }
+
+    static byte[] stripLeadingZeroes(byte[] value) {
+        int n = 0;
+        while (n < value.length && value[n] == 0) {
+            n++;
+        }
+        int newLen = value.length - n;
+        byte[] ret = new byte[newLen];
+        int m = 0;
+        while (n < value.length) {
+            ret[m++] = value[n++];
+        }
+        return ret;
+    }
+
+    public static void hexdump(String name, byte[] data) {
+        int n, m, o;
+        StringBuilder sb = new StringBuilder();
+        Formatter fmt = new Formatter(sb);
+        for (n = 0; n < data.length; n += 16) {
+            fmt.format("%04x  ", n);
+            for (m = 0; m < 16 && n + m < data.length; m++) {
+                fmt.format("%02x ", data[n + m]);
+            }
+            for (o = m; o < 16; o++) {
+                sb.append("   ");
+            }
+            sb.append(" ");
+            for (m = 0; m < 16 && n + m < data.length; m++) {
+                int c = data[n + m] & 0xff;
+                fmt.format("%c", Character.isISOControl(c) ? '.' : c);
+            }
+            sb.append("\n");
+        }
+        sb.append("\n");
+        Log.e(TAG, name + ": dumping " + data.length + " bytes\n" + fmt.toString());
+    }
+
+
+    // This returns a SessionTranscript which satisfy the requirement
+    // that the uncompressed X and Y coordinates of the public key for the
+    // mDL's ephemeral key-pair appear somewhere in the encoded
+    // DeviceEngagement.
+    public static byte[] buildSessionTranscript(KeyPair ephemeralKeyPair) {
+        // Make the coordinates appear in an already encoded bstr - this
+        // mimics how the mDL COSE_Key appear as encoded data inside the
+        // encoded DeviceEngagement
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            ECPoint w = ((ECPublicKey) ephemeralKeyPair.getPublic()).getW();
+            // X and Y are always positive so for interop we remove any leading zeroes
+            // inserted by the BigInteger encoder.
+            byte[] x = stripLeadingZeroes(w.getAffineX().toByteArray());
+            byte[] y = stripLeadingZeroes(w.getAffineY().toByteArray());
+            baos.write(new byte[]{42});
+            baos.write(x);
+            baos.write(y);
+            baos.write(new byte[]{43, 44});
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+        byte[] blobWithCoords = baos.toByteArray();
+
+        baos = new ByteArrayOutputStream();
+        try {
+            new CborEncoder(baos).encode(new CborBuilder()
+                    .addArray()
+                    .add(blobWithCoords)
+                    .end()
+                    .build());
+        } catch (CborException e) {
+            e.printStackTrace();
+            return null;
+        }
+        ByteString encodedDeviceEngagementItem = new ByteString(baos.toByteArray());
+        ByteString encodedEReaderKeyItem = new ByteString(cborEncodeString("doesn't matter"));
+        encodedDeviceEngagementItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+        encodedEReaderKeyItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+
+        baos = new ByteArrayOutputStream();
+        try {
+            new CborEncoder(baos).encode(new CborBuilder()
+                    .addArray()
+                    .add(encodedDeviceEngagementItem)
+                    .add(encodedEReaderKeyItem)
+                    .end()
+                    .build());
+        } catch (CborException e) {
+            e.printStackTrace();
+            return null;
+        }
+        return baos.toByteArray();
+    }
+
+    /*
+     * Helper function to create a CBOR data for requesting data items. The IntentToRetain
+     * value will be set to false for all elements.
+     *
+     * <p>The returned CBOR data conforms to the following CDDL schema:</p>
+     *
+     * <pre>
+     *   ItemsRequest = {
+     *     ? "docType" : DocType,
+     *     "nameSpaces" : NameSpaces,
+     *     ? "RequestInfo" : {* tstr => any} ; Additional info the reader wants to provide
+     *   }
+     *
+     *   NameSpaces = {
+     *     + NameSpace => DataElements     ; Requested data elements for each NameSpace
+     *   }
+     *
+     *   DataElements = {
+     *     + DataElement => IntentToRetain
+     *   }
+     *
+     *   DocType = tstr
+     *
+     *   DataElement = tstr
+     *   IntentToRetain = bool
+     *   NameSpace = tstr
+     * </pre>
+     *
+     * @param entriesToRequest       The entries to request, organized as a map of namespace
+     *                               names with each value being a collection of data elements
+     *                               in the given namespace.
+     * @param docType                  The document type or {@code null} if there is no document
+     *                                 type.
+     * @return CBOR data conforming to the CDDL mentioned above.
+     */
+    public static @NonNull byte[] createItemsRequest(
+            @NonNull Map<String, Collection<String>> entriesToRequest,
+            @Nullable String docType) {
+        CborBuilder builder = new CborBuilder();
+        MapBuilder<CborBuilder> mapBuilder = builder.addMap();
+        if (docType != null) {
+            mapBuilder.put("docType", docType);
+        }
+
+        MapBuilder<MapBuilder<CborBuilder>> nsMapBuilder = mapBuilder.putMap("nameSpaces");
+        for (String namespaceName : entriesToRequest.keySet()) {
+            Collection<String> entryNames = entriesToRequest.get(namespaceName);
+            MapBuilder<MapBuilder<MapBuilder<CborBuilder>>> entryNameMapBuilder =
+                    nsMapBuilder.putMap(namespaceName);
+            for (String entryName : entryNames) {
+                entryNameMapBuilder.put(entryName, false);
+            }
+        }
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        CborEncoder encoder = new CborEncoder(baos);
+        try {
+            encoder.encode(builder.build());
+        } catch (CborException e) {
+            throw new RuntimeException("Error encoding CBOR", e);
+        }
+        return baos.toByteArray();
+    }
+
+    public static KeyPair createEphemeralKeyPair() {
+        try {
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC);
+            ECGenParameterSpec ecSpec = new ECGenParameterSpec("prime256v1");
+            kpg.initialize(ecSpec);
+            KeyPair keyPair = kpg.generateKeyPair();
+            return keyPair;
+        } catch (NoSuchAlgorithmException
+                | InvalidAlgorithmParameterException e) {
+            throw new RuntimeException("Error generating ephemeral key-pair", e);
+        }
+    }
+
+    public static byte[] getPopSha256FromAuthKeyCert(X509Certificate cert) {
+        byte[] octetString = cert.getExtensionValue("1.3.6.1.4.1.11129.2.1.26");
+        if (octetString == null) {
+            return null;
+        }
+        Util.hexdump("octetString", octetString);
+
+        try {
+            ASN1InputStream asn1InputStream = new ASN1InputStream(octetString);
+            byte[] cborBytes = ((ASN1OctetString) asn1InputStream.readObject()).getOctets();
+            Util.hexdump("cborBytes", cborBytes);
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(cborBytes);
+            List<DataItem> dataItems = new CborDecoder(bais).decode();
+            if (dataItems.size() != 1) {
+                throw new RuntimeException("Expected 1 item, found " + dataItems.size());
+            }
+            if (!(dataItems.get(0) instanceof co.nstant.in.cbor.model.Array)) {
+                throw new RuntimeException("Item is not a map");
+            }
+            co.nstant.in.cbor.model.Array array = (co.nstant.in.cbor.model.Array) dataItems.get(0);
+            List<DataItem> items = array.getDataItems();
+            if (items.size() < 2) {
+                throw new RuntimeException(
+                        "Expected at least 2 array items, found " + items.size());
+            }
+            if (!(items.get(0) instanceof UnicodeString)) {
+                throw new RuntimeException("First array item is not a string");
+            }
+            String id = ((UnicodeString) items.get(0)).getString();
+            if (!id.equals("ProofOfBinding")) {
+                throw new RuntimeException("Expected ProofOfBinding, got " + id);
+            }
+            if (!(items.get(1) instanceof ByteString)) {
+                throw new RuntimeException("Second array item is not a bytestring");
+            }
+            byte[] popSha256 = ((ByteString) items.get(1)).getBytes();
+            if (popSha256.length != 32) {
+                throw new RuntimeException(
+                        "Expected bstr to be 32 bytes, it is " + popSha256.length);
+            }
+            return popSha256;
+        } catch (IOException e) {
+            throw new RuntimeException("Error decoding extension data", e);
+        } catch (CborException e) {
+            throw new RuntimeException("Error decoding data", e);
+        }
+    }
+
+}
diff --git a/identity/util/test/java/com/android/security/identity/internal/HkdfTest.java b/identity/util/test/java/com/android/security/identity/internal/HkdfTest.java
new file mode 100644
index 0000000..6a75090
--- /dev/null
+++ b/identity/util/test/java/com/android/security/identity/internal/HkdfTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.security.identity.internal;
+
+import androidx.test.runner.AndroidJUnit4;
+import com.android.security.identity.internal.Util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.GeneralSecurityException;
+import java.util.Random;
+
+/*
+ * This is based on https://github.com/google/tink/blob/master/java/src/test/java/com/google
+ * /crypto/tink/subtle/HkdfTest.java
+ * which is also Copyright (c) Google and licensed under the Apache 2 license.
+ */
+@RunWith(AndroidJUnit4.class)
+public class HkdfTest {
+
+    static Random sRandom = new Random();
+
+    /** Encodes a byte array to hex. */
+    static String hexEncode(final byte[] bytes) {
+        String chars = "0123456789abcdef";
+        StringBuilder result = new StringBuilder(2 * bytes.length);
+        for (byte b : bytes) {
+            // convert to unsigned
+            int val = b & 0xff;
+            result.append(chars.charAt(val / 16));
+            result.append(chars.charAt(val % 16));
+        }
+        return result.toString();
+    }
+
+    /** Decodes a hex string to a byte array. */
+    static byte[] hexDecode(String hex) {
+        if (hex.length() % 2 != 0) {
+            throw new IllegalArgumentException("Expected a string of even length");
+        }
+        int size = hex.length() / 2;
+        byte[] result = new byte[size];
+        for (int i = 0; i < size; i++) {
+            int hi = Character.digit(hex.charAt(2 * i), 16);
+            int lo = Character.digit(hex.charAt(2 * i + 1), 16);
+            if ((hi == -1) || (lo == -1)) {
+                throw new IllegalArgumentException("input is not hexadecimal");
+            }
+            result[i] = (byte) (16 * hi + lo);
+        }
+        return result;
+    }
+
+    static byte[] randBytes(int numBytes) {
+        byte[] bytes = new byte[numBytes];
+        sRandom.nextBytes(bytes);
+        return bytes;
+    }
+
+    @Test
+    public void testNullSaltOrInfo() throws Exception {
+        byte[] ikm = randBytes(20);
+        byte[] info = randBytes(20);
+        int size = 40;
+
+        byte[] hkdfWithNullSalt = Util.computeHkdf("HmacSha256", ikm, null, info, size);
+        byte[] hkdfWithEmptySalt = Util.computeHkdf("HmacSha256", ikm, new byte[0], info, size);
+        assertArrayEquals(hkdfWithNullSalt, hkdfWithEmptySalt);
+
+        byte[] salt = randBytes(20);
+        byte[] hkdfWithNullInfo = Util.computeHkdf("HmacSha256", ikm, salt, null, size);
+        byte[] hkdfWithEmptyInfo = Util.computeHkdf("HmacSha256", ikm, salt, new byte[0], size);
+        assertArrayEquals(hkdfWithNullInfo, hkdfWithEmptyInfo);
+    }
+
+    @Test
+    public void testInvalidCodeSize() throws Exception {
+        try {
+            Util.computeHkdf("HmacSha256", new byte[0], new byte[0], new byte[0], 32 * 256);
+            fail("Invalid size, should have thrown exception");
+        } catch (RuntimeException expected) {
+
+            // Expected
+        }
+    }
+
+    /**
+     * Tests the implementation against the test vectors from RFC 5869.
+     */
+    @Test
+    public void testVectors() throws Exception {
+        // Test case 1
+        assertEquals(
+                "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf"
+                + "1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+                computeHkdfHex("HmacSha256",
+                        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+                        "000102030405060708090a0b0c",
+                        "f0f1f2f3f4f5f6f7f8f9",
+                        42));
+
+        // Test case 2
+        assertEquals(
+                "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c"
+                        + "59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71"
+                        + "cc30c58179ec3e87c14c01d5c1f3434f1d87",
+                computeHkdfHex("HmacSha256",
+                        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
+                                + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
+                                + "404142434445464748494a4b4c4d4e4f",
+                        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
+                                + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
+                                + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
+                        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
+                                + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef"
+                                + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+                        82));
+
+        // Test case 3: salt is empty
+        assertEquals(
+                "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d"
+                        + "9d201395faa4b61a96c8",
+                computeHkdfHex("HmacSha256",
+                        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "",
+                        42));
+
+        // Test Case 4
+        assertEquals(
+                "085a01ea1b10f36933068b56efa5ad81a4f14b822f"
+                + "5b091568a9cdd4f155fda2c22e422478d305f3f896",
+                computeHkdfHex(
+                        "HmacSha1",
+                        "0b0b0b0b0b0b0b0b0b0b0b",
+                        "000102030405060708090a0b0c",
+                        "f0f1f2f3f4f5f6f7f8f9",
+                        42));
+
+        // Test Case 5
+        assertEquals(
+                "0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe"
+                        + "8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e"
+                        + "927336d0441f4c4300e2cff0d0900b52d3b4",
+                computeHkdfHex(
+                        "HmacSha1",
+                        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
+                                + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
+                                + "404142434445464748494a4b4c4d4e4f",
+                        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
+                                + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
+                                + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
+                        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
+                                + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef"
+                                + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+                        82));
+
+        // Test Case 6: salt is empty
+        assertEquals(
+                "0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0"
+                        + "ea00033de03984d34918",
+                computeHkdfHex("HmacSha1", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "",
+                        42));
+
+        // Test Case 7
+        assertEquals(
+                "2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5"
+                        + "673a081d70cce7acfc48",
+                computeHkdfHex("HmacSha1", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "", "",
+                        42));
+    }
+
+    /**
+     * Test version of Hkdf where all inputs and outputs are hexadecimal.
+     */
+    private String computeHkdfHex(String macAlgorithm, String ikmHex, String saltHex,
+            String infoHex,
+            int size) throws GeneralSecurityException {
+        return hexEncode(
+                Util.computeHkdf(macAlgorithm, hexDecode(ikmHex), hexDecode(saltHex),
+                        hexDecode(infoHex), size));
+    }
+
+}
diff --git a/identity/util/test/java/com/android/security/identity/internal/UtilUnitTests.java b/identity/util/test/java/com/android/security/identity/internal/UtilUnitTests.java
new file mode 100644
index 0000000..9c27c14
--- /dev/null
+++ b/identity/util/test/java/com/android/security/identity/internal/UtilUnitTests.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.security.identity.internal;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import com.android.security.identity.internal.Util;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import java.security.cert.X509Certificate;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import co.nstant.in.cbor.CborBuilder;
+import co.nstant.in.cbor.CborDecoder;
+import co.nstant.in.cbor.CborEncoder;
+import co.nstant.in.cbor.CborException;
+import co.nstant.in.cbor.builder.ArrayBuilder;
+import co.nstant.in.cbor.model.ByteString;
+import co.nstant.in.cbor.model.DataItem;
+import co.nstant.in.cbor.model.DoublePrecisionFloat;
+import co.nstant.in.cbor.model.HalfPrecisionFloat;
+import co.nstant.in.cbor.model.NegativeInteger;
+import co.nstant.in.cbor.model.SimpleValue;
+import co.nstant.in.cbor.model.SimpleValueType;
+import co.nstant.in.cbor.model.SinglePrecisionFloat;
+import co.nstant.in.cbor.model.UnicodeString;
+import co.nstant.in.cbor.model.UnsignedInteger;
+
+@RunWith(AndroidJUnit4.class)
+public class UtilUnitTests {
+    @Test
+    public void prettyPrintMultipleCompleteTypes() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new CborBuilder()
+                .add("text")                // add string
+                .add(1234)                  // add integer
+                .add(new byte[]{0x10})   // add byte array
+                .addArray()                 // add array
+                .add(1)
+                .add("text")
+                .end()
+                .build());
+        assertEquals("'text',\n"
+                + "1234,\n"
+                + "[0x10],\n"
+                + "[1, 'text']", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintString() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new UnicodeString("foobar"));
+        assertEquals("'foobar'", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintBytestring() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new ByteString(new byte[]{1, 2, 33, (byte) 254}));
+        assertEquals("[0x01, 0x02, 0x21, 0xfe]", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintUnsignedInteger() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new UnsignedInteger(42));
+        assertEquals("42", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintNegativeInteger() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new NegativeInteger(-42));
+        assertEquals("-42", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintDouble() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new DoublePrecisionFloat(1.1));
+        assertEquals("1.1", Util.cborPrettyPrint(baos.toByteArray()));
+
+        baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new DoublePrecisionFloat(-42.0000000001));
+        assertEquals("-42.0000000001", Util.cborPrettyPrint(baos.toByteArray()));
+
+        baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new DoublePrecisionFloat(-5));
+        assertEquals("-5", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintFloat() throws CborException {
+        ByteArrayOutputStream baos;
+
+        // TODO: These two tests yield different results on different devices, disable for now
+        /*
+        baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new SinglePrecisionFloat(1.1f));
+        assertEquals("1.100000023841858", Util.cborPrettyPrint(baos.toByteArray()));
+
+        baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new SinglePrecisionFloat(-42.0001f));
+        assertEquals("-42.000099182128906", Util.cborPrettyPrint(baos.toByteArray()));
+        */
+
+        baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new SinglePrecisionFloat(-5f));
+        assertEquals("-5", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintHalfFloat() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new HalfPrecisionFloat(1.1f));
+        assertEquals("1.099609375", Util.cborPrettyPrint(baos.toByteArray()));
+
+        baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new HalfPrecisionFloat(-42.0001f));
+        assertEquals("-42", Util.cborPrettyPrint(baos.toByteArray()));
+
+        baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new HalfPrecisionFloat(-5f));
+        assertEquals("-5", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintFalse() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.FALSE));
+        assertEquals("false", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintTrue() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.TRUE));
+        assertEquals("true", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintNull() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.NULL));
+        assertEquals("null", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintUndefined() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.UNDEFINED));
+        assertEquals("undefined", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintTag() throws CborException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new CborBuilder()
+                        .addTag(0)
+                        .add("ABC")
+                        .build());
+        byte[] data = baos.toByteArray();
+        assertEquals("tag 0 'ABC'", Util.cborPrettyPrint(data));
+    }
+
+    @Test
+    public void prettyPrintArrayNoCompounds() throws CborException {
+        // If an array has no compound elements, no newlines are used.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new CborBuilder()
+                .addArray()                 // add array
+                .add(1)
+                .add("text")
+                .add(new ByteString(new byte[]{1, 2, 3}))
+                .end()
+                .build());
+        assertEquals("[1, 'text', [0x01, 0x02, 0x03]]", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintArray() throws CborException {
+        // This array contains a compound value so will use newlines
+        CborBuilder array = new CborBuilder();
+        ArrayBuilder<CborBuilder> arrayBuilder = array.addArray();
+        arrayBuilder.add(2);
+        arrayBuilder.add(3);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new CborBuilder()
+                .addArray()                 // add array
+                .add(1)
+                .add("text")
+                .add(new ByteString(new byte[]{1, 2, 3}))
+                .add(array.build().get(0))
+                .end()
+                .build());
+        assertEquals("[\n"
+                + "  1,\n"
+                + "  'text',\n"
+                + "  [0x01, 0x02, 0x03],\n"
+                + "  [2, 3]\n"
+                + "]", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void prettyPrintMap() throws CborException {
+        // If an array has no compound elements, no newlines are used.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new CborEncoder(baos).encode(new CborBuilder()
+                .addMap()
+                .put("Foo", 42)
+                .put("Bar", "baz")
+                .put(43, 44)
+                .put(new UnicodeString("bstr"), new ByteString(new byte[]{1, 2, 3}))
+                .put(new ByteString(new byte[]{1, 2, 3}), new UnicodeString("other way"))
+                .end()
+                .build());
+        assertEquals("{\n"
+                + "  43 : 44,\n"
+                + "  [0x01, 0x02, 0x03] : 'other way',\n"
+                + "  'Bar' : 'baz',\n"
+                + "  'Foo' : 42,\n"
+                + "  'bstr' : [0x01, 0x02, 0x03]\n"
+                + "}", Util.cborPrettyPrint(baos.toByteArray()));
+    }
+
+    @Test
+    public void testCanonicalizeCbor() throws Exception {
+        // {"one":1, 2:"two"}
+        byte[] first =
+                new byte[]{(byte) 0xA2, 0x63, 0x6F, 0x6E, 0x65, 0x01, 0x02, 0x63, 0x74, 0x77, 0x6F};
+
+        // {2: "two", "one": 1}
+        byte[] second =
+                new byte[]{(byte) 0xA2, 0x02, 0x63, 0x74, 0x77, 0x6F, 0x63, 0x6F, 0x6E, 0x65, 0x01};
+
+        assertArrayEquals(Util.canonicalizeCbor(first), Util.canonicalizeCbor(second));
+    }
+
+    @Test
+    public void cborEncodeDecodeSingle() throws Exception {
+        List<DataItem> items = new CborBuilder()
+                .addMap().put(1,"one").put("one", 1).end()
+                .addArray().add(42).add(true).addMap().end().end()
+                .add("STRING")
+                .build();
+        for (DataItem item: items) {
+            assertEquals(item, Util.cborToDataItem(Util.cborEncode(item)));
+        }
+    }
+
+    @Test
+    public void cborEncodeDecodeBoolean() {
+        assertEquals(true, Util.cborDecodeBoolean(Util.cborEncodeBoolean(true)));
+        assertEquals(false, Util.cborDecodeBoolean(Util.cborEncodeBoolean(false)));
+    }
+
+    @Test
+    public void cborEncodeDecodeString() {
+        assertEquals("foo bar", Util.cborDecodeString(Util.cborEncodeString("foo bar")));
+    }
+
+    @Test
+    public void cborEncodeDecodeBytestring() {
+        byte[] bits = new byte[256];
+        for (int i = 0; i < bits.length; ++i) {
+            bits[i] = (byte)i;
+        }
+        assertArrayEquals(bits, Util.cborDecodeBytestring(Util.cborEncodeBytestring(bits)));
+    }
+
+    @Test
+    public void cborEncodeDecodeInt() {
+        assertEquals(0, Util.cborDecodeInt(Util.cborEncodeInt(0)));
+        assertEquals(Integer.MAX_VALUE, Util.cborDecodeInt(Util.cborEncodeInt(Integer.MAX_VALUE)));
+        assertEquals(Integer.MIN_VALUE, Util.cborDecodeInt(Util.cborEncodeInt(Integer.MIN_VALUE)));
+    }
+
+    @Test
+    public void prependSemanticTagForEncodedCbor() throws Exception {
+        byte[] inputBytes = new byte[] {1, 2, 3, 4};
+        byte[] encodedInput = Util.cborEncodeBytestring(inputBytes);
+        byte[] encodedWithTag = Util.prependSemanticTagForEncodedCbor(encodedInput);
+
+        ByteString decodedWithTag = (ByteString)Util.cborToDataItem(encodedWithTag);
+        assertEquals(decodedWithTag.getTag().getValue(), 24);  // RFC 8949 defines 24
+
+        byte[] decodedBytes = Util.cborDecodeBytestring(decodedWithTag.getBytes());
+        assertArrayEquals(inputBytes, decodedBytes);
+    }
+
+    private KeyPair coseGenerateKeyPair() throws Exception {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance(
+            KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+        KeyGenParameterSpec.Builder builder =
+                new KeyGenParameterSpec.Builder(
+                    "coseTestKeyPair",
+                    KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                        .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512);
+        kpg.initialize(builder.build());
+        return kpg.generateKeyPair();
+    }
+
+    @Test
+    public void coseSignAndVerify() throws Exception {
+        KeyPair keyPair = coseGenerateKeyPair();
+        byte[] data = new byte[] {0x10, 0x11, 0x12, 0x13};
+        byte[] detachedContent = new byte[] {};
+        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, null);
+        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
+        assertArrayEquals(data, Util.coseSign1GetData(sig));
+        assertEquals(new ArrayList() {}, Util.coseSign1GetX5Chain(sig));
+    }
+
+    @Test
+    public void coseSignAndVerifyDetachedContent() throws Exception {
+        KeyPair keyPair = coseGenerateKeyPair();
+        byte[] data = new byte[] {};
+        byte[] detachedContent = new byte[] {0x20, 0x21, 0x22, 0x23, 0x24};
+        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, null);
+        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
+        assertArrayEquals(data, Util.coseSign1GetData(sig));
+        assertEquals(new ArrayList() {}, Util.coseSign1GetX5Chain(sig));
+    }
+
+    @Test
+    public void coseSignAndVerifySingleCertificate() throws Exception {
+        KeyPair keyPair = coseGenerateKeyPair();
+        byte[] data = new byte[] {};
+        byte[] detachedContent = new byte[] {0x20, 0x21, 0x22, 0x23, 0x24};
+        ArrayList<X509Certificate> certs = new ArrayList() {};
+        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
+        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, certs);
+        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
+        assertArrayEquals(data, Util.coseSign1GetData(sig));
+        assertEquals(certs, Util.coseSign1GetX5Chain(sig));
+    }
+
+    @Test
+    public void coseSignAndVerifyMultipleCertificates() throws Exception {
+        KeyPair keyPair = coseGenerateKeyPair();
+        byte[] data = new byte[] {};
+        byte[] detachedContent = new byte[] {0x20, 0x21, 0x22, 0x23, 0x24};
+        ArrayList<X509Certificate> certs = new ArrayList() {};
+        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
+        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
+        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
+        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, certs);
+        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
+        assertArrayEquals(data, Util.coseSign1GetData(sig));
+        assertEquals(certs, Util.coseSign1GetX5Chain(sig));
+    }
+
+    @Test
+    public void coseMac0() throws Exception {
+        SecretKey secretKey = new SecretKeySpec(new byte[32], "");
+        byte[] data = new byte[] {0x10, 0x11, 0x12, 0x13};
+        byte[] detachedContent = new byte[] {};
+        byte[] mac = Util.coseMac0(secretKey, data, detachedContent);
+        assertEquals("[\n"
+                + "  [0xa1, 0x01, 0x05],\n"
+                + "  {},\n"
+                + "  [0x10, 0x11, 0x12, 0x13],\n"
+                + "  [0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, "
+                + "0xd8, 0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, "
+                + "0x5e, 0xbb, 0xe2, 0x2d, 0x42, 0xbe, 0x53]\n"
+                + "]", Util.cborPrettyPrint(mac));
+    }
+
+    @Test
+    public void coseMac0DetachedContent() throws Exception {
+        SecretKey secretKey = new SecretKeySpec(new byte[32], "");
+        byte[] data = new byte[] {};
+        byte[] detachedContent = new byte[] {0x10, 0x11, 0x12, 0x13};
+        byte[] mac = Util.coseMac0(secretKey, data, detachedContent);
+        // Same HMAC as in coseMac0 test, only difference is that payload is null.
+        assertEquals("[\n"
+                + "  [0xa1, 0x01, 0x05],\n"
+                + "  {},\n"
+                + "  null,\n"
+                + "  [0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, "
+                + "0xd8, 0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, "
+                + "0x5e, 0xbb, 0xe2, 0x2d, 0x42, 0xbe, 0x53]\n"
+                + "]", Util.cborPrettyPrint(mac));
+    }
+
+    @Test
+    public void replaceLineTest() {
+        assertEquals("foo",
+                Util.replaceLine("Hello World", 0, "foo"));
+        assertEquals("foo\n",
+                Util.replaceLine("Hello World\n", 0, "foo"));
+        assertEquals("Hello World",
+                Util.replaceLine("Hello World", 1, "foo"));
+        assertEquals("Hello World\n",
+                Util.replaceLine("Hello World\n", 1, "foo"));
+        assertEquals("foo\ntwo\nthree",
+                Util.replaceLine("one\ntwo\nthree", 0, "foo"));
+        assertEquals("one\nfoo\nthree",
+                Util.replaceLine("one\ntwo\nthree", 1, "foo"));
+        assertEquals("one\ntwo\nfoo",
+                Util.replaceLine("one\ntwo\nthree", 2, "foo"));
+        assertEquals("one\ntwo\nfoo",
+                Util.replaceLine("one\ntwo\nthree", -1, "foo"));
+        assertEquals("one\ntwo\nthree\nfoo",
+                Util.replaceLine("one\ntwo\nthree\nfour", -1, "foo"));
+        assertEquals("one\ntwo\nfoo\nfour",
+                Util.replaceLine("one\ntwo\nthree\nfour", -2, "foo"));
+    }
+
+}
