pairing-1.1.0: src/Data/Pairing/Hash.hs
module Data.Pairing.Hash
( module Data.Pairing
-- * Shallue-van de Woestijne encoding to BLS12 curves
, swEncBLS12
-- * Shallue-van de Woestijne encoding to BN curves
, swEncBN
) where
import Protolude
import Control.Error (hoistMaybe, runMaybeT)
import Control.Monad.Random (MonadRandom)
import qualified Data.ByteString as B (foldl')
import Data.Curve.Weierstrass
import Data.Field.Galois as F
import Data.List ((!!))
import Data.Pairing
-------------------------------------------------------------------------------
-- Shallue-van de Woestijne encoding
-------------------------------------------------------------------------------
-- | Encodes a given byte string to a point on the BLS12 curve.
--
-- The implementation uses the Shallue-van de Woestijne encoding to BLS12 curves
-- as specified in Section 3 of [Fast and simple constant-time hashing to the
-- BLS12-381 elliptic curve](https://eprint.iacr.org/2019/403.pdf).
--
-- This function is not implemented yet.
swEncBLS12 :: forall e m q r u v w . (MonadRandom m, ECPairing e q r u v w)
=> ByteString -> m (Maybe (G1 e))
swEncBLS12 = panic "swEncBLS12: not implemented."
{-# INLINABLE swEncBLS12 #-}
-- | Encodes a given byte string to a point on the BN curve.
--
-- The implementation uses the Shallue-van de Woestijne encoding to BN curves
-- as specified in Section 6 of [Indifferentiable Hashing to Barreto-Naehrig Curves]
-- (https://www.di.ens.fr/~fouque/pub/latincrypt12.pdf).
--
-- This function evaluates an empty bytestring or one that contains \NUL
-- to zero and is sent to an arbitrary point on the curve.
swEncBN :: forall e m q r u v w . (MonadRandom m, ECPairing e q r u v w)
=> ByteString -> m (Maybe (G1 e))
swEncBN bs = runMaybeT $ do
sqrt3 <- hoistMaybe $ sr $ -3
let t = fromInteger $ fromBytes bs
s1 = (sqrt3 - 1) / 2
b1 = 1 + b_ (witness :: G1 e)
guard (b1 + t * t /= 0)
if t == 0 then -- arbitrary point on the curve
if b1 == 3 then
return $ A (-1) 1 -- 1^2 = (-1)^3 + 2
else if b1 == 4 then
return $ A 1 2 -- 2^2 = 1^3 + 3
else if b1 == 6 then
return $ A (-1) 2 -- 2^2 = (-1)^3 + 5
else
A s1 <$> hoistMaybe (sr b1) -- definition 2 assuming 1 + b is a quadratic residue
else do
let w = sqrt3 * t / (b1 + t * t)
x1 = s1 - t * w
x2 = -1 - x1
x3 = 1 + 1 / (w * w)
r1 <- F.rnd
r2 <- F.rnd
r3 <- F.rnd
let a = ch $ r1 * r1 * (x1 * x1 * x1 + b_ (witness :: G1 e))
b = ch $ r2 * r2 * (x2 * x2 * x2 + b_ (witness :: G1 e))
c = ch $ r3 * r3 * t
i = mod ((a - 1) * b) 3
x = [x1, x2, x3] !! i
y = sr $ x * x * x + b_ (witness :: G1 e)
A x . (fromIntegral c *) <$> hoistMaybe y
where
ch x = if x == 0 then 0 else if qr x then 1 else -1 :: Int
{-# INLINABLE swEncBN #-}
-------------------------------------------------------------------------------
-- Auxiliary functions
-------------------------------------------------------------------------------
-- Conversion from bytestring to field.
fromBytes :: ByteString -> Integer
fromBytes = B.foldl' f 0
where
f a b = shiftL a 8 .|. fromIntegral b
{-# INLINABLE fromBytes #-}