module Wire.API.MLS.ECDSA where
import Crypto.Error
import Crypto.Hash hiding (hash)
import Crypto.PubKey.ECDSA
import Data.ASN1.BinaryEncoding
import Data.ASN1.Encoding
import Data.ASN1.Prim
import Data.Proxy
import Imports
import Wire.API.MLS.Serialisation
decodeSignature ::
forall curve.
(EllipticCurveECDSA curve) =>
Proxy curve ->
ByteString ->
Maybe (Signature curve)
decodeSignature :: forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> ByteString -> Maybe (Signature curve)
decodeSignature Proxy curve
curve ByteString
bs = do
(Integer, Integer)
ints <- case DER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' DER
DER ByteString
bs of
Right ([Start ASN1ConstructionType
Sequence, IntVal Integer
r, IntVal Integer
s, End ASN1ConstructionType
Sequence]) -> (Integer, Integer) -> Maybe (Integer, Integer)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer
r, Integer
s)
Either ASN1Error [ASN1]
_ -> Maybe (Integer, Integer)
forall a. Maybe a
Nothing
CryptoFailable (Signature curve) -> Maybe (Signature curve)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (Signature curve) -> Maybe (Signature curve))
-> CryptoFailable (Signature curve) -> Maybe (Signature curve)
forall a b. (a -> b) -> a -> b
$ Proxy curve
-> (Integer, Integer) -> CryptoFailable (Signature curve)
forall curve (proxy :: * -> *).
EllipticCurveECDSA curve =>
proxy curve
-> (Integer, Integer) -> CryptoFailable (Signature curve)
signatureFromIntegers Proxy curve
curve (Integer, Integer)
ints
encodeSignature ::
forall curve.
(EllipticCurveECDSA curve) =>
Proxy curve ->
Signature curve ->
ByteString
encodeSignature :: forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> Signature curve -> ByteString
encodeSignature Proxy curve
curve Signature curve
sig = case Proxy curve -> Signature curve -> (Integer, Integer)
forall curve (proxy :: * -> *).
EllipticCurveECDSA curve =>
proxy curve -> Signature curve -> (Integer, Integer)
signatureToIntegers Proxy curve
curve Signature curve
sig of
(Integer
r, Integer
s) ->
DER -> [ASN1] -> ByteString
forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
encodeASN1'
DER
DER
[ ASN1ConstructionType -> ASN1
Start ASN1ConstructionType
Sequence,
Integer -> ASN1
IntVal Integer
r,
Integer -> ASN1
IntVal Integer
s,
ASN1ConstructionType -> ASN1
End ASN1ConstructionType
Sequence
]
verifySignature ::
forall curve a hash.
( EllipticCurveECDSA curve,
HashAlgorithm hash
) =>
Proxy curve ->
hash ->
ByteString ->
RawMLS a ->
ByteString ->
Bool
verifySignature :: forall curve a hash.
(EllipticCurveECDSA curve, HashAlgorithm hash) =>
Proxy curve -> hash -> ByteString -> RawMLS a -> ByteString -> Bool
verifySignature Proxy curve
curve hash
hash ByteString
pub RawMLS a
x ByteString
sig =
Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> Maybe Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
Signature curve
sig' <- Proxy curve -> ByteString -> Maybe (Signature curve)
forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> ByteString -> Maybe (Signature curve)
decodeSignature Proxy curve
curve ByteString
sig
Point curve
pub' <- CryptoFailable (Point curve) -> Maybe (Point curve)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (Point curve) -> Maybe (Point curve))
-> CryptoFailable (Point curve) -> Maybe (Point curve)
forall a b. (a -> b) -> a -> b
$ Proxy curve -> ByteString -> CryptoFailable (Point curve)
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> bs -> CryptoFailable (PublicKey curve)
decodePublic Proxy curve
curve ByteString
pub
let valid :: Bool
valid = Proxy curve
-> hash -> Point curve -> Signature curve -> ByteString -> Bool
forall curve msg hash (proxy :: * -> *).
(EllipticCurveECDSA curve, ByteArrayAccess msg,
HashAlgorithm hash) =>
proxy curve
-> hash -> PublicKey curve -> Signature curve -> msg -> Bool
verify Proxy curve
curve hash
hash Point curve
pub' Signature curve
sig' RawMLS a
x.raw
Bool -> Maybe Bool
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
valid