diff --git a/sbp.cabal b/sbp.cabal
--- a/sbp.cabal
+++ b/sbp.cabal
@@ -1,5 +1,5 @@
 name:                  sbp
-version:               4.9.0
+version:               4.10.0
 synopsis:              SwiftNav's SBP Library
 homepage:              https://github.com/swift-nav/libsbp
 license:               MIT
diff --git a/src/SwiftNav/SBP/Integrity.hs b/src/SwiftNav/SBP/Integrity.hs
--- a/src/SwiftNav/SBP/Integrity.hs
+++ b/src/SwiftNav/SBP/Integrity.hs
@@ -338,3 +338,46 @@
 $(makeSBP 'msgSsrFlagIonoGridPointSatLos ''MsgSsrFlagIonoGridPointSatLos)
 $(makeJSON "_msgSsrFlagIonoGridPointSatLos_" ''MsgSsrFlagIonoGridPointSatLos)
 $(makeLenses ''MsgSsrFlagIonoGridPointSatLos)
+
+msgAcknowledge :: Word16
+msgAcknowledge = 0x0BD2
+
+data MsgAcknowledge = MsgAcknowledge
+  { _msgAcknowledge_request_id              :: !Word8
+    -- ^ Echo of the request ID field from the corresponding CRA message, or 255
+    -- if no request ID was provided.
+  , _msgAcknowledge_area_id                 :: !Word32
+    -- ^ Echo of the Area ID field from the corresponding CRA message.
+  , _msgAcknowledge_response_code           :: !Word8
+    -- ^ Reported status of the request.
+  , _msgAcknowledge_correction_mask_on_demand :: !Word16
+    -- ^ Contains the message group(s) that will be sent in response from the
+    -- corresponding CRA correction mask. An echo of the correction mask field
+    -- from the corresponding CRA message.
+  , _msgAcknowledge_correction_mask_stream  :: !Word16
+    -- ^ For future expansion. Always set to 0.
+  , _msgAcknowledge_solution_id             :: !Word8
+    -- ^ The solution ID of the instance providing the corrections.
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgAcknowledge where
+  get = do
+    _msgAcknowledge_request_id <- getWord8
+    _msgAcknowledge_area_id <- getWord32le
+    _msgAcknowledge_response_code <- getWord8
+    _msgAcknowledge_correction_mask_on_demand <- getWord16le
+    _msgAcknowledge_correction_mask_stream <- getWord16le
+    _msgAcknowledge_solution_id <- getWord8
+    pure MsgAcknowledge {..}
+
+  put MsgAcknowledge {..} = do
+    putWord8 _msgAcknowledge_request_id
+    putWord32le _msgAcknowledge_area_id
+    putWord8 _msgAcknowledge_response_code
+    putWord16le _msgAcknowledge_correction_mask_on_demand
+    putWord16le _msgAcknowledge_correction_mask_stream
+    putWord8 _msgAcknowledge_solution_id
+
+$(makeSBP 'msgAcknowledge ''MsgAcknowledge)
+$(makeJSON "_msgAcknowledge_" ''MsgAcknowledge)
+$(makeLenses ''MsgAcknowledge)
diff --git a/src/SwiftNav/SBP/Msg.hs b/src/SwiftNav/SBP/Msg.hs
--- a/src/SwiftNav/SBP/Msg.hs
+++ b/src/SwiftNav/SBP/Msg.hs
@@ -57,7 +57,8 @@
 -- Includes SBPMsgUnknown for valid SBP messages with undefined message
 -- types and SBPMsgBadCRC for SBP messages with invalid CRC checksums.
 data SBPMsg =
-     SBPMsgAcqResult MsgAcqResult Msg
+     SBPMsgAcknowledge MsgAcknowledge Msg
+   | SBPMsgAcqResult MsgAcqResult Msg
    | SBPMsgAcqResultDepA MsgAcqResultDepA Msg
    | SBPMsgAcqResultDepB MsgAcqResultDepB Msg
    | SBPMsgAcqResultDepC MsgAcqResultDepC Msg
@@ -96,6 +97,7 @@
    | SBPMsgDopsDepA MsgDopsDepA Msg
    | SBPMsgEd25519Certificate MsgEd25519Certificate Msg
    | SBPMsgEd25519Signature MsgEd25519Signature Msg
+   | SBPMsgEd25519SignatureDep MsgEd25519SignatureDep Msg
    | SBPMsgEphemerisBds MsgEphemerisBds Msg
    | SBPMsgEphemerisDepA MsgEphemerisDepA Msg
    | SBPMsgEphemerisDepB MsgEphemerisDepB Msg
@@ -192,6 +194,7 @@
    | SBPMsgPosLlhCovGnss MsgPosLlhCovGnss Msg
    | SBPMsgPosLlhDepA MsgPosLlhDepA Msg
    | SBPMsgPosLlhGnss MsgPosLlhGnss Msg
+   | SBPMsgPoseRelative MsgPoseRelative Msg
    | SBPMsgPpsTime MsgPpsTime Msg
    | SBPMsgPrintDep MsgPrintDep Msg
    | SBPMsgProtectionLevel MsgProtectionLevel Msg
@@ -291,6 +294,7 @@
       decoder <$> get where
         decoder m@Msg {..}
           | checkCrc m /= _msgSBPCrc = SBPMsgBadCrc m
+          | _msgSBPType == msgAcknowledge = SBPMsgAcknowledge (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgAcqResult = SBPMsgAcqResult (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgAcqResultDepA = SBPMsgAcqResultDepA (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgAcqResultDepB = SBPMsgAcqResultDepB (decode (fromStrict (unBytes _msgSBPPayload))) m
@@ -330,6 +334,7 @@
           | _msgSBPType == msgDopsDepA = SBPMsgDopsDepA (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgEd25519Certificate = SBPMsgEd25519Certificate (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgEd25519Signature = SBPMsgEd25519Signature (decode (fromStrict (unBytes _msgSBPPayload))) m
+          | _msgSBPType == msgEd25519SignatureDep = SBPMsgEd25519SignatureDep (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgEphemerisBds = SBPMsgEphemerisBds (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgEphemerisDepA = SBPMsgEphemerisDepA (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgEphemerisDepB = SBPMsgEphemerisDepB (decode (fromStrict (unBytes _msgSBPPayload))) m
@@ -426,6 +431,7 @@
           | _msgSBPType == msgPosLlhCovGnss = SBPMsgPosLlhCovGnss (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgPosLlhDepA = SBPMsgPosLlhDepA (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgPosLlhGnss = SBPMsgPosLlhGnss (decode (fromStrict (unBytes _msgSBPPayload))) m
+          | _msgSBPType == msgPoseRelative = SBPMsgPoseRelative (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgPpsTime = SBPMsgPpsTime (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgPrintDep = SBPMsgPrintDep (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgProtectionLevel = SBPMsgProtectionLevel (decode (fromStrict (unBytes _msgSBPPayload))) m
@@ -517,6 +523,7 @@
   put sm = do
     putWord8 msgSBPPreamble
     encoder sm where
+      encoder (SBPMsgAcknowledge _ m) = put m
       encoder (SBPMsgAcqResult _ m) = put m
       encoder (SBPMsgAcqResultDepA _ m) = put m
       encoder (SBPMsgAcqResultDepB _ m) = put m
@@ -556,6 +563,7 @@
       encoder (SBPMsgDopsDepA _ m) = put m
       encoder (SBPMsgEd25519Certificate _ m) = put m
       encoder (SBPMsgEd25519Signature _ m) = put m
+      encoder (SBPMsgEd25519SignatureDep _ m) = put m
       encoder (SBPMsgEphemerisBds _ m) = put m
       encoder (SBPMsgEphemerisDepA _ m) = put m
       encoder (SBPMsgEphemerisDepB _ m) = put m
@@ -652,6 +660,7 @@
       encoder (SBPMsgPosLlhCovGnss _ m) = put m
       encoder (SBPMsgPosLlhDepA _ m) = put m
       encoder (SBPMsgPosLlhGnss _ m) = put m
+      encoder (SBPMsgPoseRelative _ m) = put m
       encoder (SBPMsgPpsTime _ m) = put m
       encoder (SBPMsgPrintDep _ m) = put m
       encoder (SBPMsgProtectionLevel _ m) = put m
@@ -747,6 +756,7 @@
     payload <- o .: "payload"
     decoder msgType payload where
       decoder msgType payload
+        | msgType == msgAcknowledge = SBPMsgAcknowledge <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgAcqResult = SBPMsgAcqResult <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgAcqResultDepA = SBPMsgAcqResultDepA <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgAcqResultDepB = SBPMsgAcqResultDepB <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
@@ -786,6 +796,7 @@
         | msgType == msgDopsDepA = SBPMsgDopsDepA <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgEd25519Certificate = SBPMsgEd25519Certificate <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgEd25519Signature = SBPMsgEd25519Signature <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
+        | msgType == msgEd25519SignatureDep = SBPMsgEd25519SignatureDep <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgEphemerisBds = SBPMsgEphemerisBds <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgEphemerisDepA = SBPMsgEphemerisDepA <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgEphemerisDepB = SBPMsgEphemerisDepB <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
@@ -882,6 +893,7 @@
         | msgType == msgPosLlhCovGnss = SBPMsgPosLlhCovGnss <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgPosLlhDepA = SBPMsgPosLlhDepA <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgPosLlhGnss = SBPMsgPosLlhGnss <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
+        | msgType == msgPoseRelative = SBPMsgPoseRelative <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgPpsTime = SBPMsgPpsTime <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgPrintDep = SBPMsgPrintDep <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgProtectionLevel = SBPMsgProtectionLevel <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
@@ -978,6 +990,7 @@
   pure $ review _Object $ a' <> b'
 
 instance ToJSON SBPMsg where
+  toJSON (SBPMsgAcknowledge n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgAcqResult n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgAcqResultDepA n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgAcqResultDepB n m) = toJSON n <<>> toJSON m
@@ -1017,6 +1030,7 @@
   toJSON (SBPMsgDopsDepA n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgEd25519Certificate n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgEd25519Signature n m) = toJSON n <<>> toJSON m
+  toJSON (SBPMsgEd25519SignatureDep n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgEphemerisBds n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgEphemerisDepA n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgEphemerisDepB n m) = toJSON n <<>> toJSON m
@@ -1113,6 +1127,7 @@
   toJSON (SBPMsgPosLlhCovGnss n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgPosLlhDepA n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgPosLlhGnss n m) = toJSON n <<>> toJSON m
+  toJSON (SBPMsgPoseRelative n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgPpsTime n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgPrintDep n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgProtectionLevel n m) = toJSON n <<>> toJSON m
@@ -1203,6 +1218,7 @@
   toJSON (SBPMsgUnknown m) = toJSON m
 
 instance HasMsg SBPMsg where
+  msg f (SBPMsgAcknowledge n m) = SBPMsgAcknowledge n <$> f m
   msg f (SBPMsgAcqResult n m) = SBPMsgAcqResult n <$> f m
   msg f (SBPMsgAcqResultDepA n m) = SBPMsgAcqResultDepA n <$> f m
   msg f (SBPMsgAcqResultDepB n m) = SBPMsgAcqResultDepB n <$> f m
@@ -1242,6 +1258,7 @@
   msg f (SBPMsgDopsDepA n m) = SBPMsgDopsDepA n <$> f m
   msg f (SBPMsgEd25519Certificate n m) = SBPMsgEd25519Certificate n <$> f m
   msg f (SBPMsgEd25519Signature n m) = SBPMsgEd25519Signature n <$> f m
+  msg f (SBPMsgEd25519SignatureDep n m) = SBPMsgEd25519SignatureDep n <$> f m
   msg f (SBPMsgEphemerisBds n m) = SBPMsgEphemerisBds n <$> f m
   msg f (SBPMsgEphemerisDepA n m) = SBPMsgEphemerisDepA n <$> f m
   msg f (SBPMsgEphemerisDepB n m) = SBPMsgEphemerisDepB n <$> f m
@@ -1338,6 +1355,7 @@
   msg f (SBPMsgPosLlhCovGnss n m) = SBPMsgPosLlhCovGnss n <$> f m
   msg f (SBPMsgPosLlhDepA n m) = SBPMsgPosLlhDepA n <$> f m
   msg f (SBPMsgPosLlhGnss n m) = SBPMsgPosLlhGnss n <$> f m
+  msg f (SBPMsgPoseRelative n m) = SBPMsgPoseRelative n <$> f m
   msg f (SBPMsgPpsTime n m) = SBPMsgPpsTime n <$> f m
   msg f (SBPMsgPrintDep n m) = SBPMsgPrintDep n <$> f m
   msg f (SBPMsgProtectionLevel n m) = SBPMsgProtectionLevel n <$> f m
diff --git a/src/SwiftNav/SBP/Navigation.hs b/src/SwiftNav/SBP/Navigation.hs
--- a/src/SwiftNav/SBP/Navigation.hs
+++ b/src/SwiftNav/SBP/Navigation.hs
@@ -2456,3 +2456,120 @@
 $(makeSBP 'msgReferenceFrameParam ''MsgReferenceFrameParam)
 $(makeJSON "_msgReferenceFrameParam_" ''MsgReferenceFrameParam)
 $(makeLenses ''MsgReferenceFrameParam)
+
+msgPoseRelative :: Word16
+msgPoseRelative = 0x0245
+
+-- | SBP class for message MSG_POSE_RELATIVE (0x0245).
+--
+-- This solution message reports the relative pose of a sensor between two
+-- time instances. The relative pose comprises of a rotation and a translation
+-- which relates the sensor (e.g. camera) frame at a given time (first
+-- keyframe) to the sensor frame at another time (second keyframe). The
+-- relative translations is a 3x1 vector described in the first keyframe.
+-- Relative rotation is described by a quaternion from second keyframe to the
+-- first keyframe.
+data MsgPoseRelative = MsgPoseRelative
+  { _msgPoseRelative_tow       :: !Word32
+    -- ^ GPS Time of Week
+  , _msgPoseRelative_sensor_id :: !Word8
+    -- ^ ID of the sensor producing this message
+  , _msgPoseRelative_timestamp_1 :: !Word32
+    -- ^ Timestamp of first keyframe
+  , _msgPoseRelative_timestamp_2 :: !Word32
+    -- ^ Timestamp of second keyframe
+  , _msgPoseRelative_trans     :: ![Int32]
+    -- ^ Relative translation [x,y,z] described in first keyframe
+  , _msgPoseRelative_w         :: !Int32
+    -- ^ Real component of quaternion to describe relative rotation (second to
+    -- first keyframe)
+  , _msgPoseRelative_x         :: !Int32
+    -- ^ 1st imaginary component of quaternion to describe relative rotation
+    -- (second to first keyframe)
+  , _msgPoseRelative_y         :: !Int32
+    -- ^ 2nd imaginary component of quaternion to describe relative rotation
+    -- (second to first keyframe)
+  , _msgPoseRelative_z         :: !Int32
+    -- ^ 3rd imaginary component of quaternion to describe relative rotation
+    -- (second to first keyframe)
+  , _msgPoseRelative_cov_r_x_x :: !Float
+    -- ^ Estimated variance of x (relative translation)
+  , _msgPoseRelative_cov_r_x_y :: !Float
+    -- ^ Covariance of x and y (relative translation)
+  , _msgPoseRelative_cov_r_x_z :: !Float
+    -- ^ Covariance of x and z (relative translation)
+  , _msgPoseRelative_cov_r_y_y :: !Float
+    -- ^ Estimated variance of y (relative translation)
+  , _msgPoseRelative_cov_r_y_z :: !Float
+    -- ^ Covariance of y and z (relative translation)
+  , _msgPoseRelative_cov_r_z_z :: !Float
+    -- ^ Estimated variance of z (relative translation)
+  , _msgPoseRelative_cov_c_x_x :: !Float
+    -- ^ Estimated variance of x (relative rotation)
+  , _msgPoseRelative_cov_c_x_y :: !Float
+    -- ^ Covariance of x and y (relative rotation)
+  , _msgPoseRelative_cov_c_x_z :: !Float
+    -- ^ Covariance of x and z (relative rotation)
+  , _msgPoseRelative_cov_c_y_y :: !Float
+    -- ^ Estimated variance of y (relative rotation)
+  , _msgPoseRelative_cov_c_y_z :: !Float
+    -- ^ Covariance of y and z (relative rotation)
+  , _msgPoseRelative_cov_c_z_z :: !Float
+    -- ^ Estimated variance of z (relative rotation)
+  , _msgPoseRelative_flags     :: !Word8
+    -- ^ Status flags of relative translation and rotation
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgPoseRelative where
+  get = do
+    _msgPoseRelative_tow <- getWord32le
+    _msgPoseRelative_sensor_id <- getWord8
+    _msgPoseRelative_timestamp_1 <- getWord32le
+    _msgPoseRelative_timestamp_2 <- getWord32le
+    _msgPoseRelative_trans <- replicateM 3 (fromIntegral <$> getWord32le)
+    _msgPoseRelative_w <- (fromIntegral <$> getWord32le)
+    _msgPoseRelative_x <- (fromIntegral <$> getWord32le)
+    _msgPoseRelative_y <- (fromIntegral <$> getWord32le)
+    _msgPoseRelative_z <- (fromIntegral <$> getWord32le)
+    _msgPoseRelative_cov_r_x_x <- getFloat32le
+    _msgPoseRelative_cov_r_x_y <- getFloat32le
+    _msgPoseRelative_cov_r_x_z <- getFloat32le
+    _msgPoseRelative_cov_r_y_y <- getFloat32le
+    _msgPoseRelative_cov_r_y_z <- getFloat32le
+    _msgPoseRelative_cov_r_z_z <- getFloat32le
+    _msgPoseRelative_cov_c_x_x <- getFloat32le
+    _msgPoseRelative_cov_c_x_y <- getFloat32le
+    _msgPoseRelative_cov_c_x_z <- getFloat32le
+    _msgPoseRelative_cov_c_y_y <- getFloat32le
+    _msgPoseRelative_cov_c_y_z <- getFloat32le
+    _msgPoseRelative_cov_c_z_z <- getFloat32le
+    _msgPoseRelative_flags <- getWord8
+    pure MsgPoseRelative {..}
+
+  put MsgPoseRelative {..} = do
+    putWord32le _msgPoseRelative_tow
+    putWord8 _msgPoseRelative_sensor_id
+    putWord32le _msgPoseRelative_timestamp_1
+    putWord32le _msgPoseRelative_timestamp_2
+    mapM_ (putWord32le . fromIntegral) _msgPoseRelative_trans
+    (putWord32le . fromIntegral) _msgPoseRelative_w
+    (putWord32le . fromIntegral) _msgPoseRelative_x
+    (putWord32le . fromIntegral) _msgPoseRelative_y
+    (putWord32le . fromIntegral) _msgPoseRelative_z
+    putFloat32le _msgPoseRelative_cov_r_x_x
+    putFloat32le _msgPoseRelative_cov_r_x_y
+    putFloat32le _msgPoseRelative_cov_r_x_z
+    putFloat32le _msgPoseRelative_cov_r_y_y
+    putFloat32le _msgPoseRelative_cov_r_y_z
+    putFloat32le _msgPoseRelative_cov_r_z_z
+    putFloat32le _msgPoseRelative_cov_c_x_x
+    putFloat32le _msgPoseRelative_cov_c_x_y
+    putFloat32le _msgPoseRelative_cov_c_x_z
+    putFloat32le _msgPoseRelative_cov_c_y_y
+    putFloat32le _msgPoseRelative_cov_c_y_z
+    putFloat32le _msgPoseRelative_cov_c_z_z
+    putWord8 _msgPoseRelative_flags
+
+$(makeSBP 'msgPoseRelative ''MsgPoseRelative)
+$(makeJSON "_msgPoseRelative_" ''MsgPoseRelative)
+$(makeLenses ''MsgPoseRelative)
diff --git a/src/SwiftNav/SBP/Signing.hs b/src/SwiftNav/SBP/Signing.hs
--- a/src/SwiftNav/SBP/Signing.hs
+++ b/src/SwiftNav/SBP/Signing.hs
@@ -36,33 +36,33 @@
 {-# ANN module ("HLint: ignore Use newtype instead of data"::String) #-}
 
 
-msgEd25519Signature :: Word16
-msgEd25519Signature = 0x0C01
+msgEd25519SignatureDep :: Word16
+msgEd25519SignatureDep = 0x0C01
 
-data MsgEd25519Signature = MsgEd25519Signature
-  { _msgEd25519Signature_signature     :: ![Word8]
+data MsgEd25519SignatureDep = MsgEd25519SignatureDep
+  { _msgEd25519SignatureDep_signature     :: ![Word8]
     -- ^ ED25519 signature for messages.
-  , _msgEd25519Signature_fingerprint   :: ![Word8]
+  , _msgEd25519SignatureDep_fingerprint   :: ![Word8]
     -- ^ SHA-1 fingerprint of the associated certificate.
-  , _msgEd25519Signature_signed_messages :: ![Word32]
+  , _msgEd25519SignatureDep_signed_messages :: ![Word32]
     -- ^ CRCs of signed messages.
   } deriving ( Show, Read, Eq )
 
-instance Binary MsgEd25519Signature where
+instance Binary MsgEd25519SignatureDep where
   get = do
-    _msgEd25519Signature_signature <- replicateM 64 getWord8
-    _msgEd25519Signature_fingerprint <- replicateM 20 getWord8
-    _msgEd25519Signature_signed_messages <- whileM (not <$> isEmpty) getWord32le
-    pure MsgEd25519Signature {..}
+    _msgEd25519SignatureDep_signature <- replicateM 64 getWord8
+    _msgEd25519SignatureDep_fingerprint <- replicateM 20 getWord8
+    _msgEd25519SignatureDep_signed_messages <- whileM (not <$> isEmpty) getWord32le
+    pure MsgEd25519SignatureDep {..}
 
-  put MsgEd25519Signature {..} = do
-    mapM_ putWord8 _msgEd25519Signature_signature
-    mapM_ putWord8 _msgEd25519Signature_fingerprint
-    mapM_ putWord32le _msgEd25519Signature_signed_messages
+  put MsgEd25519SignatureDep {..} = do
+    mapM_ putWord8 _msgEd25519SignatureDep_signature
+    mapM_ putWord8 _msgEd25519SignatureDep_fingerprint
+    mapM_ putWord32le _msgEd25519SignatureDep_signed_messages
 
-$(makeSBP 'msgEd25519Signature ''MsgEd25519Signature)
-$(makeJSON "_msgEd25519Signature_" ''MsgEd25519Signature)
-$(makeLenses ''MsgEd25519Signature)
+$(makeSBP 'msgEd25519SignatureDep ''MsgEd25519SignatureDep)
+$(makeJSON "_msgEd25519SignatureDep_" ''MsgEd25519SignatureDep)
+$(makeLenses ''MsgEd25519SignatureDep)
 
 msgEd25519Certificate :: Word16
 msgEd25519Certificate = 0x0C02
@@ -93,3 +93,46 @@
 $(makeSBP 'msgEd25519Certificate ''MsgEd25519Certificate)
 $(makeJSON "_msgEd25519Certificate_" ''MsgEd25519Certificate)
 $(makeLenses ''MsgEd25519Certificate)
+
+msgEd25519Signature :: Word16
+msgEd25519Signature = 0x0C03
+
+data MsgEd25519Signature = MsgEd25519Signature
+  { _msgEd25519Signature_stream_counter  :: !Word8
+    -- ^ Signature message counter. Zero indexed and incremented with each
+    -- signature message. The counter will not increment if this message was
+    -- in response to an on demand request. The counter will roll over after
+    -- 256 messages. Upon connection, the value of the counter may not
+    -- initially be zero.
+  , _msgEd25519Signature_on_demand_counter :: !Word8
+    -- ^ On demand message counter. Zero indexed and incremented with each
+    -- signature message sent in response to an on demand message. The counter
+    -- will roll over after 256 messages. Upon connection, the value of the
+    -- counter may not initially be zero.
+  , _msgEd25519Signature_signature       :: ![Word8]
+    -- ^ ED25519 signature for messages.
+  , _msgEd25519Signature_fingerprint     :: ![Word8]
+    -- ^ SHA-1 fingerprint of the associated certificate.
+  , _msgEd25519Signature_signed_messages :: ![Word32]
+    -- ^ CRCs of signed messages.
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgEd25519Signature where
+  get = do
+    _msgEd25519Signature_stream_counter <- getWord8
+    _msgEd25519Signature_on_demand_counter <- getWord8
+    _msgEd25519Signature_signature <- replicateM 64 getWord8
+    _msgEd25519Signature_fingerprint <- replicateM 20 getWord8
+    _msgEd25519Signature_signed_messages <- whileM (not <$> isEmpty) getWord32le
+    pure MsgEd25519Signature {..}
+
+  put MsgEd25519Signature {..} = do
+    putWord8 _msgEd25519Signature_stream_counter
+    putWord8 _msgEd25519Signature_on_demand_counter
+    mapM_ putWord8 _msgEd25519Signature_signature
+    mapM_ putWord8 _msgEd25519Signature_fingerprint
+    mapM_ putWord32le _msgEd25519Signature_signed_messages
+
+$(makeSBP 'msgEd25519Signature ''MsgEd25519Signature)
+$(makeJSON "_msgEd25519Signature_" ''MsgEd25519Signature)
+$(makeLenses ''MsgEd25519Signature)
