{-# OPTIONS_GHC -O2 -feager-blackholing #-}
{-# LANGUAGE Safe, GADTs, DeriveDataTypeable, NoImplicitPrelude, StrictData #-}
module Crypto.ECC.Weierstrass.Internal.Curvemath where
import safe Prelude (Eq,Show,(==),(&&),Integer,Int,show,Bool,(++),(-),otherwise,(<),mod,(^),(+))
import safe qualified Data.Bits as B ((.&.))
import safe Data.Typeable(Typeable)
import safe qualified Crypto.Fi as FP
data EC a where
ECi :: Int
-> FP.FPrime
-> FP.FPrime
-> FP.FPrime
-> EC FP.FPrime
deriving(Typeable)
instance Eq (EC a) where
(ECi Int
l Integer
b Integer
p Integer
r) == :: EC a -> EC a -> Bool
== (ECi Int
l' Integer
b' Integer
p' Integer
r') = Int
lforall a. Eq a => a -> a -> Bool
==Int
l' Bool -> Bool -> Bool
&& Integer -> Integer -> Bool
FP.eq Integer
b Integer
b' Bool -> Bool -> Bool
&& Integer -> Integer -> Bool
FP.eq Integer
p Integer
p' Bool -> Bool -> Bool
&& Integer -> Integer -> Bool
FP.eq Integer
r Integer
r'
instance Show (EC a) where
show :: EC a -> String
show (ECi Int
l Integer
b Integer
p Integer
r) = String
"Curve with length" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
l forall a. [a] -> [a] -> [a]
++String
", y^2=x^3-3*x+" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
b forall a. [a] -> [a] -> [a]
++ String
" mod " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
p forall a. [a] -> [a] -> [a]
++ String
" and group order " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
r forall a. [a] -> [a] -> [a]
++ String
"."
data ECPF a where
ECPp :: FP.FPrime
-> FP.FPrime
-> FP.FPrime
-> ECPF FP.FPrime
deriving(Typeable)
instance Eq (ECPF a) where
(ECPp Integer
x Integer
y Integer
z) == :: ECPF a -> ECPF a -> Bool
== (ECPp Integer
x' Integer
y' Integer
z') = Integer -> Integer -> Bool
FP.eq Integer
x Integer
x' Bool -> Bool -> Bool
&& Integer -> Integer -> Bool
FP.eq Integer
y Integer
y' Bool -> Bool -> Bool
&& Integer -> Integer -> Bool
FP.eq Integer
z Integer
z'
instance Show (ECPF a) where
show :: ECPF a -> String
show (ECPp Integer
x Integer
y Integer
z) = String
"x: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
x forall a. [a] -> [a] -> [a]
++ String
" y: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
y forall a. [a] -> [a] -> [a]
++ String
" z: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Integer
z
isinf :: EC a -> ECPF a -> Bool
isinf :: forall a. EC a -> ECPF a -> Bool
isinf (ECi Int
l Integer
_ Integer
_ Integer
_) (ECPp Integer
x Integer
_ Integer
z) = Integer -> Integer -> Bool
FP.eq Integer
x (Int -> Integer -> Integer
FP.fromInteger Int
l Integer
0) Bool -> Bool -> Bool
&& Integer -> Integer -> Bool
FP.eq Integer
z (Int -> Integer -> Integer
FP.fromInteger Int
l Integer
0)
export :: EC a -> ECPF a -> (Integer,Integer)
export :: forall a. EC a -> ECPF a -> (Integer, Integer)
export c :: EC a
c@ECi{} pt :: ECPF a
pt@ECPp{} = let (Integer
x,Integer
y) = forall a. EC a -> ECPF a -> (Integer, Integer)
affine EC a
c ECPF a
pt
in (Integer -> Integer
FP.toInteger Integer
x, Integer -> Integer
FP.toInteger Integer
y)
affine :: EC a -> ECPF a -> (Integer,Integer)
affine :: forall a. EC a -> ECPF a -> (Integer, Integer)
affine (ECi Int
_ Integer
_ Integer
p Integer
_) (ECPp Integer
x Integer
y Integer
z) = let z' :: Integer
z' = Integer -> Integer -> Integer
FP.inv Integer
p Integer
z
in (Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x Integer
z', Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
y Integer
z')
{-# INLINABLE affine #-}
pdouble :: EC a -> ECPF a -> ECPF a
pdouble :: forall a. EC a -> ECPF a -> ECPF a
pdouble (ECi Int
_ Integer
b Integer
p Integer
_) (ECPp Integer
x Integer
y Integer
z) =
let t0_0 :: Integer
t0_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x Integer
x
t1_0 :: Integer
t1_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
y Integer
y
t2_0 :: Integer
t2_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
z Integer
z
t3_0 :: Integer
t3_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x Integer
y
t3_1 :: Integer
t3_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t3_0 Integer
t3_0
z3_0 :: Integer
z3_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x Integer
z
z3_1 :: Integer
z3_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
z3_0 Integer
z3_0
y3_0 :: Integer
y3_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
b Integer
t2_0
y3_1 :: Integer
y3_1 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
y3_0 Integer
z3_1
x3_0 :: Integer
x3_0 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
y3_1 Integer
y3_1
y3_2 :: Integer
y3_2 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
x3_0 Integer
y3_1
x3_1 :: Integer
x3_1 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
t1_0 Integer
y3_2
y3_3 :: Integer
y3_3 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t1_0 Integer
y3_2
y3_4 :: Integer
y3_4 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x3_1 Integer
y3_3
x3_2 :: Integer
x3_2 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x3_1 Integer
t3_1
t3_2 :: Integer
t3_2 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t2_0 Integer
t2_0
t2_1 :: Integer
t2_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t2_0 Integer
t3_2
z3_2 :: Integer
z3_2 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
b Integer
z3_1
z3_3 :: Integer
z3_3 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
z3_2 Integer
t2_1
z3_4 :: Integer
z3_4 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
z3_3 Integer
t0_0
t3_3 :: Integer
t3_3 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
z3_4 Integer
z3_4
z3_5 :: Integer
z3_5 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
z3_4 Integer
t3_3
t3_4 :: Integer
t3_4 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t0_0 Integer
t0_0
t0_1 :: Integer
t0_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t3_4 Integer
t0_0
t0_2 :: Integer
t0_2 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
t0_1 Integer
t2_1
t0_3 :: Integer
t0_3 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t0_2 Integer
z3_5
y3_5 :: Integer
y3_5 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
y3_4 Integer
t0_3
t0_4 :: Integer
t0_4 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
y Integer
z
t0_5 :: Integer
t0_5 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t0_4 Integer
t0_4
z3_6 :: Integer
z3_6 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t0_5 Integer
z3_5
x3_3 :: Integer
x3_3 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
x3_2 Integer
z3_6
z3_7 :: Integer
z3_7 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t0_5 Integer
t1_0
z3_8 :: Integer
z3_8 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
z3_7 Integer
z3_7
z3_9 :: Integer
z3_9 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
z3_8 Integer
z3_8
in Integer -> Integer -> Integer -> ECPF Integer
ECPp Integer
x3_3 Integer
y3_5 Integer
z3_9
{-# INLINABLE pdouble #-}
padd :: EC a -> ECPF a -> ECPF a -> ECPF a
padd :: forall a. EC a -> ECPF a -> ECPF a -> ECPF a
padd (ECi Int
_ Integer
b Integer
p Integer
_) (ECPp Integer
x1 Integer
y1 Integer
z1) (ECPp Integer
x2 Integer
y2 Integer
z2)
= let t0_0 :: Integer
t0_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x1 Integer
x2
t1_0 :: Integer
t1_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
y1 Integer
y2
t2_0 :: Integer
t2_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
z1 Integer
z2
t3_0 :: Integer
t3_0 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
x1 Integer
y1
t4_0 :: Integer
t4_0 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
x2 Integer
y2
t3_1 :: Integer
t3_1 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t3_0 Integer
t4_0
t4_1 :: Integer
t4_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t0_0 Integer
t1_0
t3_2 :: Integer
t3_2 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
t3_1 Integer
t4_1
t4_2 :: Integer
t4_2 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
y1 Integer
z1
x3_0 :: Integer
x3_0 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
y2 Integer
z2
t4_3 :: Integer
t4_3 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t4_2 Integer
x3_0
x3_1 :: Integer
x3_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t1_0 Integer
t2_0
t4_4 :: Integer
t4_4 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
t4_3 Integer
x3_1
x3_2 :: Integer
x3_2 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
x1 Integer
z1
y3_0 :: Integer
y3_0 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
x2 Integer
z2
x3_3 :: Integer
x3_3 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x3_2 Integer
y3_0
y3_1 :: Integer
y3_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t0_0 Integer
t2_0
y3_2 :: Integer
y3_2 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
x3_3 Integer
y3_1
z3_0 :: Integer
z3_0 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
b Integer
t2_0
x3_4 :: Integer
x3_4 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
y3_2 Integer
z3_0
z3_1 :: Integer
z3_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
x3_4 Integer
x3_4
x3_5 :: Integer
x3_5 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
x3_4 Integer
z3_1
z3_2 :: Integer
z3_2 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
t1_0 Integer
x3_5
x3_6 :: Integer
x3_6 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t1_0 Integer
x3_5
y3_3 :: Integer
y3_3 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
b Integer
y3_2
t1_1 :: Integer
t1_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t2_0 Integer
t2_0
t2_1 :: Integer
t2_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t1_1 Integer
t2_0
y3_4 :: Integer
y3_4 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
y3_3 Integer
t2_1
y3_5 :: Integer
y3_5 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
y3_4 Integer
t0_0
t1_2 :: Integer
t1_2 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
y3_5 Integer
y3_5
y3_6 :: Integer
y3_6 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t1_2 Integer
y3_5
t1_3 :: Integer
t1_3 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t0_0 Integer
t0_0
t0_1 :: Integer
t0_1 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
t1_3 Integer
t0_0
t0_2 :: Integer
t0_2 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
t0_1 Integer
t2_1
t1_4 :: Integer
t1_4 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t4_4 Integer
y3_6
t2_2 :: Integer
t2_2 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t0_2 Integer
y3_6
y3_7 :: Integer
y3_7 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
x3_6 Integer
z3_2
y3_8 :: Integer
y3_8 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
y3_7 Integer
t2_2
x3_7 :: Integer
x3_7 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t3_2 Integer
x3_6
x3_8 :: Integer
x3_8 = Integer -> Integer -> Integer -> Integer
FP.subr Integer
p Integer
x3_7 Integer
t1_4
z3_3 :: Integer
z3_3 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t4_4 Integer
z3_2
t1_5 :: Integer
t1_5 = Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
t3_2 Integer
t0_2
z3_4 :: Integer
z3_4 = Integer -> Integer -> Integer -> Integer
FP.addr Integer
p Integer
z3_3 Integer
t1_5
in Integer -> Integer -> Integer -> ECPF Integer
ECPp Integer
x3_8 Integer
y3_8 Integer
z3_4
{-# INLINABLE padd #-}
ison :: EC a -> ECPF a -> Bool
ison :: forall a. EC a -> ECPF a -> Bool
ison (ECi Int
l Integer
beta Integer
p Integer
_) (ECPp Integer
x Integer
y Integer
z) = Integer -> Integer -> Bool
FP.eq
(Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p (Integer -> Integer -> Integer -> Integer
FP.pow Integer
p Integer
y (Integer
2::Integer)) Integer
z)
(Integer -> Integer -> Integer -> Integer
FP.addr Integer
p (Integer -> Integer -> Integer -> Integer
FP.pow Integer
p Integer
x (Integer
3::Integer)) (Integer -> Integer -> Integer -> Integer
FP.addr Integer
p (Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p (Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p (Integer -> Integer -> Integer
FP.neg Integer
p (Int -> Integer -> Integer
FP.fromInteger Int
l Integer
3)) Integer
x) (Integer -> Integer -> Integer -> Integer
FP.pow Integer
p Integer
z (Integer
2::Integer))) (Integer -> Integer -> Integer -> Integer
FP.mulr Integer
p Integer
beta (Integer -> Integer -> Integer -> Integer
FP.pow Integer
p Integer
z (Integer
3::Integer)))))
{-# INLINABLE ison #-}
pmul :: EC a -> ECPF a -> FP.FPrime -> ECPF a
pmul :: forall a. EC a -> ECPF a -> Integer -> ECPF a
pmul curve :: EC a
curve@(ECi Int
l Integer
_ Integer
p Integer
_) (ECPp Integer
x Integer
y Integer
z) Integer
k =
let alleeins :: Integer
alleeins = Int -> Integer -> Integer
FP.fromInteger Int
l (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Int
lforall a. Num a => a -> a -> a
-Integer
1)
eins :: Integer
eins = Int -> Integer -> Integer
FP.fromInteger Int
l Integer
1
k' :: Integer
k' = Integer
k forall a. Integral a => a -> a -> a
`mod` (Integer
pforall a. Num a => a -> a -> a
+Integer
1)
ex :: ECPF a -> Int -> ECPF a
ex ECPF a
erg Int
j
| Int
j forall a. Ord a => a -> a -> Bool
< Int
0 = ECPF a
erg
| Bool
otherwise = let s :: Integer
s = Integer -> Int -> Integer
FP.condBit Integer
k' Int
j
realpattern :: Integer
realpattern = Integer -> Integer -> Integer
FP.mul Integer
alleeins Integer
s
invpattern :: Integer
invpattern = Integer -> Integer -> Integer
FP.mul Integer
alleeins (Integer -> Integer -> Integer
FP.sub Integer
eins Integer
s)
x' :: Integer
x' = Integer
x forall a. Bits a => a -> a -> a
B..&. Integer
realpattern
y' :: Integer
y' = Integer -> Integer -> Integer
FP.add (Integer
y forall a. Bits a => a -> a -> a
B..&. Integer
realpattern) (Integer
eins forall a. Bits a => a -> a -> a
B..&. Integer
invpattern)
z' :: Integer
z' = (Integer
z forall a. Bits a => a -> a -> a
B..&. Integer
realpattern)
in ECPF a -> Int -> ECPF a
ex (forall a. EC a -> ECPF a -> ECPF a -> ECPF a
padd EC a
curve (forall a. EC a -> ECPF a -> ECPF a
pdouble EC a
curve ECPF a
erg) (Integer -> Integer -> Integer -> ECPF Integer
ECPp Integer
x' Integer
y' Integer
z')) (Int
j forall a. Num a => a -> a -> a
- Int
1)
in ECPF a -> Int -> ECPF a
ex (Integer -> Integer -> Integer -> ECPF Integer
ECPp Integer
0 Integer
1 Integer
0) (Int
l forall a. Num a => a -> a -> a
- Int
1)
{-# INLINABLE pmul #-}