如何创建两个调用此外部库 API 的 ByteString?

2024-07-02

我目前正在编写与加密库的绑定,该库公开用于生成密钥对的函数:

const size_t PUBLICKEYBYTES = 32;
const size_t SECRETKEYBYTES = 32;
int random_keypair(unsigned char pk[PUBLICKEYBYTES],
                   unsigned char sk[SECRETKEYBYTES]);

该函数随机生成一个密钥,计算相应的公钥并将结果放入pk and sk.

刚归还的时候ByteString我发现最简单的方法是使用create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString from Data.ByteString.Internal。但是,该函数无法创建两个ByteStrings同时。

我的第一个方法是写一些类似的东西:

newtype PublicKey = PublicKey ByteString
newtype SecretKey = SecretKey ByteString
randomKeypair :: IO (PublicKey, SecretKey)
randomKeypair = do
    let pk = B.replicate 0 publicKeyBytes
        sk = B.replicate 0 secretKeyBytes
    B.unsafeUseAsCString pk $ \ppk ->
        B.unsafeUseAsCString sk $ \psk ->
        c_random_keypair ppk psk
    return (PublicKey pk, SecretKey sk)

然而,这似乎不适用于 GHC 7.10.2。运行测试套件时,我发现我似乎共享了ByteStrings 在函数调用之间,导致加密/解密失败并给出不正确的结果。

我已经通过定义自己的函数来解决这个问题:

createWithResult :: Int -> (Ptr Word8 -> IO a) -> IO (ByteString, a)
createWithResult i f = do
    fp <- B.mallocByteString i
    r <- withForeignPtr fp f
    return (B.fromForeignPtr fp 0 i, r)

并像这样使用它:

randomKeypair = fmap (PublicKey *** SecretKey) $
    createWithResult publicKeyBytes $ \ppk ->
    B.create secretKeyBytes $ \psk ->
    void $ c_random_keypair ppk psk

这似乎有效,所有测试都通过了。

我的问题是,当涉及到共享和引用透明度时,语义到底是什么?IO monad?

我的直觉告诉我(错误地)我可以用第一种方法解决问题,但显然我不能。我相信正在发生的事情是优化器看到let- 语句可以上升到顶级定义中,这就是我遇到这些问题的原因。


这并没有回答你的问题,但它太长了,无法发表评论。

作为一种黑客,如果您想避免进行手动分配,您可以使用两个嵌套create电话和IORef ByteString存储最里面创建的字节串create。例如。 (伪代码)

secRef <- newIORef ""
pubB <- create publicKeyBytes (\pub -> do
   secB <- create secretKeyBytes (\sec -> void $ c_random_keypair pub sec)
   writeIORef secRef secB)
secB <- readIORef secRef
return (pubB, secB)

不过,我更喜欢你的createWithResult到这种方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建两个调用此外部库 API 的 ByteString? 的相关文章

  • 了解函数类型

    我在尝试理解 Haskell 如何确定函数类型时感到有点困惑 这是一个例子 boolFcn x y x 3 y 4 当我检查上述函数的类型时 它给出了结果 Num a1 Num a Eq a1 Eq a gt a gt a1 gt Bool
  • 记录语法和求和类型

    我有关于 Haskell 中的总和类型的问题 我想创建一个由两个或多个其他类型组成的总和类型 并且每个类型可能包含多个字段 一个简单的例子是这样的 data T3 T1 a Int b Float T2 x Char deriving Sh
  • 在 Haskell 中使用 Maybe 类型

    我正在尝试利用 Haskell 中的 Maybe 类型 我有一个查找返回 Maybe 的键 值元组 如何访问 Maybe 包装的数据 例如 我想将 Maybe 包含的整数与另一个整数相加 或者 您可以进行模式匹配 case maybeVal
  • 在 Web.Scotty 中使用 StateT

    我正在尝试制作一个愚蠢的网络服务器 将数据存储为State 我在用着Web Scotty http hackage haskell org package scotty 我之前用过 ReaderT 和 scotty 来访问配置 https
  • 如何编写将布尔值返回到一个函数的函数

    我在这里发现了一个类似的问题 它问了几乎相同的问题 但又不完全一样 我的问题是如何将 a gt Bool 类型的函数列表组合成一个也是 a gt Bool 的函数 Ex compose a gt Bool gt a gt Bool comp
  • 我必须实现 Applicative 和 Functor 来实现 Monad

    我正在尝试实现一个 Monad 实例 作为一个更简单的示例 假设如下 data Maybee a Notheeng Juust a instance Monad Maybee where return x Juust x Notheeng
  • 如何在 Haskell 中编写 MST 算法(Prim 或 Kruskal)?

    我可以用 C 或 Java 编写 Prim 和 Kruskal 算法来查找最小生成树 但我想知道如何在 Haskell 中以 O mlogm 或 O mlogn 实现它们 纯函数式程序更好 多谢 正如斯文宁森所说 优先搜索队列 http h
  • ghci 中严格求和/严格折叠导致内存爆炸

    正如中提到的为什么 sum takeWhile 以下是not炸毁记忆ghci https stackoverflow com questions 14298930 why does sum takewhile 10000000 1 use
  • Java 中更高级的泛型

    假设我有以下课程 public class FixExpr Expr
  • 使用 Haskell 识别段落中的单词数

    我是 Haskell 和函数式编程的新手 我有一个 txt包含一些段落的文件 我想使用 Haskell 计算每个段落中的单词数 我已经写了输入 输出代码 paragraph words String gt int no of words I
  • Haskell 中的模式匹配正则表达式模式

    在 Scala 中 我有一个正则表达式模式匹配 如下所示 val Regex d 4 d 2 d 2 r val Regex year month day 2013 01 06 结果是 year String 2013 month Stri
  • 为什么这个 HasField 实例没有被解析?

    我在用着GHC 8 2 1 我有以下模块 LANGUAGE FlexibleInstances LANGUAGE MultiParamTypeClasses LANGUAGE UndecidableInstances LANGUAGE Ty
  • 如何定义类别实例的相等性?

    为了证明例如类别法则对于某种数据类型的某些操作 如何决定如何定义相等性 考虑使用以下类型来表示布尔表达式 data Exp ETrue EFalse EAnd Exp Exp deriving Eq 试图证明这一点是否可行Exp形成一个具有
  • 如何指定内联类型中使用的类型变量与函数定义中使用的类型变量相同?

    如果我的术语有误 请道歉 我正在尝试编写一个处理异常的包装函数 如果给定IO动作抛出 它返回Nothing 在一个IO当然是上下文 但是如果给定IO操作成功 返回Just v tryMaybe IO a gt IO Maybe a tryM
  • 将您自己的错误黑客版本列入黑名单

    我不小心上传了错误的发行版并尝试立即重新上传 但是cabal回复 This version of the package has already been uploaded As a matter of policy we do not a
  • 在 Haskell 和 C 之间交换结构化数据

    首先 我是 Haskell 初学者 我计划将 Haskell 集成到 C 中以实现实时游戏 Haskell 负责逻辑 C 负责渲染 为此 我必须在每个周期 每秒至少 30 次 相互之间传递大量复杂的结构化数据 游戏状态 所以传递的数据应该是
  • SKOS(语义网)的 Haskell 数据结构

    介绍 我正在用 Haskell 编写一个语义 Web 应用程序 使用 hsparqlhttp hackage haskell org package hsparql http hackage haskell org package hspa
  • 更新列表的第 'x' 个元素 - Haskell [重复]

    这个问题在这里已经有答案了 可能的重复 替换 Haskell 中的单个列表元素 https stackoverflow com questions 5852722 replace individual list elements in ha
  • 为什么在 Haskell 中我们需要 'seq' 或 'pseq' 和 'par' ?

    我试图理解为什么我们需要标准示例代码的所有部分 a par b pseq a b 为什么以下内容还不够 a par b par a b 上面的表达式似乎非常具有描述性 尝试评估两者a and b并行 并返回结果a b 仅仅是因为效率的原因吗
  • 我在哪里可以学习高级 Haskell? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在评论中我的答案之一 https stackoverflow com questions 4633584 algorithm to gen

随机推荐

  • 如何使用 Firebase 查询中的信息填充 Android ListView

    这是我的第一篇文章 所以如果我没有遵循我应该遵循的一些协议 我深表歉意 我正在尝试使用 Firebase 数据库中的一些信息填充 ListView 我认为我遇到的问题是对数据库的查询太慢 线程可能正在下载图片 并且我的活动加载其活动布局而不
  • MacOS Sierra 上未找到 OpenSSL

    我正在尝试安装 PHP MongoDB 驱动程序 但安装失败 因为它找不到 OpenSSL Users username mongo php driver src libmongoc src mongoc mongoc crypto ope
  • 如何获取 ruby​​ 回溯中的源值和变量值?

    Here s the last few frames of a typical Ruby on Rails traceback And here are the last few frames of a typical Nevow trac
  • 为什么这个一次性绑定表现得好像它不存在一样?

    我似乎无法一次性绑定工作 我的实际应用程序逻辑对于 plunker 来说有点太复杂了 但我什至无法得到这样的简单场景http plnkr co edit ka57xquoR2ZdY2F0li76 http plnkr co edit ka5
  • NodeJS AMQP 客户端无法连接

    最近两天我快疯了 我无法在 NodeJS 客户端上通过持久交换和持久队列建立连接 PHP 代码创建并发送消息
  • 未捕获的 NotFoundError:无法在“Node”上执行“insertBefore”:

    我有一个div另外三个里面的哪里div附加如下 状态值是通过循环 api 的结果来设置的componentWillReceiveProps 但我遇到了一个错误的问题 Uncaught NotFoundError Failed to exec
  • 将 wav 文件存储在数组中

    我需要一种快速方法来将 wav 文件的所有样本存储在数组中 我目前正在通过播放音乐并存储来自示例提供程序的值来解决这个问题 但这不是很优雅 从 NAudio 演示中 我有带有此方法的 Audioplayer 类 private ISampl
  • 如何确定 MySQL 中某些查询的优先级?

    我对一个高度竞争的 MySQL 数据库有大量的后台读取和写入 而用户读取的数量要少得多 有没有办法将某些查询 用户查询 标记为高优先级 以便它们优先于后台查询 我希望用户响应能力较高 但并不真正关心后台查询 Thanks MySQL支持in
  • MySQL:限制记录数量的百分比?

    假设我有一个值列表 如下所示 id value A 53 B 23 C 12 D 72 E 21 F 16 我需要前10名percent此列表中的 我尝试过 SELECT id value FROM list ORDER BY value
  • 禁用 WebSocket 证书验证

    我需要禁用 WebSocket 的证书验证 因为我使用的是自签名证书 我在这个问题中发现Websocket SSL 连接 https stackoverflow com questions 30902547 websocket ssl co
  • 现有的解决方案可以有效但安全地共享数据库数据吗?

    我想共享一个信息数据库 例如 geonames db 94y info a geonames db 的自定义版本 有用但安全 有没有 这样做的好方法 人们不应该被迫下载数据库来获取有用的信息 我当前的解决方案是允许任意 SELECT 查询
  • 使用迭代器与索引访问向量元素有什么区别?

    使用迭代器与索引访问向量元素有什么优点 为什么迭代器比索引更好 在索引不可用的情况下 例如 std list 对于 例子 在通用函数接受迭代器的情况下 叫做 编写应该使用的函数模板时 不止一种容器类型 他们的存在是为了创造均匀性在所有容器和
  • Cocos2D 与 iOS6 旋转错误

    我正在构建一个使用 cocos2D 的应用程序 我使用 iOS 5 开发了我的应用程序 现在当我使用 iOS 6 模拟器进行测试时 整个应用程序都会旋转 我的应用程序应该处于横向模式 但 iOS 6 将其旋转为纵向 任何建议都会有所帮助 谢
  • 如何在python中查找文件的mime类型?

    假设您想要将一堆文件保存在某个地方 例如保存在 BLOB 中 假设您想通过网页分发这些文件 并让客户端自动打开正确的应用程序 查看器 假设 浏览器通过 HTTP 响应中的 mime type 内容类型 标头确定要使用哪个应用程序 查看器 基
  • 如何从 C 函数中返回多个值?

    如果我有一个产生结果的函数int和一个结果string 如何从函数中返回它们 据我所知 我只能返回一件事 这是由函数名称前面的类型决定的 我不知道你的是什么string是的 但我假设它管理自己的内存 您有两种解决方案 1 返回一个struc
  • 用javascript去掉未使用的小数

    我有一个货币输入 只需要返回有效数字 输入始终有两位小数 因此 4 00 gt 4 4 10 gt 4 1 4 01 gt 4 01 这是我目前正在做的事情 chop off unnecessary decimals if val char
  • Cassandra 中最终一致性的含义是什么?

    当单个集群中的节点不包含相同数据的副本但数据分布在节点之间时 Cassandra 中的最终一致性意味着什么 现在 由于单个数据记录在单个位置 节点 为什么 Cassandra 不从该单一记录位置返回最近的值 在这种情况下如何产生多个副本 C
  • 密码难道不是一种隐秘的安全形式吗?

    我知道通过模糊实现安全性是不受欢迎的 并且被认为不是真正安全 但是通过模糊实现密码安全不是吗 只有没有人发现它 它才是安全的 这只是默默无闻程度的问题吗 即 经过良好加盐和散列处理的好密码是无法破解的 请注意 我不是询问保存密码的过程 假设
  • 将“列表”项附加到 StringBuilder

    我尝试将项目附加到List
  • 如何创建两个调用此外部库 API 的 ByteString?

    我目前正在编写与加密库的绑定 该库公开用于生成密钥对的函数 const size t PUBLICKEYBYTES 32 const size t SECRETKEYBYTES 32 int random keypair unsigned