基于 Shamir 的秘密共享的模式的拉格朗日插值
Lagrange Interpolation for a schema based on Shamir's Secret Sharing
我正在尝试调试阈值加密方案实施的问题。我已经在 crypto 上发布了 this question 以获得有关实际方案的一些帮助,但希望对我正在使用的简化代码进行健全性检查。
本质上,加密系统使用 Shamir 的秘密共享来组合密钥的份额。多项式是列表 'a' 的每个成员乘以多项式参数的递增幂。我省略了 prime 的 mod 以简化代码,因为实际实现通过 Haskell 包装器使用 PBC。
我有多项式
poly :: [Integer] -> Integer -> Integer
poly as xi = (f 1 as)
where
f _ [] = 0
f 0 _ = 0
f s (a:as) = (a * s) + f (s * xi) as
拉格朗日插值是:
interp0 :: [(Integer, Integer)] -> Integer
interp0 xys = round (sum $ zipWith (*) ys $ fmap (f xs) xs)
where
xs = map (fromIntegral .fst) xys
ys = map (fromIntegral .snd) xys
f :: (Eq a, Fractional a) => [a] -> a -> a
f xs xj = product $ map (p xj) xs
p :: (Eq a, Fractional a) => a -> a -> a
p xj xm = if xj == xm then 1 else negate (xm / (xj - xm))
拆分合并代码为
execPoly as@(a0:_) = do
let xs = zipWith (,) [0..] (fmap (poly as) [0..100])
let t = length as + 1
let offset = 1
let shares = take t (drop offset xs)
let sm2 = interp0 shares
putText ("poly and interp over " <> show as <> " = " <> show sm2 <> ". Should be " <> show a0)
main :: IO ()
main = do
execPoly [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] --1
execPoly [10,20,30,40,50,60,70,80] -- 2
execPoly(1) 无法合并为 10,但 execPoly(2) 合并正确。魔法门槛好像是8.
我的代码正确吗?我在实施中遗漏了将阈值大小限制为 8 的内容?
正如 MathematicalOrchid 所说,这是一个精度问题。
将代码更新为:
f :: (Eq a, Integral a) => [a] -> a -> Ratio a
f xs xj = product $ map (p xj) xs
p :: (Eq a, Integral a)=> a -> a -> Ratio a
p xj xm = if xj == xm then (1 % 1) else (negate xm) % (xj - xm)
它按预期工作。
我正在尝试调试阈值加密方案实施的问题。我已经在 crypto 上发布了 this question 以获得有关实际方案的一些帮助,但希望对我正在使用的简化代码进行健全性检查。
本质上,加密系统使用 Shamir 的秘密共享来组合密钥的份额。多项式是列表 'a' 的每个成员乘以多项式参数的递增幂。我省略了 prime 的 mod 以简化代码,因为实际实现通过 Haskell 包装器使用 PBC。
我有多项式
poly :: [Integer] -> Integer -> Integer
poly as xi = (f 1 as)
where
f _ [] = 0
f 0 _ = 0
f s (a:as) = (a * s) + f (s * xi) as
拉格朗日插值是:
interp0 :: [(Integer, Integer)] -> Integer
interp0 xys = round (sum $ zipWith (*) ys $ fmap (f xs) xs)
where
xs = map (fromIntegral .fst) xys
ys = map (fromIntegral .snd) xys
f :: (Eq a, Fractional a) => [a] -> a -> a
f xs xj = product $ map (p xj) xs
p :: (Eq a, Fractional a) => a -> a -> a
p xj xm = if xj == xm then 1 else negate (xm / (xj - xm))
拆分合并代码为
execPoly as@(a0:_) = do
let xs = zipWith (,) [0..] (fmap (poly as) [0..100])
let t = length as + 1
let offset = 1
let shares = take t (drop offset xs)
let sm2 = interp0 shares
putText ("poly and interp over " <> show as <> " = " <> show sm2 <> ". Should be " <> show a0)
main :: IO ()
main = do
execPoly [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] --1
execPoly [10,20,30,40,50,60,70,80] -- 2
execPoly(1) 无法合并为 10,但 execPoly(2) 合并正确。魔法门槛好像是8.
我的代码正确吗?我在实施中遗漏了将阈值大小限制为 8 的内容?
正如 MathematicalOrchid 所说,这是一个精度问题。
将代码更新为:
f :: (Eq a, Integral a) => [a] -> a -> Ratio a
f xs xj = product $ map (p xj) xs
p :: (Eq a, Integral a)=> a -> a -> Ratio a
p xj xm = if xj == xm then (1 % 1) else (negate xm) % (xj - xm)
它按预期工作。