Pebble Coding

プログラマーの作業メモ

secp256k1 秘密鍵と公開鍵の演算

以下の関数の機能を見てみましょう。

func secp256k1_ec_privkey_negate(_ ctx: secp256k1_context, _ seckey: inout [UInt8]) -> Bool
func secp256k1_ec_pubkey_negate(_ ctx: secp256k1_context, _ pubkey: inout secp256k1_pubkey) -> Bool
func secp256k1_ec_privkey_tweak_add(_ ctx: secp256k1_context, _ seckey: inout [UInt8], _ tweak: [UInt8]) -> Bool
func secp256k1_ec_pubkey_tweak_add(_ ctx: secp256k1_context, _ pubkey: inout secp256k1_pubkey, _ tweak: [UInt8]) -> Bool
func secp256k1_ec_privkey_tweak_mul(_ ctx: secp256k1_context, _ seckey: inout [UInt8], _ tweak: [UInt8]) -> Bool
func secp256k1_ec_pubkey_tweak_mul(_ ctx: secp256k1_context, _ pubkey: inout secp256k1_pubkey, _ tweak: [UInt8]) -> Bool

最初の一つは秘密鍵に-1を乗算し、mod L を取る操作を行います。

var seckey: [UInt8] = [0,0,0,0,0,0,0,0,
                       0,0,0,0,0,0,0,0,
                       0,0,0,0,0,0,0,0,
                       0,0,0,0,0,0,0,4]
let result = secp256k1_ec_privkey_negate(ctx, &seckey)
XCTAssert(result)
        
print("\(seckey.hexDescription())")
fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413d

pythonで確認します。

>>> L = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
>>> print("%x" % ((-4) % L))
fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413d

次の関数は公開鍵(点P)にマイナスを乗算する(y座標を-1倍する)ものです。

print("\(pubkey)")
let result3 = secp256k1_ec_pubkey_negate(ctx, &pubkey)
XCTAssert(result3)
print("\(pubkey)")
e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13,ae1266c15f2baa48a9bd1df6715aebb7269851cc404201bf30168422b88c630d
e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13,51ed993ea0d455b75642e2098ea51448d967ae33bfbdfe40cfe97bdc47739922

pythonで確かめます。

>>> p = 2**256 - 2**32 - 977
>>> x = 0xe493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13
>>> y = 0xae1266c15f2baa48a9bd1df6715aebb7269851cc404201bf30168422b88c630d
>>> print("%x" % (-y % p))
51ed993ea0d455b75642e2098ea51448d967ae33bfbdfe40cfe97bdc47739922

これで、mul や add が何をする関数なのかも分かるでしょう。
ビットコインでの使い方としては、ホットウォレットやコールドウォレット上での、秘密鍵や公開鍵の算出に使います。