我试图签署一个比特币交易,其中的一部分过程是签署它与sha256和私钥。
下面是我使用的Elixir/Erlang代码:
signed_data = :crypto.sign(:ecdsa, :sha256, data, [prk, :secp256k1]) |> Base.encode16它生成以下字符串:
3046022100AFF0CCC46F08C1A2D304483C0D9B97348EEEB7D415E394A512B87A73CB69AA660221009DB8FD52692FD0ADF16F0BB8EA870C9424F1BCD22EB6755388883DE62FBC01BD问题是,此签名对我针对BlockCypher使用的引用实现失败。
它们在示例中提供的签名如下:
3044022045734b7593ed805dd95d3dfb86658afdb647b6693a740ffc9b2aa3d37cc6c06e0220324e5024acc51550e287564c308e280b8978305198d49cb2df8d07e7822b2563因此,对于相同的数据/私有键输入参数,我的签名要长2个字节。K部分的I字节长,S部分的1字节。
我怀疑Erlang密码库没有遵循比特币预期的RFC6979。
下面是一个可以工作的签名者的实现链接:https://github.com/blockcypher/btcutils/tree/master/signer
问题是:是否有一种使Erlang密码工作的方法,或者我应该使用的另一个Erlang/Elixir库.
发布于 2015-08-13 05:00:50
我能找到的最接近的东西是:https://github.com/trustatom-oss/erlang-secp256k1
它不是一个本地的Erlang代码,它使用的是NIF和普通C,但它总比没有好。
把它留在这里,以防有人做本机Erlang/Elixir实现。如果你这么做了,请把我打平。
发布于 2016-04-20 16:08:13
ECDSA签名描述椭圆曲线内的一个点。在比特币的例子中,曲线是secp256k1。对于实数,这样的曲线看起来或多或少是这样的:

曲线内的点是由两个值或“坐标”明确指定的:对于单个R值,有两个可能的有效S值。
2015年10月,有人开始利用这种两重性,一次又一次地操纵已经被广播的交易,以淹没比特币网络并导致其失灵。
由于这种可延展性的潜在风险,Blockcypher和其他著名的比特币场景成员立刻决定拥抱到BIP-0062。
BIP 0062强制执行“低S值”。这意味着包含S组件大于某个值的签名的事务必须被丢弃。这种最高价值是:
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0如果要确保事务包含始终有效的S值,则需要检查得到的S值是否大于顶值。如果是这样,只需将当前的S值移至以下值:
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141这是一个函数在Elixir中执行这种转换的例子。
def enforce_low_s sig do
len = sig |> :binary.at(1)
rlen = sig |> :binary.at(3)
r = sig |> :binary.part(4, rlen)
slen = sig |> :binary.at(rlen + 5)
s = sig |> :binary.part(rlen + 6, slen)
sint = s |> :binary.decode_unsigned
if sint > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 do
s = (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - sint) |> :binary.encode_unsigned
slen = s |> :binary.bin_to_list |> Enum.count
len = rlen + slen + 4
end
<<48, len, 2>> <> <<rlen>> <> r <> <<2, slen>> <> s
end因此,完整的签名过程如下所示:
priv_key = "yourhexprivatekey"
|> Base.decode16!
msg = "Lorem Ipsum dolor sit amet..."
sig = :crypto.sign(:sha256, msg, [priv_key, :secp256k1])
|> enforce_low_s
|> Base.encode16https://stackoverflow.com/questions/31954520
复制相似问题