diff --git a/package.yaml b/package.yaml index 3e7d15d..d619050 100644 --- a/package.yaml +++ b/package.yaml @@ -30,6 +30,7 @@ dependencies: - random - memory - mtl + - arithmoi library: source-dirs: src diff --git a/src/LSAG.hs b/src/LSAG.hs index fb95cae..263fcc6 100644 --- a/src/LSAG.hs +++ b/src/LSAG.hs @@ -29,6 +29,7 @@ import qualified Data.ByteString as BS import Data.Monoid import Data.List import Protolude hiding (hash, head) +import Math.NumberTheory.Moduli.Sqrt (sqrtModP) -- | Generates a ring signature for a message given a specific set of -- public keys and a signing key belonging to one of the public keys @@ -82,8 +83,8 @@ sign pubKeys (pubKey, privKey) msg = where curve = ECDSA.public_curve pubKey - -- h = [Hash(L)] * g - h = ECC.pointBaseMul curve (hashPubKeys curve pubKeys) + -- h = H(L) + h = generateH g curve (show $ hashPubKeys curve pubKeys) -- y = [x] * h y = ECC.pointMul curve (ECDSA.private_d privKey) h n = ECC.ecc_n (ECC.common_curve curve) @@ -116,8 +117,9 @@ verify pubKeys (ch0, [s], y) msg = panic "Invalid input" verify pubKeys (ch0, s0:s1:s2ToEnd, y) msg = ch0 == ch0' where curve0 = ECDSA.public_curve $ head pubKeys - -- h = [H(L)] * g - h = ECC.pointBaseMul curve0 (hashPubKeys curve0 pubKeys) + -- h = H(L) + h = generateH g curve0 (show $ hashPubKeys curve0 pubKeys) + y0 = ECDSA.public_q $ head pubKeys -- z0' = [s0] * g + [ch0] * y0 z0' = ECC.pointAdd curve0 @@ -157,7 +159,7 @@ genChallenges pubKeys y msg ss = do genChallenges pubKeys y msg ss where g curve = ECC.ecc_g (ECC.common_curve curve) - h curve = ECC.pointBaseMul curve (hashPubKeys curve pubKeys) + h curve = generateH (g curve) curve (show $ hashPubKeys curve pubKeys) gs curve prevK prevS prevCh = ECC.pointAdd curve (ECC.pointMul curve prevS (g curve)) @@ -204,6 +206,26 @@ pointToBS (ECC.Point x y) = show x <> show y pubKeysToBS :: [ECDSA.PublicKey] -> BS.ByteString pubKeysToBS = foldMap (pointToBS . ECDSA.public_q) + +-- | Iterative algorithm to generate H. +-- The important to hide its discrete logarithm "k" such that H = kG +generateH :: ECC.Point -> ECC.Curve -> [Char] -> ECC.Point +generateH g curve currHash = + case yM of + Nothing -> generateH g curve (noise:currHash) + Just y -> if ECC.isPointValid curve (ECC.Point x y) + then ECC.Point x y + else generateH g curve (noise:currHash) + where + x = oracle curve (pointToBS g <> toS currHash) `mod` p + yM = sqrtModP (x ^ 3 + 7) p + p = ECC.ecc_p cp + where + cp = case curve of + ECC.CurveFP c -> c + ECC.CurveF2m _ -> panic "Not a FP curve" + noise = '1' + -- | Hash list of public keys hashPubKeys :: ECC.Curve -> [ECDSA.PublicKey] -> Integer hashPubKeys c = oracle c . pubKeysToBS diff --git a/stack.yaml b/stack.yaml index 1c9afdb..22f0c87 100644 --- a/stack.yaml +++ b/stack.yaml @@ -39,7 +39,8 @@ packages: - . # Dependency packages to be pulled from upstream that are not in the resolver # (e.g., acme-missiles-0.3) -# extra-deps: [] +extra-deps: +- arithmoi-0.8.0.0 # Override default flag values for local packages and extra-deps # flags: {}