{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
module K_PKE
( Params(..), dimension, keyGen, encrypt, decrypt
, DecryptionKey, dkEncode, dkDecode
, EncryptionKey, ekEncode, ekDecode
) where
import Control.DeepSeq (NFData(..))
import Control.Monad
import Data.ByteArray (ByteArrayAccess, Bytes, ScrubbedBytes)
import qualified Data.ByteArray as B
import Unsafe.Coerce
import Auxiliary (Rq, Tq, (..+), (..-))
import Base
import Builder (Builder)
import Iterate
import Marking (SecurityMarking(..), Leak(..))
import Vector (Vector, dot)
import qualified Auxiliary as Aux
import qualified Crypto
import qualified Builder
import Math
import qualified Matrix
import qualified Vector
data Params (k :: Nat) = Params
{ forall (k :: Nat). Params k -> Word
eta1 :: {-# UNPACK #-} !Word
, forall (k :: Nat). Params k -> Word
eta2 :: {-# UNPACK #-} !Word
, forall (k :: Nat). Params k -> Int
du :: {-# UNPACK #-} !Int
, forall (k :: Nat). Params k -> Int
dv :: {-# UNPACK #-} !Int
}
dimension :: KnownNat k => Params k -> Int
dimension :: forall (k :: Nat). KnownNat k => Params k -> Int
dimension = Nat -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Nat -> Int) -> (Params k -> Nat) -> Params k -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Params k -> Nat
forall (n :: Nat) (proxy :: Nat -> *). KnownNat n => proxy n -> Nat
natVal
class Leak t => LeakVec vec t where
leakVec :: vec (t Sec) -> vec (t Pub)
instance LeakVec (Vector k) Tq where
leakVec :: Vector k (Tq 'Sec) -> Vector k (Tq 'Pub)
leakVec = Vector k (Tq 'Sec) -> Vector k (Tq 'Pub)
forall a b. a -> b
unsafeCoerce
instance LeakVec (Vector k) Rq where
leakVec :: Vector k (Rq 'Sec) -> Vector k (Rq 'Pub)
leakVec = (Rq 'Sec -> Rq 'Pub) -> Vector k (Rq 'Sec) -> Vector k (Rq 'Pub)
forall a b. (a -> b) -> Vector k a -> Vector k b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Rq 'Sec -> Rq 'Pub
forall a b. a -> b
unsafeCoerce
newtype DecryptionKey (k :: Nat) = DecryptionKey { forall (k :: Nat). DecryptionKey k -> Vector k (Tq 'Sec)
dkS :: Vector k (Tq Sec) }
data EncryptionKey (k :: Nat) = EncryptionKey { forall (k :: Nat). EncryptionKey k -> Vector k (Tq 'Pub)
ekT :: Vector k (Tq Pub), forall (k :: Nat). EncryptionKey k -> Bytes
ekRho :: Bytes, forall (k :: Nat). EncryptionKey k -> Vector k (Vector k (Tq 'Pub))
ekA :: Vector k (Vector k (Tq Pub)) }
instance Crypto.ConstEqW (DecryptionKey k) where
constEqW :: DecryptionKey k -> DecryptionKey k -> BoolW
constEqW DecryptionKey k
a DecryptionKey k
b = Vector k (Tq 'Sec) -> Vector k (Tq 'Sec) -> BoolW
forall a. ConstEqW a => a -> a -> BoolW
Crypto.constEqW (DecryptionKey k -> Vector k (Tq 'Sec)
forall (k :: Nat). DecryptionKey k -> Vector k (Tq 'Sec)
dkS DecryptionKey k
a) (DecryptionKey k -> Vector k (Tq 'Sec)
forall (k :: Nat). DecryptionKey k -> Vector k (Tq 'Sec)
dkS DecryptionKey k
b)
instance Crypto.ConstEqW (EncryptionKey k) where
constEqW :: EncryptionKey k -> EncryptionKey k -> BoolW
constEqW EncryptionKey k
a EncryptionKey k
b = Vector k (Tq 'Pub) -> Vector k (Tq 'Pub) -> BoolW
forall a. ConstEqW a => a -> a -> BoolW
Crypto.constEqW (EncryptionKey k -> Vector k (Tq 'Pub)
forall (k :: Nat). EncryptionKey k -> Vector k (Tq 'Pub)
ekT EncryptionKey k
a) (EncryptionKey k -> Vector k (Tq 'Pub)
forall (k :: Nat). EncryptionKey k -> Vector k (Tq 'Pub)
ekT EncryptionKey k
b) BoolW -> BoolW -> BoolW
`Crypto.andW` Bytes -> Bytes -> BoolW
forall a. ConstEqW a => a -> a -> BoolW
Crypto.constEqW (EncryptionKey k -> Bytes
forall (k :: Nat). EncryptionKey k -> Bytes
ekRho EncryptionKey k
a) (EncryptionKey k -> Bytes
forall (k :: Nat). EncryptionKey k -> Bytes
ekRho EncryptionKey k
b)
instance NFData (DecryptionKey k) where
rnf :: DecryptionKey k -> ()
rnf = Vector k (Tq 'Sec) -> ()
forall a (n :: Nat). NFData a => Vector n a -> ()
Vector.toNormalForm (Vector k (Tq 'Sec) -> ())
-> (DecryptionKey k -> Vector k (Tq 'Sec)) -> DecryptionKey k -> ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DecryptionKey k -> Vector k (Tq 'Sec)
forall (k :: Nat). DecryptionKey k -> Vector k (Tq 'Sec)
dkS
instance NFData (EncryptionKey k) where
rnf :: EncryptionKey k -> ()
rnf EncryptionKey k
ek = Vector k (Tq 'Pub) -> ()
forall a (n :: Nat). NFData a => Vector n a -> ()
Vector.toNormalForm (EncryptionKey k -> Vector k (Tq 'Pub)
forall (k :: Nat). EncryptionKey k -> Vector k (Tq 'Pub)
ekT EncryptionKey k
ek) () -> () -> ()
forall a b. a -> b -> b
`seq` Bytes -> ()
forall a. NFData a => a -> ()
rnf (EncryptionKey k -> Bytes
forall (k :: Nat). EncryptionKey k -> Bytes
ekRho EncryptionKey k
ek)
ekEncode :: EncryptionKey k -> Builder Pub
ekEncode :: forall (k :: Nat). EncryptionKey k -> Builder 'Pub
ekEncode EncryptionKey k
ek = (Tq 'Pub -> Builder 'Pub) -> Vector k (Tq 'Pub) -> Builder 'Pub
forall b a (n :: Nat). Monoid b => (a -> b) -> Vector n a -> b
Vector.concatMap Tq 'Pub -> Builder 'Pub
forall (marking :: SecurityMarking). Tq marking -> Builder marking
Aux.byteEncode12 (EncryptionKey k -> Vector k (Tq 'Pub)
forall (k :: Nat). EncryptionKey k -> Vector k (Tq 'Pub)
ekT EncryptionKey k
ek) Builder 'Pub -> Builder 'Pub -> Builder 'Pub
forall a. Semigroup a => a -> a -> a
<> SecureBytes 'Pub -> Builder 'Pub
forall (marking :: SecurityMarking).
Classified marking =>
SecureBytes marking -> Builder marking
Builder.bytes (EncryptionKey k -> Bytes
forall (k :: Nat). EncryptionKey k -> Bytes
ekRho EncryptionKey k
ek)
ekDecode :: (KnownNat k, ByteArrayAccess ba) => Params k -> ba -> Maybe (EncryptionKey k)
ekDecode :: forall (k :: Nat) ba.
(KnownNat k, ByteArrayAccess ba) =>
Params k -> ba -> Maybe (EncryptionKey k)
ekDecode Params k
params ba
input = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (ba -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
384 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
32)
let !tt :: Vector k (Tq 'Pub)
tt = (Offset (Tq 'Pub) -> Tq 'Pub) -> Vector k (Tq 'Pub)
forall (n :: Nat) a. KnownNat n => (Offset a -> a) -> Vector n a
Vector.create ((Offset (Tq 'Pub) -> Tq 'Pub) -> Vector k (Tq 'Pub))
-> (Offset (Tq 'Pub) -> Tq 'Pub) -> Vector k (Tq 'Pub)
forall a b. (a -> b) -> a -> b
$ \Offset (Tq 'Pub)
i -> View ba -> Tq 'Pub
forall (marking :: SecurityMarking) ba.
(Classified marking, ByteArrayAccess ba) =>
ba -> Tq marking
Aux.byteDecode12 (Offset (Tq 'Pub) -> View ba
forall {ty}. Offset ty -> View ba
view384 Offset (Tq 'Pub)
i)
!rho :: Bytes
rho = View ba -> Bytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (View ba -> Bytes) -> View ba -> Bytes
forall a b. (a -> b) -> a -> b
$ ba -> Int -> Int -> View ba
forall bytes.
ByteArrayAccess bytes =>
bytes -> Int -> Int -> View bytes
B.view ba
input (Int
384 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k) Int
32
elem384 :: Offset (Tq 'Pub) -> SecureBytes 'Pub
elem384 Offset (Tq 'Pub)
off = Builder 'Pub -> SecureBytes 'Pub
forall (marking :: SecurityMarking).
Classified marking =>
Builder marking -> SecureBytes marking
Builder.run (Tq 'Pub -> Builder 'Pub
forall (marking :: SecurityMarking). Tq marking -> Builder marking
Aux.byteEncode12 (Vector k (Tq 'Pub) -> Offset (Tq 'Pub) -> Tq 'Pub
forall (n :: Nat) a. Vector n a -> Offset a -> a
Vector.index Vector k (Tq 'Pub)
tt Offset (Tq 'Pub)
off))
[Int] -> (Int -> Maybe ()) -> Maybe ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Int -> [Int]
offsets Int
k) ((Int -> Maybe ()) -> Maybe ()) -> (Int -> Maybe ()) -> Maybe ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Offset (Tq 'Pub) -> SecureBytes 'Pub
elem384 (Int -> Offset (Tq 'Pub)
forall ty. Int -> Offset ty
Offset Int
i) Bytes -> View ba -> Bool
forall a b.
(ByteArrayAccess a, ByteArrayAccess b) =>
a -> b -> Bool
`Crypto.eq` Offset (ZonkAny 0) -> View ba
forall {ty}. Offset ty -> View ba
view384 (Int -> Offset (ZonkAny 0)
forall ty. Int -> Offset ty
Offset Int
i))
let aa :: Vector k (Vector k (Tq 'Pub))
aa = Bytes -> Vector k (Vector k (Tq 'Pub))
forall (k :: Nat).
KnownNat k =>
Bytes -> Vector k (Vector k (Tq 'Pub))
createMatrix Bytes
rho
EncryptionKey k -> Maybe (EncryptionKey k)
forall a. a -> Maybe a
Just EncryptionKey { ekT :: Vector k (Tq 'Pub)
ekT = Vector k (Tq 'Pub)
tt, ekRho :: Bytes
ekRho = Bytes
rho, ekA :: Vector k (Vector k (Tq 'Pub))
ekA = Vector k (Vector k (Tq 'Pub))
aa }
where
k :: Int
k = Params k -> Int
forall (k :: Nat). KnownNat k => Params k -> Int
dimension Params k
params
view384 :: Offset ty -> View ba
view384 (Offset Int
i) = ba -> Int -> Int -> View ba
forall bytes.
ByteArrayAccess bytes =>
bytes -> Int -> Int -> View bytes
B.view ba
input (Int
384 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i) Int
384
dkEncode :: DecryptionKey k -> Builder Sec
dkEncode :: forall (k :: Nat). DecryptionKey k -> Builder 'Sec
dkEncode = (Tq 'Sec -> Builder 'Sec) -> Vector k (Tq 'Sec) -> Builder 'Sec
forall b a (n :: Nat). Monoid b => (a -> b) -> Vector n a -> b
Vector.concatMap Tq 'Sec -> Builder 'Sec
forall (marking :: SecurityMarking). Tq marking -> Builder marking
Aux.byteEncode12 (Vector k (Tq 'Sec) -> Builder 'Sec)
-> (DecryptionKey k -> Vector k (Tq 'Sec))
-> DecryptionKey k
-> Builder 'Sec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DecryptionKey k -> Vector k (Tq 'Sec)
forall (k :: Nat). DecryptionKey k -> Vector k (Tq 'Sec)
dkS
dkDecode :: (KnownNat k, ByteArrayAccess ba) => ba -> DecryptionKey k
dkDecode :: forall (k :: Nat) ba.
(KnownNat k, ByteArrayAccess ba) =>
ba -> DecryptionKey k
dkDecode ba
input = do
let !dk :: Vector k (Tq 'Sec)
dk = (Offset (Tq 'Sec) -> Tq 'Sec) -> Vector k (Tq 'Sec)
forall (n :: Nat) a. KnownNat n => (Offset a -> a) -> Vector n a
Vector.create ((Offset (Tq 'Sec) -> Tq 'Sec) -> Vector k (Tq 'Sec))
-> (Offset (Tq 'Sec) -> Tq 'Sec) -> Vector k (Tq 'Sec)
forall a b. (a -> b) -> a -> b
$ \Offset (Tq 'Sec)
i -> View ba -> Tq 'Sec
forall (marking :: SecurityMarking) ba.
(Classified marking, ByteArrayAccess ba) =>
ba -> Tq marking
Aux.byteDecode12 (Offset (Tq 'Sec) -> View ba
forall {ty}. Offset ty -> View ba
view384 Offset (Tq 'Sec)
i)
in DecryptionKey { dkS :: Vector k (Tq 'Sec)
dkS = Vector k (Tq 'Sec)
dk }
where
view384 :: Offset ty -> View ba
view384 (Offset Int
i) = ba -> Int -> Int -> View ba
forall bytes.
ByteArrayAccess bytes =>
bytes -> Int -> Int -> View bytes
B.view ba
input (Int
384 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i) Int
384
createMatrix :: KnownNat k => Bytes -> Vector k (Vector k (Tq Pub))
createMatrix :: forall (k :: Nat).
KnownNat k =>
Bytes -> Vector k (Vector k (Tq 'Pub))
createMatrix !Bytes
rho = (Offset (Tq 'Pub) -> Offset (Vector k (Tq 'Pub)) -> Tq 'Pub)
-> Vector k (Vector k (Tq 'Pub))
forall (m :: Nat) (n :: Nat) ty.
(KnownNat m, KnownNat n) =>
(Offset ty -> Offset (Vector n ty) -> ty) -> Vector m (Vector n ty)
Matrix.create ((Offset (Tq 'Pub) -> Offset (Vector k (Tq 'Pub)) -> Tq 'Pub)
-> Vector k (Vector k (Tq 'Pub)))
-> (Offset (Tq 'Pub) -> Offset (Vector k (Tq 'Pub)) -> Tq 'Pub)
-> Vector k (Vector k (Tq 'Pub))
forall a b. (a -> b) -> a -> b
$ \(Offset Int
i) (Offset Int
j) ->
SecureBytes 'Pub -> Word8 -> Word8 -> Tq 'Pub
Aux.sampleNTT Bytes
SecureBytes 'Pub
rho (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
j) (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)
createVector :: (KnownNat k, ByteArrayAccess s) => Word -> s -> Int -> Vector k (Rq Sec)
createVector :: forall (k :: Nat) s.
(KnownNat k, ByteArrayAccess s) =>
Word -> s -> Int -> Vector k (Rq 'Sec)
createVector !Word
eta !s
s !Int
j = (Offset (Rq 'Sec) -> Rq 'Sec) -> Vector k (Rq 'Sec)
forall (n :: Nat) a. KnownNat n => (Offset a -> a) -> Vector n a
Vector.create ((Offset (Rq 'Sec) -> Rq 'Sec) -> Vector k (Rq 'Sec))
-> (Offset (Rq 'Sec) -> Rq 'Sec) -> Vector k (Rq 'Sec)
forall a b. (a -> b) -> a -> b
$ \(Offset Int
i) -> Word -> s -> Int -> Rq 'Sec
forall s. ByteArrayAccess s => Word -> s -> Int -> Rq 'Sec
sample Word
eta s
s (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
j)
{-# INLINE createVector #-}
sample :: ByteArrayAccess s => Word -> s -> Int -> Rq Sec
sample :: forall s. ByteArrayAccess s => Word -> s -> Int -> Rq 'Sec
sample Word
eta s
s = Word -> SecureBytes 'Sec -> Rq 'Sec
Aux.samplePolyCBD Word
eta (ScrubbedBytes -> Rq 'Sec)
-> (Int -> ScrubbedBytes) -> Int -> Rq 'Sec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> s -> Word8 -> ScrubbedBytes
forall s. ByteArrayAccess s => Word -> s -> Word8 -> ScrubbedBytes
Crypto.prf Word
eta s
s (Word8 -> ScrubbedBytes) -> (Int -> Word8) -> Int -> ScrubbedBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE sample #-}
keyGen :: (KnownNat k, ByteArrayAccess d) => Params k -> d -> (EncryptionKey k, DecryptionKey k)
keyGen :: forall (k :: Nat) d.
(KnownNat k, ByteArrayAccess d) =>
Params k -> d -> (EncryptionKey k, DecryptionKey k)
keyGen params :: Params k
params@Params{Int
Word
eta1 :: forall (k :: Nat). Params k -> Word
eta2 :: forall (k :: Nat). Params k -> Word
du :: forall (k :: Nat). Params k -> Int
dv :: forall (k :: Nat). Params k -> Int
eta1 :: Word
eta2 :: Word
du :: Int
dv :: Int
..} d
d = (EncryptionKey k
ek, DecryptionKey k
dk)
where
k :: Int
k = Params k -> Int
forall (k :: Nat). KnownNat k => Params k -> Int
dimension Params k
params
(Bytes
rho, View ScrubbedBytes
sigma) = ScrubbedBytes -> (Bytes, View ScrubbedBytes)
forall ba.
ByteArray ba =>
ScrubbedBytes -> (ba, View ScrubbedBytes)
Crypto.g (d -> Word8 -> ScrubbedBytes
forall a. ByteArrayAccess a => a -> Word8 -> ScrubbedBytes
Crypto.snoc d
d (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k))
aa :: Vector k (Vector k (Tq 'Pub))
aa = Bytes -> Vector k (Vector k (Tq 'Pub))
forall (k :: Nat).
KnownNat k =>
Bytes -> Vector k (Vector k (Tq 'Pub))
createMatrix Bytes
rho
s :: Vector k (Rq 'Sec)
s = Word -> View ScrubbedBytes -> Int -> Vector k (Rq 'Sec)
forall (k :: Nat) s.
(KnownNat k, ByteArrayAccess s) =>
Word -> s -> Int -> Vector k (Rq 'Sec)
createVector Word
eta1 View ScrubbedBytes
sigma Int
0
e :: Vector k (Rq 'Sec)
e = Word -> View ScrubbedBytes -> Int -> Vector k (Rq 'Sec)
forall (k :: Nat) s.
(KnownNat k, ByteArrayAccess s) =>
Word -> s -> Int -> Vector k (Rq 'Sec)
createVector Word
eta1 View ScrubbedBytes
sigma Int
k
!ss :: Vector k (Tq 'Sec)
ss = Rq 'Sec -> Tq 'Sec
forall (marking :: SecurityMarking).
Classified marking =>
Rq marking -> Tq marking
Aux.ntt (Rq 'Sec -> Tq 'Sec) -> Vector k (Rq 'Sec) -> Vector k (Tq 'Sec)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector k (Rq 'Sec)
s
ee :: Vector k (Tq 'Sec)
ee = Rq 'Sec -> Tq 'Sec
forall (marking :: SecurityMarking).
Classified marking =>
Rq marking -> Tq marking
Aux.ntt (Rq 'Sec -> Tq 'Sec) -> Vector k (Rq 'Sec) -> Vector k (Tq 'Sec)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector k (Rq 'Sec)
e
!tt :: Vector k (Tq 'Pub)
tt = Vector k (Tq 'Sec) -> Vector k (Tq 'Pub)
forall (vec :: * -> *) (t :: SecurityMarking -> *).
LeakVec vec t =>
vec (t 'Sec) -> vec (t 'Pub)
leakVec (Vector k (Tq 'Sec) -> Vector k (Tq 'Pub))
-> Vector k (Tq 'Sec) -> Vector k (Tq 'Pub)
forall a b. (a -> b) -> a -> b
$ Vector k (Vector k (Tq 'Pub))
-> Vector k (Tq 'Sec) -> Vector k (Tq 'Sec) -> Vector k (Tq 'Sec)
forall (n :: Nat) b a (m :: Nat).
(KnownNat n, BiMulAdd b a) =>
Vector m (Vector n b) -> Vector m a -> Vector n a -> Vector n a
Matrix.mulw Vector k (Vector k (Tq 'Pub))
aa Vector k (Tq 'Sec)
ss Vector k (Tq 'Sec)
ee
ek :: EncryptionKey k
ek = EncryptionKey { ekT :: Vector k (Tq 'Pub)
ekT = Vector k (Tq 'Pub)
tt, ekRho :: Bytes
ekRho = Bytes
rho, ekA :: Vector k (Vector k (Tq 'Pub))
ekA = Vector k (Vector k (Tq 'Pub))
aa }
dk :: DecryptionKey k
dk = DecryptionKey { dkS :: Vector k (Tq 'Sec)
dkS = Vector k (Tq 'Sec)
ss }
encrypt :: (KnownNat k, ByteArrayAccess m, ByteArrayAccess r) => Params k -> EncryptionKey k -> m -> r -> Bytes
encrypt :: forall (k :: Nat) m r.
(KnownNat k, ByteArrayAccess m, ByteArrayAccess r) =>
Params k -> EncryptionKey k -> m -> r -> Bytes
encrypt params :: Params k
params@Params{Int
Word
eta1 :: forall (k :: Nat). Params k -> Word
eta2 :: forall (k :: Nat). Params k -> Word
du :: forall (k :: Nat). Params k -> Int
dv :: forall (k :: Nat). Params k -> Int
eta1 :: Word
eta2 :: Word
du :: Int
dv :: Int
..} EncryptionKey k
ek m
m r
r = Builder 'Pub -> SecureBytes 'Pub
forall (marking :: SecurityMarking).
Classified marking =>
Builder marking -> SecureBytes marking
Builder.run (Builder 'Pub
c1 Builder 'Pub -> Builder 'Pub -> Builder 'Pub
forall a. Semigroup a => a -> a -> a
<> Builder 'Pub
c2)
where
k :: Int
k = Params k -> Int
forall (k :: Nat). KnownNat k => Params k -> Int
dimension Params k
params
tt :: Vector k (Tq 'Pub)
tt = EncryptionKey k -> Vector k (Tq 'Pub)
forall (k :: Nat). EncryptionKey k -> Vector k (Tq 'Pub)
ekT EncryptionKey k
ek
aa :: Vector k (Vector k (Tq 'Pub))
aa = EncryptionKey k -> Vector k (Vector k (Tq 'Pub))
forall (k :: Nat). EncryptionKey k -> Vector k (Vector k (Tq 'Pub))
ekA EncryptionKey k
ek
y :: Vector k (Rq 'Sec)
y = Word -> r -> Int -> Vector k (Rq 'Sec)
forall (k :: Nat) s.
(KnownNat k, ByteArrayAccess s) =>
Word -> s -> Int -> Vector k (Rq 'Sec)
createVector Word
eta1 r
r Int
0
e1 :: Vector k (Rq 'Sec)
e1 = Word -> r -> Int -> Vector k (Rq 'Sec)
forall (k :: Nat) s.
(KnownNat k, ByteArrayAccess s) =>
Word -> s -> Int -> Vector k (Rq 'Sec)
createVector Word
eta2 r
r Int
k
e2 :: Rq 'Sec
e2 = Word -> r -> Int -> Rq 'Sec
forall s. ByteArrayAccess s => Word -> s -> Int -> Rq 'Sec
sample Word
eta2 r
r (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k)
yy :: Vector k (Tq 'Sec)
yy = Rq 'Sec -> Tq 'Sec
forall (marking :: SecurityMarking).
Classified marking =>
Rq marking -> Tq marking
Aux.ntt (Rq 'Sec -> Tq 'Sec) -> Vector k (Rq 'Sec) -> Vector k (Tq 'Sec)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector k (Rq 'Sec)
y
u :: Vector k (Rq 'Pub)
u = Vector k (Rq 'Sec) -> Vector k (Rq 'Pub)
forall (vec :: * -> *) (t :: SecurityMarking -> *).
LeakVec vec t =>
vec (t 'Sec) -> vec (t 'Pub)
leakVec (Vector k (Rq 'Sec) -> Vector k (Rq 'Pub))
-> Vector k (Rq 'Sec) -> Vector k (Rq 'Pub)
forall a b. (a -> b) -> a -> b
$ (Tq 'Sec -> Rq 'Sec
Aux.nttInv (Tq 'Sec -> Rq 'Sec) -> Vector k (Tq 'Sec) -> Vector k (Rq 'Sec)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector k (Vector k (Tq 'Pub))
-> Vector k (Tq 'Sec) -> Vector k (Tq 'Sec)
forall b a (m :: Nat) (n :: Nat).
BiMulAdd b a =>
Vector m (Vector n b) -> Vector n a -> Vector m a
Matrix.muly Vector k (Vector k (Tq 'Pub))
aa Vector k (Tq 'Sec)
yy) Vector k (Rq 'Sec) -> Vector k (Rq 'Sec) -> Vector k (Rq 'Sec)
forall a. Add a => a -> a -> a
.+ Vector k (Rq 'Sec)
e1
mu :: Rq 'Sec
mu = Int -> BlockN 'Sec N Word16 -> Rq 'Sec
forall (marking :: SecurityMarking).
Classified marking =>
Int -> BlockN marking N Word16 -> Rq marking
Aux.rdecompress Int
1 (m -> BlockN 'Sec N Word16
forall ba. ByteArrayAccess ba => ba -> BlockN 'Sec N Word16
Aux.byteDecode1 m
m)
v :: Rq 'Pub
v = Tq 'Sec -> Rq 'Sec
Aux.nttInv (Vector k (Tq 'Pub)
tt Vector k (Tq 'Pub) -> Vector k (Tq 'Sec) -> Tq 'Sec
forall b a (n :: Nat).
BiMulAdd b a =>
Vector n b -> Vector n a -> a
`dot` Vector k (Tq 'Sec)
yy) Rq 'Sec -> Rq 'Sec -> Rq 'Sec
forall a. Add a => a -> a -> a
.+ Rq 'Sec
e2 Rq 'Sec -> Rq 'Sec -> Rq 'Pub
..+ Rq 'Sec
mu
c1 :: Builder 'Pub
c1 = (Rq 'Pub -> Builder 'Pub) -> Vector k (Rq 'Pub) -> Builder 'Pub
forall b a (n :: Nat). Monoid b => (a -> b) -> Vector n a -> b
Vector.concatMap (Int -> BlockN 'Pub N Word16 -> Builder 'Pub
forall (marking :: SecurityMarking).
Int -> BlockN marking N Word16 -> Builder marking
Aux.byteEncode Int
du (BlockN 'Pub N Word16 -> Builder 'Pub)
-> (Rq 'Pub -> BlockN 'Pub N Word16) -> Rq 'Pub -> Builder 'Pub
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Rq 'Pub -> BlockN 'Pub N Word16
forall (marking :: SecurityMarking).
Classified marking =>
Int -> Rq marking -> BlockN marking N Word16
Aux.rcompress Int
du) Vector k (Rq 'Pub)
u
c2 :: Builder 'Pub
c2 = Int -> BlockN 'Pub N Word16 -> Builder 'Pub
forall (marking :: SecurityMarking).
Int -> BlockN marking N Word16 -> Builder marking
Aux.byteEncode Int
dv (Int -> Rq 'Pub -> BlockN 'Pub N Word16
forall (marking :: SecurityMarking).
Classified marking =>
Int -> Rq marking -> BlockN marking N Word16
Aux.rcompress Int
dv Rq 'Pub
v)
decrypt :: KnownNat k => Params k -> DecryptionKey k -> Bytes -> ScrubbedBytes
decrypt :: forall (k :: Nat).
KnownNat k =>
Params k -> DecryptionKey k -> Bytes -> ScrubbedBytes
decrypt params :: Params k
params@Params{Int
Word
eta1 :: forall (k :: Nat). Params k -> Word
eta2 :: forall (k :: Nat). Params k -> Word
du :: forall (k :: Nat). Params k -> Int
dv :: forall (k :: Nat). Params k -> Int
eta1 :: Word
eta2 :: Word
du :: Int
dv :: Int
..} DecryptionKey k
dk Bytes
c = Builder 'Sec -> SecureBytes 'Sec
forall (marking :: SecurityMarking).
Classified marking =>
Builder marking -> SecureBytes marking
Builder.run Builder 'Sec
m
where
k :: Int
k = Params k -> Int
forall (k :: Nat). KnownNat k => Params k -> Int
dimension Params k
params
c2 :: View Bytes
c2 = Bytes -> Int -> Int -> View Bytes
forall bytes.
ByteArrayAccess bytes =>
bytes -> Int -> Int -> View bytes
B.view Bytes
c (Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
du Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k) (Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
dv)
u' :: Vector k (Rq 'Pub)
u' = (Offset (Rq 'Pub) -> Rq 'Pub) -> Vector k (Rq 'Pub)
forall (n :: Nat) a. KnownNat n => (Offset a -> a) -> Vector n a
Vector.create ((Offset (Rq 'Pub) -> Rq 'Pub) -> Vector k (Rq 'Pub))
-> (Offset (Rq 'Pub) -> Rq 'Pub) -> Vector k (Rq 'Pub)
forall a b. (a -> b) -> a -> b
$ \(Offset Int
i) -> Int -> BlockN 'Pub N Word16 -> Rq 'Pub
forall (marking :: SecurityMarking).
Classified marking =>
Int -> BlockN marking N Word16 -> Rq marking
Aux.rdecompress Int
du (BlockN 'Pub N Word16 -> Rq 'Pub)
-> (View Bytes -> BlockN 'Pub N Word16) -> View Bytes -> Rq 'Pub
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> View Bytes -> BlockN 'Pub N Word16
forall (marking :: SecurityMarking) ba.
(Classified marking, ByteArrayAccess ba) =>
Int -> ba -> BlockN marking N Word16
Aux.byteDecode Int
du (View Bytes -> Rq 'Pub) -> View Bytes -> Rq 'Pub
forall a b. (a -> b) -> a -> b
$ Bytes -> Int -> Int -> View Bytes
forall bytes.
ByteArrayAccess bytes =>
bytes -> Int -> Int -> View bytes
B.view Bytes
c (Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
du Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i) (Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
du) :: Rq Pub
v' :: Rq 'Pub
v' = Int -> BlockN 'Pub N Word16 -> Rq 'Pub
forall (marking :: SecurityMarking).
Classified marking =>
Int -> BlockN marking N Word16 -> Rq marking
Aux.rdecompress Int
dv (Int -> View Bytes -> BlockN 'Pub N Word16
forall (marking :: SecurityMarking) ba.
(Classified marking, ByteArrayAccess ba) =>
Int -> ba -> BlockN marking N Word16
Aux.byteDecode Int
dv View Bytes
c2)
w :: Rq 'Sec
w = Rq 'Pub
v' Rq 'Pub -> Rq 'Sec -> Rq 'Sec
..- Tq 'Sec -> Rq 'Sec
Aux.nttInv ((Rq 'Pub -> Tq 'Pub
forall (marking :: SecurityMarking).
Classified marking =>
Rq marking -> Tq marking
Aux.ntt (Rq 'Pub -> Tq 'Pub) -> Vector k (Rq 'Pub) -> Vector k (Tq 'Pub)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector k (Rq 'Pub)
u') Vector k (Tq 'Pub) -> Vector k (Tq 'Sec) -> Tq 'Sec
forall b a (n :: Nat).
BiMulAdd b a =>
Vector n b -> Vector n a -> a
`dot` DecryptionKey k -> Vector k (Tq 'Sec)
forall (k :: Nat). DecryptionKey k -> Vector k (Tq 'Sec)
dkS DecryptionKey k
dk)
m :: Builder 'Sec
m = BlockN 'Sec N Word16 -> Builder 'Sec
Aux.byteEncode1 (Int -> Rq 'Sec -> BlockN 'Sec N Word16
forall (marking :: SecurityMarking).
Classified marking =>
Int -> Rq marking -> BlockN marking N Word16
Aux.rcompress Int
1 Rq 'Sec
w)