{-# LANGUAGE BangPatterns #-}
module Crypto.PubKey.ECC.Prim (
scalarGenerate,
scalarInverse,
scalarAdd,
scalarMul,
pointAdd,
pointNegate,
pointDouble,
pointBaseMul,
pointMul,
pointAddTwoMuls,
pointDecompose,
pointCompose,
isPointAtInfinity,
isPointValid,
isPointInSubgroup,
) where
import Crypto.Error (maybeCryptoError)
import Crypto.Internal.ECC (CurveField (..), MulResult (..), curveMul)
import Crypto.Number.Basic (numBits)
import Crypto.Number.F2m
import Crypto.Number.Generate (generateBetween)
import Crypto.Number.ModArithmetic
import qualified Crypto.PubKey.ECC.P256 as P256
import Crypto.PubKey.ECC.Types
import Crypto.Random
import Data.Bits (shiftL, shiftR, testBit, (.&.))
import Data.Maybe
p256Curve :: Curve
p256Curve :: Curve
p256Curve = CurveName -> Curve
getCurveByName CurveName
SEC_p256r1
{-# NOINLINE p256Curve #-}
p256Order :: Integer
p256Order :: Integer
p256Order = CurveCommon -> Integer
ecc_n (Curve -> CurveCommon
common_curve Curve
p256Curve)
p256Base :: Point
p256Base :: Point
p256Base = CurveCommon -> Point
ecc_g (Curve -> CurveCommon
common_curve Curve
p256Curve)
toP256 :: Point -> Maybe P256.Point
toP256 :: Point -> Maybe Point
toP256 Point
PointO = Maybe Point
forall a. Maybe a
Nothing
toP256 (Point Integer
x Integer
y)
| Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 Bool -> Bool -> Bool
|| Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 Bool -> Bool -> Bool
|| Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
limit Bool -> Bool -> Bool
|| Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
limit = Maybe Point
forall a. Maybe a
Nothing
| Point -> Bool
P256.pointIsValid Point
p = Point -> Maybe Point
forall a. a -> Maybe a
Just Point
p
| Bool
otherwise = Maybe Point
forall a. Maybe a
Nothing
where
limit :: Integer
limit = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
256
p :: Point
p = (Integer, Integer) -> Point
P256.pointFromIntegers (Integer
x, Integer
y)
fromP256 :: P256.Point -> Point
fromP256 :: Point -> Point
fromP256 Point
p
| Point -> Bool
P256.pointIsAtInfinity Point
p = Point
PointO
| Bool
otherwise = (Integer -> Integer -> Point) -> (Integer, Integer) -> Point
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Integer -> Integer -> Point
Point (Point -> (Integer, Integer)
P256.pointToIntegers Point
p)
p256Scalar :: Integer -> Maybe P256.Scalar
p256Scalar :: Integer -> Maybe Scalar
p256Scalar Integer
n
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 Bool -> Bool -> Bool
|| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
256 = Maybe Scalar
forall a. Maybe a
Nothing
| Bool
otherwise = CryptoFailable Scalar -> Maybe Scalar
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (Integer -> CryptoFailable Scalar
P256.scalarFromInteger Integer
n)
toP256Scalar :: Integer -> Maybe P256.Scalar
toP256Scalar :: Integer -> Maybe Scalar
toP256Scalar Integer
n = case Scalar -> Scalar
P256.scalarReduce (Scalar -> Scalar) -> Maybe Scalar -> Maybe Scalar
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> Maybe Scalar
p256Scalar Integer
n of
Maybe Scalar
Nothing -> Integer -> Maybe Scalar
toP256Scalar (Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
p256Order)
Just Scalar
s
| Scalar -> Bool
P256.scalarIsZero Scalar
s -> Maybe Scalar
forall a. Maybe a
Nothing
| Bool
otherwise -> Scalar -> Maybe Scalar
forall a. a -> Maybe a
Just Scalar
s
p256AddTwoMuls :: Integer -> Point -> Integer -> Point -> Maybe Point
p256AddTwoMuls :: Integer -> Point -> Integer -> Point -> Maybe Point
p256AddTwoMuls Integer
n1 Point
p1 Integer
n2 Point
p2
| Point
p1 Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
p256Base = Integer -> Integer -> Point -> Maybe Point
withBase Integer
n1 Integer
n2 Point
p2
| Point
p2 Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
p256Base = Integer -> Integer -> Point -> Maybe Point
withBase Integer
n2 Integer
n1 Point
p1
| Bool
otherwise = Maybe Point
forall a. Maybe a
Nothing
where
withBase :: Integer -> Integer -> Point -> Maybe Point
withBase Integer
a Integer
b Point
q =
Point -> Point
fromP256
(Point -> Point) -> Maybe Point -> Maybe Point
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Scalar -> Scalar -> Point -> Point
P256.pointsMulVarTime (Scalar -> Scalar -> Point -> Point)
-> Maybe Scalar -> Maybe (Scalar -> Point -> Point)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> Maybe Scalar
toP256Scalar Integer
a Maybe (Scalar -> Point -> Point)
-> Maybe Scalar -> Maybe (Point -> Point)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Integer -> Maybe Scalar
toP256Scalar Integer
b Maybe (Point -> Point) -> Maybe Point -> Maybe Point
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Point -> Maybe Point
toP256 Point
q)
scalarGenerate :: MonadRandom randomly => Curve -> randomly PrivateNumber
scalarGenerate :: forall (randomly :: * -> *).
MonadRandom randomly =>
Curve -> randomly Integer
scalarGenerate Curve
curve = Integer -> Integer -> randomly Integer
forall (m :: * -> *).
MonadRandom m =>
Integer -> Integer -> m Integer
generateBetween Integer
1 (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
where
n :: Integer
n = CurveCommon -> Integer
ecc_n (CurveCommon -> Integer) -> CurveCommon -> Integer
forall a b. (a -> b) -> a -> b
$ Curve -> CurveCommon
common_curve Curve
curve
scalarInverse :: Curve -> Integer -> Maybe Integer
scalarInverse :: Curve -> Integer -> Maybe Integer
scalarInverse Curve
c Integer
k
| Curve
c Curve -> Curve -> Bool
forall a. Eq a => a -> a -> Bool
== Curve
p256Curve
, Just Scalar
s <- Integer -> Maybe Scalar
toP256Scalar Integer
k =
Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Scalar -> Integer
P256.scalarToInteger (Scalar -> Scalar
P256.scalarInvSafe Scalar
s))
| Bool
otherwise = Integer -> Integer -> Maybe Integer
inverseSafe Integer
k (CurveCommon -> Integer
ecc_n (CurveCommon -> Integer) -> CurveCommon -> Integer
forall a b. (a -> b) -> a -> b
$ Curve -> CurveCommon
common_curve Curve
c)
scalarAdd :: Curve -> Integer -> Integer -> Integer
scalarAdd :: Curve -> Integer -> Integer -> Integer
scalarAdd Curve
c Integer
a Integer
b
| Curve
c Curve -> Curve -> Bool
forall a. Eq a => a -> a -> Bool
== Curve
p256Curve
, Just Scalar
x <- Integer -> Maybe Scalar
p256Scalar Integer
a
, Just Scalar
y <- Integer -> Maybe Scalar
p256Scalar Integer
b =
Scalar -> Integer
P256.scalarToInteger (Scalar -> Scalar -> Scalar
P256.scalarAdd Scalar
x Scalar
y)
| Bool
otherwise = (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` CurveCommon -> Integer
ecc_n (Curve -> CurveCommon
common_curve Curve
c)
scalarMul :: Curve -> Integer -> Integer -> Integer
scalarMul :: Curve -> Integer -> Integer -> Integer
scalarMul Curve
c Integer
a Integer
b
| Curve
c Curve -> Curve -> Bool
forall a. Eq a => a -> a -> Bool
== Curve
p256Curve
, Just Scalar
x <- Integer -> Maybe Scalar
p256Scalar Integer
a
, Just Scalar
y <- Integer -> Maybe Scalar
p256Scalar Integer
b =
Scalar -> Integer
P256.scalarToInteger (Scalar -> Scalar -> Scalar
P256.scalarMul Scalar
x Scalar
y)
| Bool
otherwise = (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` CurveCommon -> Integer
ecc_n (Curve -> CurveCommon
common_curve Curve
c)
pointNegate :: Curve -> Point -> Point
pointNegate :: Curve -> Point -> Point
pointNegate Curve
_ Point
PointO = Point
PointO
pointNegate (CurveFP CurvePrime
c) (Point Integer
x Integer
y) = Integer -> Integer -> Point
Point Integer
x (CurvePrime -> Integer
ecc_p CurvePrime
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
y)
pointNegate CurveF2m{} (Point Integer
x Integer
y) = Integer -> Integer -> Point
Point Integer
x (Integer
x Integer -> Integer -> Integer
`addF2m` Integer
y)
pointAdd :: Curve -> Point -> Point -> Point
pointAdd :: Curve -> Point -> Point -> Point
pointAdd Curve
_ Point
PointO Point
PointO = Point
PointO
pointAdd Curve
_ Point
PointO Point
q = Point
q
pointAdd Curve
_ Point
p Point
PointO = Point
p
pointAdd Curve
c Point
p Point
q
| Point
p Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
q = Curve -> Point -> Point
pointDouble Curve
c Point
p
| Point
p Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Curve -> Point -> Point
pointNegate Curve
c Point
q = Point
PointO
pointAdd (CurveFP (CurvePrime Integer
pr CurveCommon
_)) (Point Integer
xp Integer
yp) (Point Integer
xq Integer
yq) =
Point -> Maybe Point -> Point
forall a. a -> Maybe a -> a
fromMaybe Point
PointO (Maybe Point -> Point) -> Maybe Point -> Point
forall a b. (a -> b) -> a -> b
$ do
Integer
s <- Integer -> Integer -> Integer -> Maybe Integer
divmod (Integer
yp Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
yq) (Integer
xp Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
xq) Integer
pr
let xr :: Integer
xr = (Integer
s Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
2 :: Int) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
xp Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
xq) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
pr
yr :: Integer
yr = (Integer
s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Integer
xp Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
xr) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
yp) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
pr
Point -> Maybe Point
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Point -> Maybe Point) -> Point -> Maybe Point
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Point
Point Integer
xr Integer
yr
pointAdd (CurveF2m (CurveBinary Integer
fx CurveCommon
cc)) (Point Integer
xp Integer
yp) (Point Integer
xq Integer
yq) =
Point -> Maybe Point -> Point
forall a. a -> Maybe a -> a
fromMaybe Point
PointO (Maybe Point -> Point) -> Maybe Point -> Point
forall a b. (a -> b) -> a -> b
$ do
Integer
s <- Integer -> Integer -> Integer -> Maybe Integer
divF2m Integer
fx (Integer
yp Integer -> Integer -> Integer
`addF2m` Integer
yq) (Integer
xp Integer -> Integer -> Integer
`addF2m` Integer
xq)
let xr :: Integer
xr = Integer -> Integer -> Integer -> Integer
mulF2m Integer
fx Integer
s Integer
s Integer -> Integer -> Integer
`addF2m` Integer
s Integer -> Integer -> Integer
`addF2m` Integer
xp Integer -> Integer -> Integer
`addF2m` Integer
xq Integer -> Integer -> Integer
`addF2m` Integer
a
yr :: Integer
yr = Integer -> Integer -> Integer -> Integer
mulF2m Integer
fx Integer
s (Integer
xp Integer -> Integer -> Integer
`addF2m` Integer
xr) Integer -> Integer -> Integer
`addF2m` Integer
xr Integer -> Integer -> Integer
`addF2m` Integer
yp
Point -> Maybe Point
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Point -> Maybe Point) -> Point -> Maybe Point
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Point
Point Integer
xr Integer
yr
where
a :: Integer
a = CurveCommon -> Integer
ecc_a CurveCommon
cc
pointDouble :: Curve -> Point -> Point
pointDouble :: Curve -> Point -> Point
pointDouble Curve
_ Point
PointO = Point
PointO
pointDouble (CurveFP (CurvePrime Integer
pr CurveCommon
cc)) (Point Integer
xp Integer
yp) = Point -> Maybe Point -> Point
forall a. a -> Maybe a -> a
fromMaybe Point
PointO (Maybe Point -> Point) -> Maybe Point -> Point
forall a b. (a -> b) -> a -> b
$ do
Integer
lambda <- Integer -> Integer -> Integer -> Maybe Integer
divmod (Integer
3 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
xp Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
2 :: Int) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
a) (Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
yp) Integer
pr
let xr :: Integer
xr = (Integer
lambda Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
2 :: Int) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
xp) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
pr
yr :: Integer
yr = (Integer
lambda Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Integer
xp Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
xr) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
yp) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
pr
Point -> Maybe Point
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Point -> Maybe Point) -> Point -> Maybe Point
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Point
Point Integer
xr Integer
yr
where
a :: Integer
a = CurveCommon -> Integer
ecc_a CurveCommon
cc
pointDouble (CurveF2m (CurveBinary Integer
fx CurveCommon
cc)) (Point Integer
xp Integer
yp)
| Integer
xp Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Point
PointO
| Bool
otherwise = Point -> Maybe Point -> Point
forall a. a -> Maybe a -> a
fromMaybe Point
PointO (Maybe Point -> Point) -> Maybe Point -> Point
forall a b. (a -> b) -> a -> b
$ do
Integer
s <- Integer -> Maybe Integer
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Maybe Integer)
-> (Integer -> Integer) -> Integer -> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer -> Integer
addF2m Integer
xp (Integer -> Maybe Integer) -> Maybe Integer -> Maybe Integer
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Integer -> Integer -> Integer -> Maybe Integer
divF2m Integer
fx Integer
yp Integer
xp
let xr :: Integer
xr = Integer -> Integer -> Integer -> Integer
mulF2m Integer
fx Integer
s Integer
s Integer -> Integer -> Integer
`addF2m` Integer
s Integer -> Integer -> Integer
`addF2m` Integer
a
yr :: Integer
yr = Integer -> Integer -> Integer -> Integer
mulF2m Integer
fx Integer
xp Integer
xp Integer -> Integer -> Integer
`addF2m` Integer -> Integer -> Integer -> Integer
mulF2m Integer
fx Integer
xr (Integer
s Integer -> Integer -> Integer
`addF2m` Integer
1)
Point -> Maybe Point
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Point -> Maybe Point) -> Point -> Maybe Point
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Point
Point Integer
xr Integer
yr
where
a :: Integer
a = CurveCommon -> Integer
ecc_a CurveCommon
cc
pointBaseMul :: Curve -> Integer -> Point
pointBaseMul :: Curve -> Integer -> Point
pointBaseMul Curve
c Integer
n = Curve -> Integer -> Point -> Point
pointMul Curve
c Integer
n (CurveCommon -> Point
ecc_g (CurveCommon -> Point) -> CurveCommon -> Point
forall a b. (a -> b) -> a -> b
$ Curve -> CurveCommon
common_curve Curve
c)
pointMul :: Curve -> Integer -> Point -> Point
pointMul :: Curve -> Integer -> Point -> Point
pointMul Curve
_ Integer
_ Point
PointO = Point
PointO
pointMul Curve
c Integer
n Point
p
| Curve
c Curve -> Curve -> Bool
forall a. Eq a => a -> a -> Bool
== Curve
p256Curve
, Point
p Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
p256Base =
Point -> (Scalar -> Point) -> Maybe Scalar -> Point
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Point
PointO (Point -> Point
fromP256 (Point -> Point) -> (Scalar -> Point) -> Scalar -> Point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scalar -> Point
P256.toPoint) (Integer -> Maybe Scalar
toP256Scalar Integer
n)
| Curve
c Curve -> Curve -> Bool
forall a. Eq a => a -> a -> Bool
== Curve
p256Curve
, Just Point
q <- Point -> Maybe Point
toP256 Point
p =
Point -> (Scalar -> Point) -> Maybe Scalar -> Point
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Point
PointO (\Scalar
s -> Point -> Point
fromP256 (Scalar -> Point -> Point
P256.pointMul Scalar
s Point
q)) (Integer -> Maybe Scalar
toP256Scalar Integer
n)
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Curve -> Integer -> Point -> Point
pointMul Curve
c (-Integer
n) (Curve -> Point -> Point
pointNegate Curve
c Point
p)
| Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Point
PointO
| Bool
otherwise =
case Curve
c of
CurveFP (CurvePrime Integer
pr CurveCommon
cc) -> Integer -> CurveCommon -> Point
primeMul Integer
pr CurveCommon
cc
CurveF2m (CurveBinary Integer
fx CurveCommon
cc) -> Integer -> CurveCommon -> Point
binaryMul Integer
fx CurveCommon
cc
where
primeMul :: Integer -> CurveCommon -> Point
primeMul Integer
pr CurveCommon
cc = case Point
p of
Point Integer
px Integer
py
| Curve -> Point -> Bool
isPointValid Curve
c Point
p ->
Point -> MulResult -> Point
answer Point
slow (MulResult -> Point) -> MulResult -> Point
forall a b. (a -> b) -> a -> b
$
CurveField
-> Integer -> Integer -> Integer -> Integer -> Bool -> MulResult
curveMul
(Integer -> Integer -> Integer -> CurveField
Prime Integer
pr (CurveCommon -> Integer
ecc_a CurveCommon
cc) (CurveCommon -> Integer
ecc_b CurveCommon
cc))
(CurveCommon -> Integer
ecc_n CurveCommon
cc)
Integer
n
Integer
px
Integer
py
(Point
p Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== CurveCommon -> Point
ecc_g CurveCommon
cc)
Point
_ -> Point
slow
where
slow :: Point
slow =
Integer -> Integer -> Int -> Integer -> Point -> Point
jacobianMul
Integer
pr
(CurveCommon -> Integer
ecc_a CurveCommon
cc)
(Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Integer -> Int
integerBits Integer
n) (Integer -> Int
integerBits (CurveCommon -> Integer
ecc_n CurveCommon
cc)))
Integer
n
Point
p
binaryMul :: Integer -> CurveCommon -> Point
binaryMul Integer
fx CurveCommon
cc = case Point
p of
Point Integer
px Integer
py
| Curve -> Point -> Bool
isPointValid Curve
c Point
p ->
Point -> MulResult -> Point
answer (Integer -> Point -> Point
forall {t}. Integral t => t -> Point -> Point
affineMul Integer
n Point
p) (MulResult -> Point) -> MulResult -> Point
forall a b. (a -> b) -> a -> b
$
CurveField
-> Integer -> Integer -> Integer -> Integer -> Bool -> MulResult
curveMul (Integer -> Integer -> CurveField
Binary Integer
fx (CurveCommon -> Integer
ecc_b CurveCommon
cc)) (CurveCommon -> Integer
ecc_n CurveCommon
cc) Integer
n Integer
px Integer
py Bool
False
Point
_ -> Integer -> Point -> Point
forall {t}. Integral t => t -> Point -> Point
affineMul Integer
n Point
p
answer :: Point -> MulResult -> Point
answer Point
fallback MulResult
r = case MulResult
r of
MulPoint Integer
x Integer
y -> Integer -> Integer -> Point
Point Integer
x Integer
y
MulResult
MulInfinity -> Point
PointO
MulResult
MulUnsupported -> Point
fallback
affineMul :: t -> Point -> Point
affineMul t
k Point
q
| t
k t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0 = Point
PointO
| t
k t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
1 = Point
q
| t -> Bool
forall a. Integral a => a -> Bool
odd t
k = Curve -> Point -> Point -> Point
pointAdd Curve
c Point
q (t -> Point -> Point
affineMul (t
k t -> t -> t
forall a. Num a => a -> a -> a
- t
1) Point
q)
| Bool
otherwise = t -> Point -> Point
affineMul (t
k t -> t -> t
forall a. Integral a => a -> a -> a
`div` t
2) (Curve -> Point -> Point
pointDouble Curve
c Point
q)
integerBits :: Integer -> Int
integerBits :: Integer -> Int
integerBits = Int -> Integer -> Int
forall {t} {t}. (Num t, Integral t) => t -> t -> t
go Int
0
where
go :: t -> t -> t
go t
acc t
0 = t
acc
go t
acc t
k = t -> t -> t
go (t
acc t -> t -> t
forall a. Num a => a -> a -> a
+ t
1) (t
k t -> t -> t
forall a. Integral a => a -> a -> a
`div` t
2)
data JPoint = JPointO | JPoint !Integer !Integer !Integer
data Field = Field !Integer !Int !Integer
mkField :: Integer -> Field
mkField :: Integer -> Field
mkField Integer
p
| Integer
p Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 Bool -> Bool -> Bool
&& Integer
c Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 Bool -> Bool -> Bool
&& Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Integer -> Int
numBits Integer
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
k Bool -> Bool -> Bool
&& Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
256 = Integer -> Int -> Integer -> Field
Field Integer
p Int
k Integer
c
| Bool
otherwise = Integer -> Int -> Integer -> Field
Field Integer
p Int
0 Integer
0
where
k :: Int
k = Integer -> Int
numBits Integer
p
c :: Integer
c = (Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
k) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
p
fieldPrime :: Field -> Integer
fieldPrime :: Field -> Integer
fieldPrime (Field Integer
p Int
_ Integer
_) = Integer
p
fieldReduce :: Field -> Integer -> Integer
fieldReduce :: Field -> Integer -> Integer
fieldReduce (Field Integer
p Int
k Integer
c) Integer
x
| Integer
c Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 Bool -> Bool -> Bool
|| Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Integer
x Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
p
| Bool
otherwise = Integer -> Integer
trim (Integer -> Integer
fold Integer
x)
where
mask :: Integer
mask = (Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
k) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
fold :: Integer -> Integer
fold Integer
v
| Integer
v Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
mask = Integer -> Integer
fold ((Integer
v Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
k) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Integer
v Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
mask))
| Bool
otherwise = Integer
v
trim :: Integer -> Integer
trim Integer
v
| Integer
v Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
p = Integer -> Integer
trim (Integer
v Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
p)
| Bool
otherwise = Integer
v
{-# INLINE fieldReduce #-}
data Affine = AffineO | Affine !Integer !Integer
jacobianMul :: Integer -> Integer -> Int -> Integer -> Point -> Point
jacobianMul :: Integer -> Integer -> Int -> Integer -> Point -> Point
jacobianMul Integer
_ Integer
_ Int
_ Integer
_ Point
PointO = Point
PointO
jacobianMul Integer
pr Integer
a Int
bits Integer
n (Point Integer
px Integer
py) = Field -> JPoint -> Point
fromJacobian Field
f (Int -> JPoint -> JPoint
go (Int
bits Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) JPoint
JPointO)
where
f :: Field
f = Integer -> Field
mkField Integer
pr
base :: Affine
base = Integer -> Integer -> Affine
Affine Integer
px Integer
py
go :: Int -> JPoint -> JPoint
go Int
i JPoint
acc
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = JPoint
acc
| Bool
otherwise =
let !d :: JPoint
d = Field -> Integer -> JPoint -> JPoint
jDouble Field
f Integer
a JPoint
acc
!s :: JPoint
s = Field -> Integer -> JPoint -> Affine -> JPoint
jAddAffine Field
f Integer
a JPoint
d Affine
base
in Int -> JPoint -> JPoint
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (if Integer -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Integer
n Int
i then JPoint
s else JPoint
d)
jDouble :: Field -> Integer -> JPoint -> JPoint
jDouble :: Field -> Integer -> JPoint -> JPoint
jDouble Field
_ Integer
_ JPoint
JPointO = JPoint
JPointO
jDouble Field
f Integer
a (JPoint Integer
x Integer
y Integer
z)
| Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = JPoint
JPointO
| Bool
otherwise = Integer -> Integer -> Integer -> JPoint
JPoint Integer
x3 Integer
y3 Integer
z3
where
red :: Integer -> Integer
red = Field -> Integer -> Integer
fieldReduce Field
f
yy :: Integer
yy = Integer -> Integer
red (Integer
y Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
y)
delta :: Integer
delta = Integer -> Integer
red (Integer
4 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
yy)
zz :: Integer
zz = Integer -> Integer
red (Integer
z Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
z)
m :: Integer
m = Integer -> Integer
red (Integer
3 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
zz Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
zz)
x3 :: Integer
x3 = Integer -> Integer
red (Integer
m Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
m Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
delta)
y3 :: Integer
y3 = Integer -> Integer
red (Integer
m Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Integer
delta Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
x3) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
8 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
yy Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
yy)
z3 :: Integer
z3 = Integer -> Integer
red (Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
y Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
z)
jAddAffine :: Field -> Integer -> JPoint -> Affine -> JPoint
jAddAffine :: Field -> Integer -> JPoint -> Affine -> JPoint
jAddAffine Field
_ Integer
_ JPoint
p Affine
AffineO = JPoint
p
jAddAffine Field
_ Integer
_ JPoint
JPointO (Affine Integer
x2 Integer
y2) = Integer -> Integer -> Integer -> JPoint
JPoint Integer
x2 Integer
y2 Integer
1
jAddAffine Field
f Integer
a p :: JPoint
p@(JPoint Integer
x1 Integer
y1 Integer
z1) (Affine Integer
x2 Integer
y2)
| Integer
h Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0 = Integer -> Integer -> Integer -> JPoint
JPoint Integer
x3 Integer
y3 Integer
z3
| Integer
r Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0 = JPoint
JPointO
| Bool
otherwise = Field -> Integer -> JPoint -> JPoint
jDouble Field
f Integer
a JPoint
p
where
red :: Integer -> Integer
red = Field -> Integer -> Integer
fieldReduce Field
f
z1s :: Integer
z1s = Integer -> Integer
red (Integer
z1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
z1)
u2 :: Integer
u2 = Integer -> Integer
red (Integer
x2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
z1s)
s2 :: Integer
s2 = Integer -> Integer
red (Integer
y2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
z1s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
z1)
h :: Integer
h = Integer -> Integer
red (Integer
u2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
x1)
r :: Integer
r = Integer -> Integer
red (Integer
s2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
y1)
h2 :: Integer
h2 = Integer -> Integer
red (Integer
h Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
h)
h3 :: Integer
h3 = Integer -> Integer
red (Integer
h2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
h)
x3 :: Integer
x3 = Integer -> Integer
red (Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
h3 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
x1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
h2)
y3 :: Integer
y3 = Integer -> Integer
red (Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Integer
x1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
h2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
x3) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
y1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
h3)
z3 :: Integer
z3 = Integer -> Integer
red (Integer
h Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
z1)
fromJacobian :: Field -> JPoint -> Point
fromJacobian :: Field -> JPoint -> Point
fromJacobian Field
_ JPoint
JPointO = Point
PointO
fromJacobian Field
f (JPoint Integer
x Integer
y Integer
z) =
case Integer -> Integer -> Maybe Integer
inverse Integer
z (Field -> Integer
fieldPrime Field
f) of
Maybe Integer
Nothing -> Point
PointO
Just Integer
zi ->
let red :: Integer -> Integer
red = Field -> Integer -> Integer
fieldReduce Field
f
zi2 :: Integer
zi2 = Integer -> Integer
red (Integer
zi Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
zi)
in Integer -> Integer -> Point
Point (Integer -> Integer
red (Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
zi2)) (Integer -> Integer
red (Integer
y Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
zi2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
zi))
pointAddTwoMuls :: Curve -> Integer -> Point -> Integer -> Point -> Point
pointAddTwoMuls :: Curve -> Integer -> Point -> Integer -> Point -> Point
pointAddTwoMuls Curve
c Integer
n1 Point
p1 Integer
n2 Point
p2
| Curve
c Curve -> Curve -> Bool
forall a. Eq a => a -> a -> Bool
== Curve
p256Curve, Just Point
r <- Integer -> Point -> Integer -> Point -> Maybe Point
p256AddTwoMuls Integer
n1 Point
p1 Integer
n2 Point
p2 = Point
r
| Bool
otherwise = Curve -> Point -> Point -> Point
pointAdd Curve
c (Curve -> Integer -> Point -> Point
pointMul Curve
c Integer
n1 Point
p1) (Curve -> Integer -> Point -> Point
pointMul Curve
c Integer
n2 Point
p2)
pointDecompose :: Curve -> Point -> Maybe (Integer, Integer, Bool)
pointDecompose :: Curve -> Point -> Maybe (Integer, Integer, Bool)
pointDecompose Curve
_ Point
PointO = Maybe (Integer, Integer, Bool)
forall a. Maybe a
Nothing
pointDecompose Curve
curve (Point Integer
x Integer
y) = do
let CurveCommon Integer
_ Integer
_ Point
_ Integer
n Integer
_ = Curve -> CurveCommon
common_curve Curve
curve
let (Integer
index, Integer
residue) = Integer
x Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` Integer
n
Bool
parity <- case Curve
curve of
CurveFP CurvePrime
_ -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Maybe Bool) -> Bool -> Maybe Bool
forall a b. (a -> b) -> a -> b
$ Integer -> Bool
forall a. Integral a => a -> Bool
odd Integer
y
CurveF2m CurveBinary
_ | Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
CurveF2m (CurveBinary Integer
fx CurveCommon
_) -> Integer -> Bool
forall a. Integral a => a -> Bool
odd (Integer -> Bool) -> Maybe Integer -> Maybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> Integer -> Integer -> Maybe Integer
divF2m Integer
fx Integer
y Integer
x
(Integer, Integer, Bool) -> Maybe (Integer, Integer, Bool)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer
index, Integer
residue, Bool
parity)
pointCompose :: Curve -> Integer -> Integer -> Bool -> Maybe Point
pointCompose :: Curve -> Integer -> Integer -> Bool -> Maybe Point
pointCompose Curve
curve Integer
index Integer
residue Bool
parity = do
let CurveCommon Integer
a Integer
b Point
_ Integer
n Integer
_ = Curve -> CurveCommon
common_curve Curve
curve
let x :: Integer
x = Integer
residue Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
index Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
n
Integer
y <- case Curve
curve of
CurveFP (CurvePrime Integer
p CurveCommon
_) -> do
Integer
z <- Integer -> Integer -> Maybe Integer
squareRoot Integer
p (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer
x Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
3 :: Int) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b
Integer -> Maybe Integer
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ if Integer -> Bool
forall a. Integral a => a -> Bool
odd Integer
z Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
parity then Integer
z else Integer
p Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
z
CurveF2m (CurveBinary Integer
fx CurveCommon
_) | Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 -> Integer -> Maybe Integer
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
sqrtF2m Integer
fx Integer
b
CurveF2m (CurveBinary Integer
fx CurveCommon
_) -> do
Integer
c <- Integer -> Integer -> Integer -> Maybe Integer
divF2m Integer
fx Integer
b (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
squareF2m Integer
fx Integer
x
Integer
z <- Integer -> Integer -> Maybe Integer
quadraticF2m Integer
fx (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
addF2m Integer
x (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
addF2m Integer
a Integer
c
Integer -> Maybe Integer
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> Integer
mulF2m Integer
fx Integer
x (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ if Integer -> Bool
forall a. Integral a => a -> Bool
odd Integer
z Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
parity then Integer
z else Integer -> Integer -> Integer
addF2m Integer
1 Integer
z
Point -> Maybe Point
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Point -> Maybe Point) -> Point -> Maybe Point
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Point
Point Integer
x Integer
y
isPointAtInfinity :: Point -> Bool
isPointAtInfinity :: Point -> Bool
isPointAtInfinity Point
PointO = Bool
True
isPointAtInfinity Point
_ = Bool
False
isPointValid :: Curve -> Point -> Bool
isPointValid :: Curve -> Point -> Bool
isPointValid Curve
_ Point
PointO = Bool
True
isPointValid (CurveFP (CurvePrime Integer
p CurveCommon
cc)) (Point Integer
x Integer
y) =
Integer -> Bool
isValid Integer
x Bool -> Bool -> Bool
&& Integer -> Bool
isValid Integer
y Bool -> Bool -> Bool
&& (Integer
y Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
2 :: Int)) Integer -> Integer -> Bool
`eqModP` (Integer
x Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
3 :: Int) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b)
where
a :: Integer
a = CurveCommon -> Integer
ecc_a CurveCommon
cc
b :: Integer
b = CurveCommon -> Integer
ecc_b CurveCommon
cc
eqModP :: Integer -> Integer -> Bool
eqModP Integer
z1 Integer
z2 = (Integer
z1 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
p) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== (Integer
z2 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
p)
isValid :: Integer -> Bool
isValid Integer
e = Integer
e Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 Bool -> Bool -> Bool
&& Integer
e Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
p
isPointValid (CurveF2m (CurveBinary Integer
fx CurveCommon
cc)) (Point Integer
x Integer
y) =
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and
[ Integer -> Bool
isValid Integer
x
, Integer -> Bool
isValid Integer
y
, ((((Integer
x Integer -> Integer -> Integer
`add` Integer
a) Integer -> Integer -> Integer
`mul` Integer
x Integer -> Integer -> Integer
`add` Integer
y) Integer -> Integer -> Integer
`mul` Integer
x) Integer -> Integer -> Integer
`add` Integer
b Integer -> Integer -> Integer
`add` (Integer -> Integer -> Integer
squareF2m Integer
fx Integer
y)) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
]
where
a :: Integer
a = CurveCommon -> Integer
ecc_a CurveCommon
cc
b :: Integer
b = CurveCommon -> Integer
ecc_b CurveCommon
cc
add :: Integer -> Integer -> Integer
add = Integer -> Integer -> Integer
addF2m
mul :: Integer -> Integer -> Integer
mul = Integer -> Integer -> Integer -> Integer
mulF2m Integer
fx
isValid :: Integer -> Bool
isValid Integer
e = Integer -> Integer -> Integer
modF2m Integer
fx Integer
e Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
e
isPointInSubgroup :: Curve -> Point -> Bool
isPointInSubgroup :: Curve -> Point -> Bool
isPointInSubgroup Curve
curve Point
p
| CurveCommon -> Integer
ecc_h CurveCommon
cc Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
1 = Bool
True
| Bool
otherwise = Curve -> Integer -> Point -> Point
pointMul Curve
curve (CurveCommon -> Integer
ecc_n CurveCommon
cc) Point
p Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
PointO
where
cc :: CurveCommon
cc = Curve -> CurveCommon
common_curve Curve
curve
divmod :: Integer -> Integer -> Integer -> Maybe Integer
divmod :: Integer -> Integer -> Integer -> Maybe Integer
divmod Integer
y Integer
x Integer
m = do
Integer
i <- Integer -> Integer -> Maybe Integer
inverse (Integer
x Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
m) Integer
m
Integer -> Maybe Integer
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer
y Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
i Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
m