この文書はコンピューター工学知識が一部必要です。
Address and Signature
不特定多数で構成されている Blockchain Network の中、どうやって’私’とゆう存在を証明するのができましょうか。 ’私’や’所有者’とゆう存在を証明できないならば、’所有資産’も存在なしになります。
その故, Blockchainで取引が成立するには、’私’とゆう存在を証明する方法が必要です。 ここで、AddressとSignatureシステムが登場します。
Public-key cryptography
AddressとSignatureは伝統的コンピューター工学のPublic-key cryptographyを使って具現されています。
Public-key cryptographyは数学的な難題を利用して暗号化やHashingをする技術です。
- 答え(Private Key)を知っている時には早い処理ができますが、
- 答えを知らない時には、問題を解決する為大きなコストが必要で、現代のコンピューターの能力には解決が難しい問題を活用します。
例) Rivest–Shamir–Adleman (RSA)
- 素因数pとqを選びます。
- φ = (p−1)(q−1)
- e = φ 互いに素
- edをφで分けて、残りが1になるdを探します。
- Public keyは(e, p, q), Private Keyは(d, p, q)になります。
名前そのまま,Public Keyは誰でアクセスできるようにに公開して,Private Keyは所有者が保管します。 大体、二つの方法で使用されます。
- Public Keyで暗号化されたデータはPrivate Keyの所有者だけ読むのができます。
- 所有者のデータをPrivate Keyで署名(Sign)して、Public Keyでこの署名が正しいか確認できます。
普通、Blockchainでは Elliptic Curve Digital Signature Algorithm (ECDSA) を Address と Signature に使用します。
Hash
Hash Algorithm (Hash Function)は任意のデータを持って、特定Functionを利用して、固定長さのデータに置換します。 有名なHash関数はMessage-Digest Algorithm(MD)やSecure Hash Algorithm(SHA)が有ります。
Hashをする理由は色々ですが、代表的に下のような理由が有ります。
- 特定データが正しいか検証する時(Check Sum)。データが変造されたら、Hashも変化されます。
- 固定長さで(もしは短い長さ)置換する時
Address
AddressはPublic Keyの変形です。Private Keyを使ってSignができならば、Addressの所有者を証明するのができます。
- Bitcoinは色んなAddress Formatを使用します。FormatはBitcoinが使ったScript(P2PK, P2PKH, P2SH, P2WPKH, .. )を従います。
- Scriptに付いては、他の文書で説明します。
- Ethereumは単一Address Formatを使用しています。
public byte[] getPubKeyHash() {
if (pubKeyHash == null)
pubKeyHash = Utils.sha256hash160(this.pub.getEncoded());
return pubKeyHash;
}
(ECKey.java in BitcoinJ)
public String toBase58() {
return Base58.encodeChecked(getVersion(), bytes);
}
(LegacyAddress.java in BitcoinJ)
public static String encodeChecked(int version, byte[] payload) {
if (version < 0 || version > 255)
throw new IllegalArgumentException("Version not in range.");
// A stringified buffer is:
// 1 byte version + data bytes + 4 bytes check code (a truncated hash)
byte[] addressBytes = new byte[1 + payload.length + 4];
addressBytes[0] = (byte) version;
System.arraycopy(payload, 0, addressBytes, 1, payload.length);
byte[] checksum = Sha256Hash.hashTwice(addressBytes, 0, payload.length + 1);
System.arraycopy(checksum, 0, addressBytes, payload.length + 1, 4);
return Base58.encode(addressBytes);
}
(Base58.java in BitcoinJ)
P2PKH Scriptで, Public KeyからAddressを作る方法は下の過程になります。
- Public Keyでsha256 Hashを計算します。
- (1)で、ripemd160 Hashを計算します。
- (2)で、Version と CheckSum Hash付けのデータを計算します。
- 初めの1ByteはVersionで、Network や Address Format に従って決定されます。
- 次の20Byte(160 Bit)は,payload(ripemd160 hash)が位置します。
- 最後は4ByteのSHA256 Hashで, 上で作った21 ByteのHashを2回計算します。
- 25Byte長さのAddress。
- (3)で、Base58 Encodingをします。これがユーザーが使うAddressになります。
特定プロジェクトから派生しているBlockchainはオリジナルプロジェットのAddressシステムをフォロワーすることが多いです。
Ethereumとその派生プロジェットは互い同じプロジェットで見ては行けないですが、Addressが互換可能の為、ユーザーを混乱させているケースがよく発生します。
Transaction and Signature
BitcoinのAddressは'Hashされた'Public Keyですから,史実Public Keyじゃありません。 だから、Transaction(取引)を作る時,Addressの所有者はPublic Keyをいっしょにに公開します。
Public Keyが公開されたあと、AddressはPublic Keyから作られているため、Blockchain Networkの参加者は同じ方法でこれを確認できます。
Public Keyが有効ならば、Private Keyを持っている所有者はBlockchain Network参加者に、自身が資産の所有者だとPublic-key cryptographyで証明できます。
Reference
- この文書は韓国語文書から翻訳されています。韓国語文書が原文になります。
- Rivest, R.; Shamir, A.; Adleman, L. (February 1978). "A Method for Obtaining Digital Signatures and Public-Key Cryptosystems"
- Diffie, W.; Hellman, M.E. (November 1976). "New directions in cryptography"
- BitcoinJ, Apache License 2.0
- List of address prefixes