Some code reorginazation and comments
diff --git a/errors/errors.go b/errors/errors.go
index 8154fc5..4b76b41 100644
--- a/errors/errors.go
+++ b/errors/errors.go
@@ -1,5 +1,5 @@
-// This is a thin wrapper over the `pkg/errors` package.  It decorates the
-// base package with the following functionality:
+// This is a thin wrapper over the `pkg/errors` package.  It decorates this
+// package with the following functionality:
 //
 // 1. Wrap and Wrapf produce an error with exactly one stack trace.  If the
 // wrapped error already contains a stack trace, these functions just append
@@ -26,16 +26,21 @@
 	return pkgerrors.Cause(err)
 }
 
-// Errorf formats an error
+// Errorf formats according to a format specifier and returns the string
+// as a value that satisfies error.
+// Errorf also records the stack trace at the point it was called.
 func Errorf(format string, args ...interface{}) error {
 	return pkgerrors.Errorf(format, args...)
 }
 
-// New creates a new error
+// New returns an error with the supplied message.
+// New also records the stack trace at the point it was called.
 func New(message string) error {
 	return pkgerrors.New(message)
 }
 
+// Wrap returns an error annotating err with a stack trace at the point Wrap is
+// called, and the supplied message.  If err is nil, Wrap returns nil.
 func Wrap(err error, message string) error {
 	if _, ok := err.(stackTracer); !ok {
 		return pkgerrors.Wrap(err, message)
@@ -45,10 +50,14 @@
 	}
 }
 
+// Wrapf returns an error annotating err with a stack trace at the point Wrapf
+// is called, and the format specifier.  If err is nil, Wrapf returns nil.
 func Wrapf(err error, format string, args ...interface{}) error {
 	return Wrap(err, fmt.Sprintf(format, args...))
 }
 
+// WithStack annotates err with a stack trace at the point WithStack was called.
+// If err is nil, WithStack returns nil.
 func WithStack(err error) error {
 	if _, ok := err.(stackTracer); !ok {
 		return pkgerrors.WithStack(err)
@@ -57,6 +66,7 @@
 	}
 }
 
+// HasStackTrace tells you if the given error contains a stack trace.
 func HasStackTrace(err error) bool {
 	_, ok := err.(stackTracer)
 	return ok
diff --git a/flash/flash.go b/flash/flash.go
index 6b85814..5903fb2 100644
--- a/flash/flash.go
+++ b/flash/flash.go
@@ -99,6 +99,10 @@
 }
 
 func areasDistinct(a FlashArea, b FlashArea) bool {
+	if a.Device != b.Device {
+		return true
+	}
+
 	var lo FlashArea
 	var hi FlashArea
 
@@ -110,7 +114,7 @@
 		hi = a
 	}
 
-	return lo.Device != hi.Device || lo.Offset+lo.Size <= hi.Offset
+	return lo.Offset+lo.Size <= hi.Offset
 }
 
 // @return overlapping-areas, id-conflicts.
diff --git a/image/image.go b/image/image.go
index 5c489c5..7289f52 100644
--- a/image/image.go
+++ b/image/image.go
@@ -20,16 +20,11 @@
 package image
 
 import (
-	"bytes"
 	"encoding/binary"
-	"encoding/hex"
-	"encoding/json"
 	"fmt"
 	"io"
 	"io/ioutil"
 	"os"
-	"strconv"
-	"strings"
 
 	"github.com/apache/mynewt-artifact/errors"
 	"github.com/apache/mynewt-artifact/sec"
@@ -150,120 +145,11 @@
 		tlvType == IMAGE_TLV_ECDSA256
 }
 
-func ParseVersion(versStr string) (ImageVersion, error) {
-	var err error
-	var major uint64
-	var minor uint64
-	var rev uint64
-	var buildNum uint64
-	var ver ImageVersion
-
-	components := strings.Split(versStr, ".")
-	major, err = strconv.ParseUint(components[0], 10, 8)
-	if err != nil {
-		return ver, errors.Errorf("invalid version string %s", versStr)
-	}
-	if len(components) > 1 {
-		minor, err = strconv.ParseUint(components[1], 10, 8)
-		if err != nil {
-			return ver, errors.Errorf("invalid version string %s", versStr)
-		}
-	}
-	if len(components) > 2 {
-		rev, err = strconv.ParseUint(components[2], 10, 16)
-		if err != nil {
-			return ver, errors.Errorf("invalid version string %s", versStr)
-		}
-	}
-	if len(components) > 3 {
-		buildNum, err = strconv.ParseUint(components[3], 10, 32)
-		if err != nil {
-			return ver, errors.Errorf("invalid version string %s", versStr)
-		}
-	}
-
-	ver.Major = uint8(major)
-	ver.Minor = uint8(minor)
-	ver.Rev = uint16(rev)
-	ver.BuildNum = uint32(buildNum)
-	return ver, nil
-}
-
 func (ver ImageVersion) String() string {
 	return fmt.Sprintf("%d.%d.%d.%d",
 		ver.Major, ver.Minor, ver.Rev, ver.BuildNum)
 }
 
-func (h *ImageHdr) Map(offset int) map[string]interface{} {
-	return map[string]interface{}{
-		"magic":   h.Magic,
-		"hdr_sz":  h.HdrSz,
-		"img_sz":  h.ImgSz,
-		"flags":   h.Flags,
-		"vers":    h.Vers.String(),
-		"_offset": offset,
-	}
-}
-
-func rawBodyMap(offset int) map[string]interface{} {
-	return map[string]interface{}{
-		"_offset": offset,
-	}
-}
-
-func (t *ImageTrailer) Map(offset int) map[string]interface{} {
-	return map[string]interface{}{
-		"magic":       t.Magic,
-		"tlv_tot_len": t.TlvTotLen,
-		"_offset":     offset,
-	}
-}
-
-func (t *ImageTlv) Map(offset int) map[string]interface{} {
-	return map[string]interface{}{
-		"type":     t.Header.Type,
-		"len":      t.Header.Len,
-		"data":     hex.EncodeToString(t.Data),
-		"_typestr": ImageTlvTypeName(t.Header.Type),
-		"_offset":  offset,
-	}
-}
-
-func (img *Image) Map() (map[string]interface{}, error) {
-	offs, err := img.Offsets()
-	if err != nil {
-		return nil, err
-	}
-
-	m := map[string]interface{}{}
-	m["header"] = img.Header.Map(offs.Header)
-	m["body"] = rawBodyMap(offs.Body)
-	trailer := img.Trailer()
-	m["trailer"] = trailer.Map(offs.Trailer)
-
-	tlvMaps := []map[string]interface{}{}
-	for i, tlv := range img.Tlvs {
-		tlvMaps = append(tlvMaps, tlv.Map(offs.Tlvs[i]))
-	}
-	m["tlvs"] = tlvMaps
-
-	return m, nil
-}
-
-func (img *Image) Json() (string, error) {
-	m, err := img.Map()
-	if err != nil {
-		return "", err
-	}
-
-	b, err := json.MarshalIndent(m, "", "    ")
-	if err != nil {
-		return "", errors.Wrapf(err, "failed to marshal image")
-	}
-
-	return string(b), nil
-}
-
 func (tlv *ImageTlv) Write(w io.Writer) (int, error) {
 	totalSize := 0
 
@@ -282,18 +168,34 @@
 	return totalSize, nil
 }
 
-func (i *Image) FindTlvs(tlvType uint8) []ImageTlv {
-	var tlvs []ImageTlv
+// FindTlvIndices searches an image for TLVs of the specified type and
+// returns their indices.
+func (i *Image) FindTlvIndices(tlvType uint8) []int {
+	var idxs []int
 
-	for _, tlv := range i.Tlvs {
+	for i, tlv := range i.Tlvs {
 		if tlv.Header.Type == tlvType {
-			tlvs = append(tlvs, tlv)
+			idxs = append(idxs, i)
 		}
 	}
 
+	return idxs
+}
+
+// FindTlvs retrieves all TLVs in an image's footer with the specified type.
+func (i *Image) FindTlvs(tlvType uint8) []*ImageTlv {
+	var tlvs []*ImageTlv
+
+	idxs := i.FindTlvIndices(tlvType)
+	for _, idx := range idxs {
+		tlvs = append(tlvs, &i.Tlvs[idx])
+	}
+
 	return tlvs
 }
 
+// FindUniqueTlv retrieves a TLV in an image's footer with the specified
+// type.  It returns an error if there is more than one TLV with this type.
 func (i *Image) FindUniqueTlv(tlvType uint8) (*ImageTlv, error) {
 	tlvs := i.FindTlvs(tlvType)
 	if len(tlvs) == 0 {
@@ -304,9 +206,11 @@
 			len(tlvs), tlvType)
 	}
 
-	return &tlvs[0], nil
+	return tlvs[0], nil
 }
 
+// RemoveTlvsIf removes all TLVs from an image that satisfy the supplied
+// predicate.  It returns a slice of the removed TLVs.
 func (i *Image) RemoveTlvsIf(pred func(tlv ImageTlv) bool) []ImageTlv {
 	rmed := []ImageTlv{}
 
@@ -323,12 +227,15 @@
 	return rmed
 }
 
+// RemoveTlvsWithType removes from an image all TLVs with the specified type.
+// It returns a slice of the removed TLVs.
 func (i *Image) RemoveTlvsWithType(tlvType uint8) []ImageTlv {
 	return i.RemoveTlvsIf(func(tlv ImageTlv) bool {
 		return tlv.Header.Type == tlvType
 	})
 }
 
+// ImageTrailer constructs an image trailer corresponding to the given image.
 func (img *Image) Trailer() ImageTrailer {
 	trailer := ImageTrailer{
 		Magic:     IMAGE_TRAILER_MAGIC,
@@ -341,6 +248,7 @@
 	return trailer
 }
 
+// Hash retrieves the contents of an image's SHA256 TLV.
 func (i *Image) Hash() ([]byte, error) {
 	tlv, err := i.FindUniqueTlv(IMAGE_TLV_SHA256)
 	if err != nil {
@@ -355,10 +263,13 @@
 	return tlv.Data, nil
 }
 
+// CalcHash calculates a SHA256 of the given image.
 func (i *Image) CalcHash() ([]byte, error) {
 	return calcHash(nil, i.Header, i.Pad, i.Body)
 }
 
+// WritePlusOffsets writes a binary image to the given writer.  It returns
+// the offsets of the image components that got written.
 func (i *Image) WritePlusOffsets(w io.Writer) (ImageOffsets, error) {
 	offs := ImageOffsets{}
 	offset := 0
@@ -406,10 +317,13 @@
 	return offs, nil
 }
 
+// Offsets returns the offsets of each of an image's components if it were
+// serialized.
 func (i *Image) Offsets() (ImageOffsets, error) {
 	return i.WritePlusOffsets(ioutil.Discard)
 }
 
+// TotalSize returns the size of the image if it were serialized, in bytes.
 func (i *Image) TotalSize() (int, error) {
 	offs, err := i.Offsets()
 	if err != nil {
@@ -418,6 +332,7 @@
 	return offs.TotalSize, nil
 }
 
+// Write serializes and writes a Mynewt image.
 func (i *Image) Write(w io.Writer) (int, error) {
 	offs, err := i.WritePlusOffsets(w)
 	if err != nil {
@@ -427,6 +342,7 @@
 	return offs.TotalSize, nil
 }
 
+// WriteToFile writes a Mynewt image to a file.
 func (i *Image) WriteToFile(filename string) error {
 	f, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
 	if err != nil {
@@ -440,6 +356,8 @@
 	return nil
 }
 
+// CollectSigs returns a slice of all signatures present in an image's
+// trailer.
 func (img *Image) CollectSigs() ([]sec.Sig, error) {
 	var sigs []sec.Sig
 
@@ -470,151 +388,3 @@
 
 	return sigs, nil
 }
-
-func parseRawHeader(imgData []byte, offset int) (ImageHdr, int, error) {
-	var hdr ImageHdr
-
-	r := bytes.NewReader(imgData)
-	r.Seek(int64(offset), io.SeekStart)
-
-	if err := binary.Read(r, binary.LittleEndian, &hdr); err != nil {
-		return hdr, 0, errors.Wrapf(err, "error reading image header")
-	}
-
-	if hdr.Magic != IMAGE_MAGIC {
-		return hdr, 0, errors.Errorf(
-			"image magic incorrect; expected 0x%08x, got 0x%08x",
-			uint32(IMAGE_MAGIC), hdr.Magic)
-	}
-
-	remLen := len(imgData) - offset
-	if remLen < int(hdr.HdrSz) {
-		return hdr, 0, errors.Errorf(
-			"image header incomplete; expected %d bytes, got %d bytes",
-			hdr.HdrSz, remLen)
-	}
-
-	return hdr, int(hdr.HdrSz), nil
-}
-
-func parseRawBody(imgData []byte, hdr ImageHdr,
-	offset int) ([]byte, int, error) {
-
-	imgSz := int(hdr.ImgSz)
-	remLen := len(imgData) - offset
-
-	if remLen < imgSz {
-		return nil, 0, errors.Errorf(
-			"image body incomplete; expected %d bytes, got %d bytes",
-			imgSz, remLen)
-	}
-
-	return imgData[offset : offset+imgSz], imgSz, nil
-}
-
-func parseRawTrailer(imgData []byte, offset int) (ImageTrailer, int, error) {
-	var trailer ImageTrailer
-
-	r := bytes.NewReader(imgData)
-	r.Seek(int64(offset), io.SeekStart)
-
-	if err := binary.Read(r, binary.LittleEndian, &trailer); err != nil {
-		return trailer, 0, errors.Wrapf(err,
-			"image contains invalid trailer at offset %d", offset)
-	}
-
-	return trailer, IMAGE_TRAILER_SIZE, nil
-}
-
-func parseRawTlv(imgData []byte, offset int) (ImageTlv, int, error) {
-	tlv := ImageTlv{}
-
-	r := bytes.NewReader(imgData)
-	r.Seek(int64(offset), io.SeekStart)
-
-	if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
-		return tlv, 0, errors.Wrapf(err,
-			"image contains invalid TLV at offset %d", offset)
-	}
-
-	tlv.Data = make([]byte, tlv.Header.Len)
-	if _, err := r.Read(tlv.Data); err != nil {
-		return tlv, 0, errors.Wrapf(err,
-			"image contains invalid TLV at offset %d", offset)
-	}
-
-	return tlv, IMAGE_TLV_SIZE + int(tlv.Header.Len), nil
-}
-
-func ParseImage(imgData []byte) (Image, error) {
-	img := Image{}
-	offset := 0
-
-	hdr, size, err := parseRawHeader(imgData, offset)
-	if err != nil {
-		return img, err
-	}
-	offset += size
-
-	body, size, err := parseRawBody(imgData, hdr, offset)
-	if err != nil {
-		return img, err
-	}
-	offset += size
-
-	trailer, size, err := parseRawTrailer(imgData, offset)
-	if err != nil {
-		return img, err
-	}
-	offset += size
-
-	totalLen := IMAGE_HEADER_SIZE + len(body) + int(trailer.TlvTotLen)
-	if len(imgData) < totalLen {
-		return img, errors.Errorf("image data truncated: have=%d want=%d",
-			len(imgData), totalLen)
-	}
-
-	// Trim excess data following image trailer.
-	imgData = imgData[:totalLen]
-
-	var tlvs []ImageTlv
-	tlvLen := IMAGE_TRAILER_SIZE
-	for offset < len(imgData) {
-		tlv, size, err := parseRawTlv(imgData, offset)
-		if err != nil {
-			return img, err
-		}
-
-		tlvs = append(tlvs, tlv)
-
-		offset += size
-		if offset > len(imgData) {
-			return img, errors.Errorf("TLVs extend beyond end of image")
-		}
-
-		tlvLen += size
-	}
-
-	if int(trailer.TlvTotLen) != tlvLen {
-		return img, errors.Errorf(
-			"invalid image: trailer indicates TLV-length=%d; actual=%d",
-			trailer.TlvTotLen, tlvLen)
-	}
-
-	img.Header = hdr
-	img.Body = body
-	img.Tlvs = tlvs
-
-	return img, nil
-}
-
-func ReadImage(filename string) (Image, error) {
-	ri := Image{}
-
-	imgData, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return ri, errors.Wrapf(err, "failed to read image from file")
-	}
-
-	return ParseImage(imgData)
-}
diff --git a/image/image_test.go b/image/image_test.go
index 132e6fb..fb0d8df 100644
--- a/image/image_test.go
+++ b/image/image_test.go
@@ -78,7 +78,7 @@
 		}
 	}
 
-	err = img.VerifyIntegrity()
+	err = img.Verify()
 	if !e.integrity {
 		if err == nil {
 			fatalErr("integrity", "good", "bad", nil)
@@ -93,7 +93,7 @@
 
 	man := readManifest(e.basename)
 
-	err = img.ValidateManifest(man)
+	err = img.VerifyManifest(man)
 	if !e.man {
 		if err == nil {
 			fatalErr("manifest", "good", "bad", nil)
diff --git a/image/map.go b/image/map.go
new file mode 100644
index 0000000..76c6aa0
--- /dev/null
+++ b/image/map.go
@@ -0,0 +1,81 @@
+package image
+
+import (
+	"encoding/hex"
+	"encoding/json"
+
+	"github.com/apache/mynewt-artifact/errors"
+)
+
+func (h *ImageHdr) Map(offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"_offset": offset,
+		"flags":   h.Flags,
+		"hdr_sz":  h.HdrSz,
+		"img_sz":  h.ImgSz,
+		"magic":   h.Magic,
+		"vers":    h.Vers.String(),
+	}
+}
+
+func rawBodyMap(offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"_offset": offset,
+	}
+}
+
+func (t *ImageTrailer) Map(offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"_offset":     offset,
+		"magic":       t.Magic,
+		"tlv_tot_len": t.TlvTotLen,
+	}
+}
+
+func (t *ImageTlv) Map(index int, offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"_index":   index,
+		"_offset":  offset,
+		"_typestr": ImageTlvTypeName(t.Header.Type),
+		"data":     hex.EncodeToString(t.Data),
+		"len":      t.Header.Len,
+		"type":     t.Header.Type,
+	}
+}
+
+// Map produces a JSON-friendly map representation of an image.
+func (img *Image) Map() (map[string]interface{}, error) {
+	offs, err := img.Offsets()
+	if err != nil {
+		return nil, err
+	}
+
+	m := map[string]interface{}{}
+	m["header"] = img.Header.Map(offs.Header)
+	m["body"] = rawBodyMap(offs.Body)
+	trailer := img.Trailer()
+	m["trailer"] = trailer.Map(offs.Trailer)
+
+	tlvMaps := []map[string]interface{}{}
+	for i, tlv := range img.Tlvs {
+		tlvMaps = append(tlvMaps, tlv.Map(i, offs.Tlvs[i]))
+	}
+	m["tlvs"] = tlvMaps
+
+	return m, nil
+}
+
+// Json produces a JSON representation of an image.
+func (img *Image) Json() (string, error) {
+	m, err := img.Map()
+	if err != nil {
+		return "", err
+	}
+
+	b, err := json.MarshalIndent(m, "", "    ")
+	if err != nil {
+		return "", errors.Wrapf(err, "failed to marshal image")
+	}
+
+	return string(b), nil
+}
diff --git a/image/parse.go b/image/parse.go
new file mode 100644
index 0000000..f1019a8
--- /dev/null
+++ b/image/parse.go
@@ -0,0 +1,200 @@
+package image
+
+import (
+	"bytes"
+	"encoding/binary"
+	"io"
+	"io/ioutil"
+	"strconv"
+	"strings"
+
+	"github.com/apache/mynewt-artifact/errors"
+)
+
+// ParseVersion parses an image version string (e.g., "1.2.3.4")
+func ParseVersion(versStr string) (ImageVersion, error) {
+	var err error
+	var major uint64
+	var minor uint64
+	var rev uint64
+	var buildNum uint64
+	var ver ImageVersion
+
+	components := strings.SplitN(versStr, ".", 4)
+	major, err = strconv.ParseUint(components[0], 10, 8)
+	if err != nil {
+		return ver, errors.Errorf("invalid version string %s", versStr)
+	}
+	if len(components) > 1 {
+		minor, err = strconv.ParseUint(components[1], 10, 8)
+		if err != nil {
+			return ver, errors.Errorf("invalid version string %s", versStr)
+		}
+	}
+	if len(components) > 2 {
+		rev, err = strconv.ParseUint(components[2], 10, 16)
+		if err != nil {
+			return ver, errors.Errorf("invalid version string %s", versStr)
+		}
+	}
+	if len(components) > 3 {
+		buildNum, err = strconv.ParseUint(components[3], 10, 32)
+		if err != nil {
+			return ver, errors.Errorf("invalid version string %s", versStr)
+		}
+	}
+
+	ver.Major = uint8(major)
+	ver.Minor = uint8(minor)
+	ver.Rev = uint16(rev)
+	ver.BuildNum = uint32(buildNum)
+	return ver, nil
+}
+
+func parseRawHeader(imgData []byte, offset int) (ImageHdr, int, error) {
+	var hdr ImageHdr
+
+	r := bytes.NewReader(imgData)
+	r.Seek(int64(offset), io.SeekStart)
+
+	if err := binary.Read(r, binary.LittleEndian, &hdr); err != nil {
+		return hdr, 0, errors.Wrapf(err, "error reading image header")
+	}
+
+	if hdr.Magic != IMAGE_MAGIC {
+		return hdr, 0, errors.Errorf(
+			"image magic incorrect; expected 0x%08x, got 0x%08x",
+			uint32(IMAGE_MAGIC), hdr.Magic)
+	}
+
+	remLen := len(imgData) - offset
+	if remLen < int(hdr.HdrSz) {
+		return hdr, 0, errors.Errorf(
+			"image header incomplete; expected %d bytes, got %d bytes",
+			hdr.HdrSz, remLen)
+	}
+
+	return hdr, int(hdr.HdrSz), nil
+}
+
+func parseRawBody(imgData []byte, hdr ImageHdr,
+	offset int) ([]byte, int, error) {
+
+	imgSz := int(hdr.ImgSz)
+	remLen := len(imgData) - offset
+
+	if remLen < imgSz {
+		return nil, 0, errors.Errorf(
+			"image body incomplete; expected %d bytes, got %d bytes",
+			imgSz, remLen)
+	}
+
+	return imgData[offset : offset+imgSz], imgSz, nil
+}
+
+func parseRawTrailer(imgData []byte, offset int) (ImageTrailer, int, error) {
+	var trailer ImageTrailer
+
+	r := bytes.NewReader(imgData)
+	r.Seek(int64(offset), io.SeekStart)
+
+	if err := binary.Read(r, binary.LittleEndian, &trailer); err != nil {
+		return trailer, 0, errors.Wrapf(err,
+			"image contains invalid trailer at offset %d", offset)
+	}
+
+	return trailer, IMAGE_TRAILER_SIZE, nil
+}
+
+func parseRawTlv(imgData []byte, offset int) (ImageTlv, int, error) {
+	tlv := ImageTlv{}
+
+	r := bytes.NewReader(imgData)
+	r.Seek(int64(offset), io.SeekStart)
+
+	if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
+		return tlv, 0, errors.Wrapf(err,
+			"image contains invalid TLV at offset %d", offset)
+	}
+
+	tlv.Data = make([]byte, tlv.Header.Len)
+	if _, err := r.Read(tlv.Data); err != nil {
+		return tlv, 0, errors.Wrapf(err,
+			"image contains invalid TLV at offset %d", offset)
+	}
+
+	return tlv, IMAGE_TLV_SIZE + int(tlv.Header.Len), nil
+}
+
+func ParseImage(imgData []byte) (Image, error) {
+	img := Image{}
+	offset := 0
+
+	hdr, size, err := parseRawHeader(imgData, offset)
+	if err != nil {
+		return img, err
+	}
+	offset += size
+
+	body, size, err := parseRawBody(imgData, hdr, offset)
+	if err != nil {
+		return img, err
+	}
+	offset += size
+
+	trailer, size, err := parseRawTrailer(imgData, offset)
+	if err != nil {
+		return img, err
+	}
+	offset += size
+
+	totalLen := IMAGE_HEADER_SIZE + len(body) + int(trailer.TlvTotLen)
+	if len(imgData) < totalLen {
+		return img, errors.Errorf("image data truncated: have=%d want=%d",
+			len(imgData), totalLen)
+	}
+
+	// Trim excess data following image trailer.
+	imgData = imgData[:totalLen]
+
+	var tlvs []ImageTlv
+	tlvLen := IMAGE_TRAILER_SIZE
+	for offset < len(imgData) {
+		tlv, size, err := parseRawTlv(imgData, offset)
+		if err != nil {
+			return img, err
+		}
+
+		tlvs = append(tlvs, tlv)
+
+		offset += size
+		if offset > len(imgData) {
+			return img, errors.Errorf("TLVs extend beyond end of image")
+		}
+
+		tlvLen += size
+	}
+
+	if int(trailer.TlvTotLen) != tlvLen {
+		return img, errors.Errorf(
+			"invalid image: trailer indicates TLV-length=%d; actual=%d",
+			trailer.TlvTotLen, tlvLen)
+	}
+
+	img.Header = hdr
+	img.Body = body
+	img.Tlvs = tlvs
+
+	return img, nil
+}
+
+func ReadImage(filename string) (Image, error) {
+	ri := Image{}
+
+	imgData, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return ri, errors.Wrapf(err, "failed to read image from file")
+	}
+
+	return ParseImage(imgData)
+}
diff --git a/manifest/manifest.go b/manifest/manifest.go
index 3a7298a..7508bc0 100644
--- a/manifest/manifest.go
+++ b/manifest/manifest.go
@@ -82,6 +82,7 @@
 	LoaderPkgSizes []*ManifestSizePkg `json:"loader_pkgsz,omitempty"`
 }
 
+// ReadManifest reads a JSON manifest from a file.
 func ReadManifest(path string) (Manifest, error) {
 	m := Manifest{}
 
@@ -98,6 +99,7 @@
 	return m, nil
 }
 
+// Write serializes a manifest as JSON and writes it to the given writer.
 func (m *Manifest) Write(w io.Writer) (int, error) {
 	buffer, err := json.MarshalIndent(m, "", "  ")
 	if err != nil {
@@ -112,6 +114,8 @@
 	return cnt, nil
 }
 
+// FindTargetVar searches a manifest's target definition for a setting with
+// the specified key.  Examples of keys are: "app", "bsp", and "syscfg".
 func (m *Manifest) FindTargetVar(key string) string {
 	for _, tv := range m.TgtVars {
 		parts := strings.SplitN(tv, "=", 2)
diff --git a/manifest/mfg_manifest.go b/manifest/mfg_manifest.go
index 3ebd22a..f742e12 100644
--- a/manifest/mfg_manifest.go
+++ b/manifest/mfg_manifest.go
@@ -75,6 +75,8 @@
 	Meta    *MfgManifestMeta    `json:"meta,omitempty"`
 }
 
+// ReadMfgManifest reads a JSON mfg manifest from a byte slice and produces an
+// MfgManifest object.
 func ParseMfgManifest(jsonText []byte) (MfgManifest, error) {
 	m := MfgManifest{
 		// Backwards compatibility: assume 0xff if unspecified.
@@ -88,6 +90,8 @@
 	return m, nil
 }
 
+// ReadMfgManifest reads a JSON mfg manifest from a file and produces an
+// MfgManifest object.
 func ReadMfgManifest(path string) (MfgManifest, error) {
 	content, err := ioutil.ReadFile(path)
 	if err != nil {
@@ -103,6 +107,12 @@
 	return m, nil
 }
 
+// IsBoot indicates whether an mfg manifest target is a boot loader.
+func (mt *MfgManifestTarget) IsBoot() bool {
+	return mt.BinPath != ""
+}
+
+// MarshalJson produces a JSON representation of an mfg manifest.
 func (m *MfgManifest) MarshalJson() ([]byte, error) {
 	buffer, err := json.MarshalIndent(m, "", "  ")
 	if err != nil {
@@ -112,7 +122,9 @@
 	return buffer, nil
 }
 
-func (m *MfgManifest) FindFlashArea(device int, offset int) *flash.FlashArea {
+// FindFlashAreaDevOff searches an mfg manifest for a flash area with the
+// specified device and offset.
+func (m *MfgManifest) FindFlashAreaDevOff(device int, offset int) *flash.FlashArea {
 	for i, _ := range m.FlashAreas {
 		fa := &m.FlashAreas[i]
 		if fa.Device == device && fa.Offset == offset {
@@ -123,6 +135,8 @@
 	return nil
 }
 
+// FindFlashAreaName searches an mfg manifest for a flash area with the
+// specified name.
 func (m *MfgManifest) FindFlashAreaName(name string) *flash.FlashArea {
 	for i, _ := range m.FlashAreas {
 		fa := &m.FlashAreas[i]
@@ -134,6 +148,7 @@
 	return nil
 }
 
+// SecSig converts the provided mfg manifest signature into a sec.Sig object.
 func (ms *MfgManifestSig) SecSig() (sec.Sig, error) {
 	keyHash, err := hex.DecodeString(ms.Key)
 	if err != nil {
@@ -153,6 +168,8 @@
 	}, nil
 }
 
+// SecSigs converts all the signutures in the provided mfg manifest into
+// sec.Sig objects.
 func (m *MfgManifest) SecSigs() ([]sec.Sig, error) {
 	var sigs []sec.Sig
 	for _, ms := range m.Signatures {
@@ -166,7 +183,3 @@
 
 	return sigs, nil
 }
-
-func (mt *MfgManifestTarget) IsBoot() bool {
-	return mt.BinPath != ""
-}
diff --git a/mfg/map_meta.go b/mfg/map_meta.go
index 19b1ee8..99714ff 100644
--- a/mfg/map_meta.go
+++ b/mfg/map_meta.go
@@ -86,6 +86,7 @@
 	}
 }
 
+// Map produces a JSON-friendly map representation of an MMR TLV.
 func (t *MetaTlv) Map(index int, offset int) map[string]interface{} {
 	hmap := map[string]interface{}{
 		"_type_name": MetaTlvTypeName(t.Header.Type),
@@ -110,6 +111,7 @@
 	}
 }
 
+// Map produces a JSON-friendly map representation of an MMR footer.
 func (f *MetaFooter) Map(offset int) map[string]interface{} {
 	return map[string]interface{}{
 		"_offset": offset,
@@ -119,6 +121,7 @@
 	}
 }
 
+// Map produces a JSON-friendly map representation of an MMR.
 func (m *Meta) Map(endOffset int) map[string]interface{} {
 	offsets := m.Offsets()
 	startOffset := endOffset - int(m.Footer.Size)
@@ -140,6 +143,7 @@
 	}
 }
 
+// Json produces a JSON representation of an MMR.
 func (m *Meta) Json(offset int) (string, error) {
 	mmap := m.Map(offset)
 
diff --git a/mfg/meta.go b/mfg/meta.go
index b4786bc..1e7029c 100644
--- a/mfg/meta.go
+++ b/mfg/meta.go
@@ -160,6 +160,8 @@
 	return sz, nil
 }
 
+// StructuredBody constructs the appropriate "body" object from a raw TLV
+// (e.g., MetaTlvBodyHash from a TLV with type=META_TLV_TYPE_HASH).
 func (tlv *MetaTlv) StructuredBody() (interface{}, error) {
 	r := bytes.NewReader(tlv.Data)
 
@@ -197,6 +199,8 @@
 	}
 }
 
+// WritePlusOffsets writes a binary MMR to the given writer.  It returns the
+// offsets of the mfgimage components that got written.
 func (meta *Meta) WritePlusOffsets(w io.Writer) (MetaOffsets, error) {
 	mo := MetaOffsets{}
 	sz := 0
@@ -221,11 +225,14 @@
 	return mo, nil
 }
 
+// Offsets returns the offsets of each of an MMR's components if it were
+// serialized.
 func (meta *Meta) Offsets() MetaOffsets {
 	mo, _ := meta.WritePlusOffsets(ioutil.Discard)
 	return mo
 }
 
+// Write serializes and writes an MMR.
 func (meta *Meta) Write(w io.Writer) (int, error) {
 	mo, err := meta.WritePlusOffsets(w)
 	if err != nil {
@@ -235,10 +242,12 @@
 	return mo.TotalSize, nil
 }
 
+// Size calculates the total size of an MMR if it were serialied.
 func (meta *Meta) Size() int {
 	return meta.Offsets().TotalSize
 }
 
+// Bytes serializes an MMR to binary form.
 func (meta *Meta) Bytes() ([]byte, error) {
 	b := &bytes.Buffer{}
 
@@ -250,6 +259,8 @@
 	return b.Bytes(), nil
 }
 
+// FindTlvIndices searches an MMR for TLVs of the specified type and returns
+// their indices.
 func (meta *Meta) FindTlvIndices(typ uint8) []int {
 	indices := []int{}
 
@@ -262,6 +273,7 @@
 	return indices
 }
 
+// FindTlvIndices searches an MMR for all TLVs of the specified type.
 func (meta *Meta) FindTlvs(typ uint8) []*MetaTlv {
 	indices := meta.FindTlvIndices(typ)
 
@@ -273,15 +285,18 @@
 	return tlvs
 }
 
+// FindTlvIndices searches an MMR for the first TLV of the specified type.
 func (meta *Meta) FindFirstTlv(typ uint8) *MetaTlv {
-	indices := meta.FindTlvIndices(typ)
-	if len(indices) == 0 {
+	tlvs := meta.FindTlvs(typ)
+	if len(tlvs) == 0 {
 		return nil
 	}
 
-	return &meta.Tlvs[indices[0]]
+	return tlvs[0]
 }
 
+// HashOffset calculates the offset of the SHA256 TLV in an MMR if it were
+// serialized.
 func (meta *Meta) HashOffset() int {
 	mo := meta.Offsets()
 	indices := meta.FindTlvIndices(META_TLV_TYPE_HASH)
@@ -292,6 +307,7 @@
 	return META_TLV_HEADER_SZ + mo.Tlvs[indices[0]]
 }
 
+// ClearHash zeroes out an MMRs SHA256 TLV.
 func (meta *Meta) ClearHash() {
 	tlv := meta.FindFirstTlv(META_TLV_TYPE_HASH)
 	if tlv != nil {
@@ -299,6 +315,8 @@
 	}
 }
 
+// Hash locates an MMR's SHA256 TLV and returns its value.  It returns nil if
+// the MMR doesn't have a SHA256 TLV.
 func (meta *Meta) Hash() []byte {
 	tlv := meta.FindFirstTlv(META_TLV_TYPE_HASH)
 	if tlv == nil {
@@ -307,15 +325,15 @@
 	return tlv.Data
 }
 
+// Clone performs a deep copy of an MMR.
 func (meta *Meta) Clone() Meta {
-	var tlvs []MetaTlv
-	for _, src := range meta.Tlvs {
-		dst := MetaTlv{
+	tlvs := make([]MetaTlv, len(meta.Tlvs))
+	for i, src := range meta.Tlvs {
+		tlvs[i] = MetaTlv{
 			Header: src.Header,
 			Data:   make([]byte, len(src.Data)),
 		}
-		copy(dst.Data, src.Data)
-		tlvs = append(tlvs, dst)
+		copy(tlvs[i].Data, src.Data)
 	}
 
 	return Meta{
@@ -323,83 +341,3 @@
 		Footer: meta.Footer,
 	}
 }
-
-func parseMetaTlv(bin []byte) (MetaTlv, int, error) {
-	r := bytes.NewReader(bin)
-
-	tlv := MetaTlv{}
-	if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
-		return tlv, 0, errors.Wrapf(err, "error reading TLV header")
-	}
-
-	data := make([]byte, tlv.Header.Size)
-	sz, err := r.Read(data)
-	if err != nil {
-		return tlv, 0, errors.Wrapf(err,
-			"error reading %d bytes of TLV data",
-			tlv.Header.Size)
-	}
-	if sz != len(data) {
-		return tlv, 0, errors.Errorf(
-			"error reading %d bytes of TLV data: incomplete read",
-			tlv.Header.Size)
-	}
-	tlv.Data = data
-
-	return tlv, META_TLV_HEADER_SZ + int(tlv.Header.Size), nil
-}
-
-func parseMetaFooter(bin []byte) (MetaFooter, int, error) {
-	r := bytes.NewReader(bin)
-
-	var ftr MetaFooter
-	if err := binary.Read(r, binary.LittleEndian, &ftr); err != nil {
-		return ftr, 0, errors.Wrapf(err,
-			"error reading meta footer")
-	}
-
-	if ftr.Magic != META_MAGIC {
-		return ftr, 0, errors.Errorf(
-			"meta footer contains invalid magic; exp:0x%08x, got:0x%08x",
-			META_MAGIC, ftr.Magic)
-	}
-
-	return ftr, META_FOOTER_SZ, nil
-}
-
-func ParseMeta(bin []byte) (Meta, int, error) {
-	if len(bin) < META_FOOTER_SZ {
-		return Meta{}, 0, errors.Errorf(
-			"binary too small to accommodate meta footer; "+
-				"bin-size=%d ftr-size=%d", len(bin), META_FOOTER_SZ)
-	}
-
-	ftr, _, err := parseMetaFooter(bin[len(bin)-META_FOOTER_SZ:])
-	if err != nil {
-		return Meta{}, 0, err
-	}
-
-	if int(ftr.Size) > len(bin) {
-		return Meta{}, 0, errors.Errorf(
-			"binary too small to accommodate meta region; "+
-				"bin-size=%d meta-size=%d", len(bin), ftr.Size)
-	}
-
-	ftrOff := len(bin) - META_FOOTER_SZ
-	off := len(bin) - int(ftr.Size)
-
-	tlvs := []MetaTlv{}
-	for off < ftrOff {
-		tlv, sz, err := parseMetaTlv(bin[off:])
-		if err != nil {
-			return Meta{}, 0, err
-		}
-		tlvs = append(tlvs, tlv)
-		off += sz
-	}
-
-	return Meta{
-		Tlvs:   tlvs,
-		Footer: ftr,
-	}, off, nil
-}
diff --git a/mfg/mfg.go b/mfg/mfg.go
index eea6abf..2667003 100644
--- a/mfg/mfg.go
+++ b/mfg/mfg.go
@@ -20,7 +20,6 @@
 package mfg
 
 import (
-	"bytes"
 	"crypto/sha256"
 
 	"github.com/apache/mynewt-artifact/errors"
@@ -39,33 +38,9 @@
 	MetaOff int
 }
 
-func Parse(data []byte, metaEndOff int, eraseVal byte) (Mfg, error) {
-	m := Mfg{
-		Bin: data,
-	}
-
-	if metaEndOff >= 0 {
-		if metaEndOff > len(data) {
-			return m, errors.Errorf(
-				"MMR offset (%d) beyond end of mfgimage (%d)",
-				metaEndOff, len(data))
-		}
-
-		meta, _, err := ParseMeta(data[:metaEndOff])
-		if err != nil {
-			return m, err
-		}
-		m.Meta = &meta
-		m.MetaOff = metaEndOff - int(meta.Footer.Size)
-
-		for i := 0; i < int(meta.Footer.Size); i++ {
-			m.Bin[m.MetaOff+i] = eraseVal
-		}
-	}
-
-	return m, nil
-}
-
+// StripPadding produces a new byte slice by removing padding from an
+// existing byte slice.  Padding is defined as a sequence of trailing bytes,
+// all with the specified value.
 func StripPadding(b []byte, eraseVal byte) []byte {
 	var pad int
 	for pad = 0; pad < len(b); pad++ {
@@ -78,6 +53,8 @@
 	return b[:len(b)-pad]
 }
 
+// AddPadding produces a new byte slice by adding extra bytes to the end of
+// an existing slice.
 func AddPadding(b []byte, eraseVal byte, padLen int) []byte {
 	for i := 0; i < padLen; i++ {
 		b = append(b, eraseVal)
@@ -114,8 +91,10 @@
 	return CalcHash(bin), nil
 }
 
+// RefillHash replace's the contents of an mfgimage's SHA256 TLV with a newly
+// calculated hash.
 func (m *Mfg) RefillHash(eraseVal byte) error {
-	if m.Meta == nil || m.Meta.Hash() == nil {
+	if m.Meta == nil {
 		return nil
 	}
 	tlv := m.Meta.FindFirstTlv(META_TLV_TYPE_HASH)
@@ -135,6 +114,9 @@
 	return nil
 }
 
+// Hash retrieves the SHA256 value associated with an mfgimage.  If the
+// mfgimage has an MMR with a SHA256 TLV, the TLV's value is returned.
+// Otherwise, the hash is calculated and returned.
 func (m *Mfg) Hash(eraseVal byte) ([]byte, error) {
 	var hashBytes []byte
 
@@ -154,21 +136,7 @@
 	return hashBytes, nil
 }
 
-func (m *Mfg) HashIsValid(eraseVal byte) (bool, error) {
-	// If the mfg doesn't contain a hash TLV, then there is nothing to verify.
-	tlv := m.Meta.FindFirstTlv(META_TLV_TYPE_HASH)
-	if tlv == nil {
-		return true, nil
-	}
-
-	hash, err := m.RecalcHash(eraseVal)
-	if err != nil {
-		return false, err
-	}
-
-	return bytes.Equal(hash, tlv.Data), nil
-}
-
+// Bytes serializes an mfgimage into binary form.
 func (m *Mfg) Bytes(eraseVal byte) ([]byte, error) {
 	binCopy := make([]byte, len(m.Bin))
 	copy(binCopy, m.Bin)
@@ -188,6 +156,7 @@
 	return binCopy, nil
 }
 
+// Clone performs a deep copy of an mfgimage.
 func (m *Mfg) Clone() Mfg {
 	var meta *Meta
 	if m.Meta != nil {
@@ -205,7 +174,11 @@
 	}
 }
 
-func (m *Mfg) ExtractFlashArea(area flash.FlashArea, eraseVal byte) ([]byte, error) {
+// ExtractFlashArea copies a portion out of a serialized mfgimage.  The
+// offset and size to copy indicated by the provided FlashArea.
+func (m *Mfg) ExtractFlashArea(area flash.FlashArea,
+	eraseVal byte) ([]byte, error) {
+
 	b, err := m.Bytes(eraseVal)
 	if err != nil {
 		return nil, err
@@ -228,6 +201,8 @@
 	return b[area.Offset:end], nil
 }
 
+// Tlvs retrieves the slice of TLVs present in an mfgimage's MMR.  It returns
+// nil if the mfgimage has no MMR.
 func (m *Mfg) Tlvs() []MetaTlv {
 	if m.Meta == nil {
 		return nil
diff --git a/mfg/mfg_test.go b/mfg/mfg_test.go
index 5e7d8ff..a2e503e 100644
--- a/mfg/mfg_test.go
+++ b/mfg/mfg_test.go
@@ -86,7 +86,7 @@
 		}
 	}
 
-	err = m.VerifyIntegrity(man.EraseVal)
+	err = m.Verify(man.EraseVal)
 	if !e.integrity {
 		if err == nil {
 			fatalErr("integrity", "good", "bad", nil)
@@ -99,7 +99,7 @@
 		}
 	}
 
-	err = m.ValidateManifest(man)
+	err = m.VerifyManifest(man)
 	if !e.man {
 		if err == nil {
 			fatalErr("manifest", "good", "bad", nil)
diff --git a/mfg/parse.go b/mfg/parse.go
new file mode 100644
index 0000000..1d4e4b7
--- /dev/null
+++ b/mfg/parse.go
@@ -0,0 +1,118 @@
+package mfg
+
+import (
+	"bytes"
+	"encoding/binary"
+
+	"github.com/apache/mynewt-artifact/errors"
+)
+
+func parseMetaFooter(bin []byte) (MetaFooter, int, error) {
+	r := bytes.NewReader(bin)
+
+	var ftr MetaFooter
+	if err := binary.Read(r, binary.LittleEndian, &ftr); err != nil {
+		return ftr, 0, errors.Wrapf(err,
+			"error reading meta footer")
+	}
+
+	if ftr.Magic != META_MAGIC {
+		return ftr, 0, errors.Errorf(
+			"meta footer contains invalid magic; exp:0x%08x, got:0x%08x",
+			META_MAGIC, ftr.Magic)
+	}
+
+	return ftr, META_FOOTER_SZ, nil
+}
+
+func parseMetaTlv(bin []byte) (MetaTlv, int, error) {
+	r := bytes.NewReader(bin)
+
+	tlv := MetaTlv{}
+	if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
+		return tlv, 0, errors.Wrapf(err, "error reading TLV header")
+	}
+
+	data := make([]byte, tlv.Header.Size)
+	sz, err := r.Read(data)
+	if err != nil {
+		return tlv, 0, errors.Wrapf(err,
+			"error reading %d bytes of TLV data",
+			tlv.Header.Size)
+	}
+	if sz != len(data) {
+		return tlv, 0, errors.Errorf(
+			"error reading %d bytes of TLV data: incomplete read",
+			tlv.Header.Size)
+	}
+	tlv.Data = data
+
+	return tlv, META_TLV_HEADER_SZ + int(tlv.Header.Size), nil
+}
+
+func parseMeta(bin []byte) (Meta, error) {
+	if len(bin) < META_FOOTER_SZ {
+		return Meta{}, errors.Errorf(
+			"binary too small to accommodate meta footer; "+
+				"bin-size=%d ftr-size=%d", len(bin), META_FOOTER_SZ)
+	}
+
+	ftr, _, err := parseMetaFooter(bin[len(bin)-META_FOOTER_SZ:])
+	if err != nil {
+		return Meta{}, err
+	}
+
+	if int(ftr.Size) > len(bin) {
+		return Meta{}, errors.Errorf(
+			"binary too small to accommodate meta region; "+
+				"bin-size=%d meta-size=%d", len(bin), ftr.Size)
+	}
+
+	ftrOff := len(bin) - META_FOOTER_SZ
+	off := len(bin) - int(ftr.Size)
+
+	tlvs := []MetaTlv{}
+	for off < ftrOff {
+		tlv, sz, err := parseMetaTlv(bin[off:])
+		if err != nil {
+			return Meta{}, err
+		}
+		tlvs = append(tlvs, tlv)
+		off += sz
+	}
+
+	return Meta{
+		Tlvs:   tlvs,
+		Footer: ftr,
+	}, nil
+}
+
+// Parse parses a serialized mfgimage (e.g., "mfgimg.bin") and produces an
+// Mfg object.  metaEndOff is the offset immediately following the MMR, or -1
+// if there is no MMR.
+func Parse(data []byte, metaEndOff int, eraseVal byte) (Mfg, error) {
+	m := Mfg{
+		Bin: data,
+	}
+
+	if metaEndOff >= 0 {
+		if metaEndOff > len(data) {
+			return m, errors.Errorf(
+				"MMR offset (%d) beyond end of mfgimage (%d)",
+				metaEndOff, len(data))
+		}
+
+		meta, err := parseMeta(data[:metaEndOff])
+		if err != nil {
+			return m, err
+		}
+		m.Meta = &meta
+		m.MetaOff = metaEndOff - int(meta.Footer.Size)
+
+		for i := 0; i < int(meta.Footer.Size); i++ {
+			m.Bin[m.MetaOff+i] = eraseVal
+		}
+	}
+
+	return m, nil
+}
diff --git a/mfg/verify.go b/mfg/verify.go
index 17a5a76..ffa2817 100644
--- a/mfg/verify.go
+++ b/mfg/verify.go
@@ -105,7 +105,7 @@
 
 func (m *Mfg) validateManTargets(man manifest.MfgManifest) error {
 	for _, t := range man.Targets {
-		fa := man.FindFlashArea(man.Device, t.Offset)
+		fa := man.FindFlashAreaDevOff(man.Device, t.Offset)
 		if fa == nil {
 			return errors.Errorf(
 				"no flash area in mfgimage corresponding to target \"%s\"",
diff --git a/misc/misc.go b/misc/misc.go
deleted file mode 100644
index 2f685e1..0000000
--- a/misc/misc.go
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 misc
-
-import (
-	"fmt"
-)
-
-func HashString(hash []byte) string {
-	return fmt.Sprintf("%x", hash)
-}
diff --git a/sec/key.go b/sec/key.go
index 473ef62..dabbd1f 100644
--- a/sec/key.go
+++ b/sec/key.go
@@ -168,7 +168,7 @@
 
 func (key *SignKey) PubBytes() ([]byte, error) {
 	pk := key.PubKey()
-	return pk.PubBytes()
+	return pk.Bytes()
 }
 
 func RawKeyHash(pubKeyBytes []byte) []byte {
@@ -256,18 +256,15 @@
 func ParseKeBase64(keyBytes []byte) (cipher.Block, error) {
 	kek, err := base64.StdEncoding.DecodeString(string(keyBytes))
 	if err != nil {
-		return nil, errors.Wrapf(err,
-			"Error decoding kek: %s")
+		return nil, errors.Wrapf(err, "error decoding kek")
 	}
 	if len(kek) != 16 {
-		return nil, errors.Errorf(
-			"Unexpected key size: %d != 16", len(kek))
+		return nil, errors.Errorf("unexpected key size: %d != 16", len(kek))
 	}
 
 	cipher, err := aes.NewCipher(kek)
 	if err != nil {
-		return nil, errors.Wrapf(err,
-			"Error creating keywrap cipher")
+		return nil, errors.Wrapf(err, "error creating keywrap cipher")
 	}
 
 	return cipher, nil
@@ -276,7 +273,7 @@
 func EncryptSecretAes(c cipher.Block, plainSecret []byte) ([]byte, error) {
 	cipherSecret, err := keywrap.Wrap(c, plainSecret)
 	if err != nil {
-		return nil, errors.Wrapf(err, "Error key-wrapping")
+		return nil, errors.Wrapf(err, "error key-wrapping")
 	}
 
 	return cipherSecret, nil
@@ -288,14 +285,14 @@
 	}
 }
 
-func (key *PubSignKey) PubBytes() ([]byte, error) {
+func (key *PubSignKey) Bytes() ([]byte, error) {
 	key.AssertValid()
 
-	var pubBytes []byte
+	var b []byte
 
 	if key.Rsa != nil {
 		var err error
-		pubBytes, err = asn1.Marshal(*key.Rsa)
+		b, err = asn1.Marshal(*key.Rsa)
 		if err != nil {
 			return nil, err
 		}
@@ -304,11 +301,11 @@
 		case "P-224":
 			fallthrough
 		case "P-256":
-			pubBytes, _ = x509.MarshalPKIXPublicKey(*key.Ec)
+			b, _ = x509.MarshalPKIXPublicKey(*key.Ec)
 		default:
 			return nil, errors.Errorf("unsupported ECC curve")
 		}
 	}
 
-	return pubBytes, nil
+	return b, nil
 }
diff --git a/sec/sig.go b/sec/sig.go
index 8aa0b32..d6b8ffe 100644
--- a/sec/sig.go
+++ b/sec/sig.go
@@ -14,7 +14,7 @@
 }
 
 func checkOneKeyOneSig(k PubSignKey, sig Sig, hash []byte) (bool, error) {
-	pubBytes, err := k.PubBytes()
+	pubBytes, err := k.Bytes()
 	if err != nil {
 		return false, errors.WithStack(err)
 	}