Initial commit
This commit is contained in:
commit
c101616e62
309 changed files with 53937 additions and 0 deletions
134
bundled/Network/Stellar/Signature.hs
Normal file
134
bundled/Network/Stellar/Signature.hs
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
|
||||
module Network.Stellar.Signature
|
||||
( signBlob
|
||||
, verifyBlob
|
||||
, verifyBlobWithKP
|
||||
, signTx
|
||||
, verifyTx
|
||||
, transactionHash
|
||||
)
|
||||
where
|
||||
|
||||
import qualified Crypto.Sign.Ed25519 as C
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as LB
|
||||
import Data.Digest.Pure.SHA (bytestringDigest, sha256)
|
||||
import qualified Data.Vector as Vector
|
||||
|
||||
import Network.ONCRPC.XDR (xdrSerialize)
|
||||
import qualified Network.ONCRPC.XDR as XDR
|
||||
import Network.ONCRPC.XDR.Array (boundLengthArray, lengthArray',
|
||||
unLengthArray, unsafeLengthArray)
|
||||
import Network.Stellar.Keypair
|
||||
import Network.Stellar.Network
|
||||
import Network.Stellar.TransactionXdr
|
||||
|
||||
signBlob :: KeyPair -> ByteString -> ByteString
|
||||
signBlob KeyPair{kpPrivateKey} = C.unSignature . C.dsign kpPrivateKey
|
||||
|
||||
verifyBlob
|
||||
:: C.PublicKey
|
||||
-> ByteString -- ^ message
|
||||
-> ByteString -- ^ signature
|
||||
-> Bool
|
||||
verifyBlob publicKey message = C.dverify publicKey message . C.Signature
|
||||
|
||||
verifyBlobWithKP
|
||||
:: KeyPair
|
||||
-> ByteString -- ^ message
|
||||
-> ByteString -- ^ signature
|
||||
-> Bool
|
||||
verifyBlobWithKP KeyPair{kpPublicKey} message =
|
||||
C.dverify kpPublicKey message . C.Signature
|
||||
|
||||
data SignError = TooManySignatures
|
||||
deriving Show
|
||||
|
||||
takeEnd :: Int -> ByteString -> ByteString
|
||||
takeEnd n bs = B.drop (B.length bs - n) bs
|
||||
|
||||
accountXdrFromEd :: C.PublicKey -> AccountID
|
||||
accountXdrFromEd (C.PublicKey key) =
|
||||
PublicKey'PUBLIC_KEY_TYPE_ED25519 $ lengthArray' key
|
||||
|
||||
keyToHint :: KeyPair -> SignatureHint
|
||||
keyToHint KeyPair{kpPublicKey} =
|
||||
lengthArray' $ takeEnd 4 $ xdrSerialize $ accountXdrFromEd kpPublicKey
|
||||
|
||||
signTx
|
||||
:: Network
|
||||
-> TransactionEnvelope
|
||||
-> [KeyPair]
|
||||
-> Either SignError TransactionEnvelope
|
||||
signTx nId envelope newKeys =
|
||||
case envelope of
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX_V0
|
||||
(TransactionV0Envelope tx signatures) ->
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX_V0 . TransactionV0Envelope tx
|
||||
<$> appendSignatures signatures
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX
|
||||
(TransactionV1Envelope tx signatures) ->
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX . TransactionV1Envelope tx
|
||||
<$> appendSignatures signatures
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX_FEE_BUMP
|
||||
(FeeBumpTransactionEnvelope tx signatures) ->
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX_FEE_BUMP
|
||||
. FeeBumpTransactionEnvelope tx
|
||||
<$> appendSignatures signatures
|
||||
where
|
||||
signature :: KeyPair -> Signature
|
||||
signature KeyPair{kpPrivateKey} =
|
||||
boundLengthArray $
|
||||
C.unSignature $ C.dsign kpPrivateKey $ transactionHash nId envelope
|
||||
|
||||
appendSignatures
|
||||
:: XDR.Array 20 DecoratedSignature
|
||||
-> Either SignError (XDR.Array 20 DecoratedSignature)
|
||||
appendSignatures oldSignatures
|
||||
| Vector.length oldSignatures' + length newKeys <= 20 =
|
||||
Right $
|
||||
unsafeLengthArray $
|
||||
oldSignatures'
|
||||
<> Vector.fromList
|
||||
[ DecoratedSignature (keyToHint key) (signature key)
|
||||
| key <- newKeys
|
||||
]
|
||||
| otherwise = Left TooManySignatures
|
||||
where
|
||||
oldSignatures' = unLengthArray oldSignatures
|
||||
|
||||
transactionHash :: Network -> TransactionEnvelope -> ByteString
|
||||
transactionHash nId = \case
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX_V0 (TransactionV0Envelope tx _) ->
|
||||
go ( xdrSerialize ENVELOPE_TYPE_TX
|
||||
<> xdrSerialize PUBLIC_KEY_TYPE_ED25519
|
||||
)
|
||||
tx
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX (TransactionV1Envelope tx _) ->
|
||||
go (xdrSerialize ENVELOPE_TYPE_TX) tx
|
||||
TransactionEnvelope'ENVELOPE_TYPE_TX_FEE_BUMP
|
||||
(FeeBumpTransactionEnvelope tx _) ->
|
||||
go (xdrSerialize ENVELOPE_TYPE_TX_FEE_BUMP) tx
|
||||
where
|
||||
go prefix tx =
|
||||
LB.toStrict $
|
||||
bytestringDigest $
|
||||
sha256 $
|
||||
LB.fromStrict $
|
||||
B.concat [nId, prefix, xdrSerialize tx]
|
||||
|
||||
verifyTx
|
||||
:: Network
|
||||
-> TransactionEnvelope
|
||||
-> C.PublicKey
|
||||
-> DecoratedSignature
|
||||
-> Bool
|
||||
verifyTx nId envelope publicKey (DecoratedSignature _ signature) =
|
||||
C.dverify
|
||||
publicKey
|
||||
(transactionHash nId envelope)
|
||||
(C.Signature $ unLengthArray signature)
|
||||
Loading…
Add table
Add a link
Reference in a new issue