{-# OPTIONS_GHC -O2 -feager-blackholing #-}
{-# LANGUAGE Trustworthy #-}
module Crypto.ECC.Weierstrass.ECDSA ( basicecdsa
, basicecdsaVerify
, ECPF
)
where
import safe Crypto.ECC.Weierstrass.Internal.Curvemath
import safe Crypto.ECC.Weierstrass.StandardCurves
import safe qualified Crypto.Fi as FP
import safe qualified Crypto.ECC.Ed25519.Internal as Ed
import qualified Crypto.Hash.SHA512 as H
import safe qualified Data.ByteString as BS
basicecdsa :: BS.ByteString -> Integer -> Integer -> Either String (Integer,Integer)
basicecdsa :: ByteString
-> Integer -> Integer -> Either String (Integer, Integer)
basicecdsa ByteString
bs Integer
dA Integer
k =
let curve :: EC Integer
curve = Int -> Integer -> Integer -> Integer -> EC Integer
ECi (StandardCurve -> Int
stdc_l StandardCurve
p256) (StandardCurve -> Integer
stdc_b StandardCurve
p256) (StandardCurve -> Integer
stdc_p StandardCurve
p256) (StandardCurve -> Integer
stdc_r StandardCurve
p256)
bPoint :: ECPF Integer
bPoint = Integer -> Integer -> Integer -> ECPF Integer
ECPp (StandardCurve -> Integer
stdc_xp StandardCurve
p256) (StandardCurve -> Integer
stdc_yp StandardCurve
p256) Integer
1
order :: Integer
order = StandardCurve -> Integer
stdc_r StandardCurve
p256
Right Integer
z = ByteString -> Either String Integer
Ed.getFPrime32 (ByteString -> Either String Integer)
-> ByteString -> Either String Integer
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
h ByteString
bs
(Integer
x1,Integer
_) = EC Integer -> ECPF Integer -> (Integer, Integer)
forall a. EC a -> ECPF a -> (Integer, Integer)
affine EC Integer
curve (ECPF Integer -> (Integer, Integer))
-> ECPF Integer -> (Integer, Integer)
forall a b. (a -> b) -> a -> b
$ EC Integer -> ECPF Integer -> Integer -> ECPF Integer
forall a. EC a -> ECPF a -> Integer -> ECPF a
pmul EC Integer
curve ECPF Integer
bPoint Integer
k
r :: Integer
r = Integer
x1 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
order
s :: Integer
s = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
order (Integer -> Integer -> Integer
FP.inv Integer
order Integer
k) (Integer -> Integer -> Integer
FP.add Integer
z (Integer -> Integer -> Integer -> Integer
FP.mulr Integer
order Integer
r Integer
dA))
in if Integer
r Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0 Bool -> Bool -> Bool
&& Integer
s Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
then (Integer, Integer) -> Either String (Integer, Integer)
forall a b. b -> Either a b
Right (Integer
r,Integer
s)
else String -> Either String (Integer, Integer)
forall a b. a -> Either a b
Left String
"fail"
basicecdsaVerify :: ECPF Integer -> (Integer,Integer) -> BS.ByteString -> Bool
basicecdsaVerify :: ECPF Integer -> (Integer, Integer) -> ByteString -> Bool
basicecdsaVerify ECPF Integer
dB (Integer
r,Integer
s) ByteString
m = let curve :: EC Integer
curve = Int -> Integer -> Integer -> Integer -> EC Integer
ECi (StandardCurve -> Int
stdc_l StandardCurve
p256) (StandardCurve -> Integer
stdc_b StandardCurve
p256) (StandardCurve -> Integer
stdc_p StandardCurve
p256) (StandardCurve -> Integer
stdc_r StandardCurve
p256)
order :: Integer
order = StandardCurve -> Integer
stdc_r StandardCurve
p256
bPoint :: ECPF Integer
bPoint = Integer -> Integer -> Integer -> ECPF Integer
ECPp (StandardCurve -> Integer
stdc_xp StandardCurve
p256) (StandardCurve -> Integer
stdc_yp StandardCurve
p256) Integer
1
Right Integer
z = ByteString -> Either String Integer
Ed.getFPrime32 (ByteString -> Either String Integer)
-> ByteString -> Either String Integer
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
h ByteString
m
w :: Integer
w = Integer -> Integer -> Integer
FP.inv Integer
order Integer
s
u1 :: Integer
u1 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
order Integer
z Integer
w
u2 :: Integer
u2 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
order Integer
r Integer
w
point :: ECPF Integer
point = EC Integer -> ECPF Integer -> ECPF Integer -> ECPF Integer
forall a. EC a -> ECPF a -> ECPF a -> ECPF a
padd EC Integer
curve (EC Integer -> ECPF Integer -> Integer -> ECPF Integer
forall a. EC a -> ECPF a -> Integer -> ECPF a
pmul EC Integer
curve ECPF Integer
bPoint Integer
u1) (EC Integer -> ECPF Integer -> Integer -> ECPF Integer
forall a. EC a -> ECPF a -> Integer -> ECPF a
pmul EC Integer
curve ECPF Integer
dB Integer
u2)
(Integer
x1,Integer
_) = EC Integer -> ECPF Integer -> (Integer, Integer)
forall a. EC a -> ECPF a -> (Integer, Integer)
affine EC Integer
curve ECPF Integer
point
in Bool -> Bool
not (EC Integer -> ECPF Integer -> Bool
forall a. EC a -> ECPF a -> Bool
isinf EC Integer
curve ECPF Integer
dB) Bool -> Bool -> Bool
&& EC Integer -> ECPF Integer -> Bool
forall a. EC a -> ECPF a -> Bool
ison EC Integer
curve ECPF Integer
dB Bool -> Bool -> Bool
&& EC Integer -> ECPF Integer -> Bool
forall a. EC a -> ECPF a -> Bool
isinf EC Integer
curve (EC Integer -> ECPF Integer -> Integer -> ECPF Integer
forall a. EC a -> ECPF a -> Integer -> ECPF a
pmul EC Integer
curve ECPF Integer
dB Integer
order) Bool -> Bool -> Bool
&& Integer
r Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 Bool -> Bool -> Bool
&& Integer
r Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
order Bool -> Bool -> Bool
&& Integer
s Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 Bool -> Bool -> Bool
&& Integer
s Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
order Bool -> Bool -> Bool
&& Bool -> Bool
not (EC Integer -> ECPF Integer -> Bool
forall a. EC a -> ECPF a -> Bool
isinf EC Integer
curve ECPF Integer
point) Bool -> Bool -> Bool
&& Integer
x1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
r
h :: BS.ByteString -> BS.ByteString
h :: ByteString -> ByteString
h = ByteString -> ByteString
H.hash