Skip to content

Latest commit

 

History

History
100 lines (68 loc) · 5.39 KB

kip-0005.md

File metadata and controls

100 lines (68 loc) · 5.39 KB
  KIP: 5
  Layer: Applications
  Title: Message Signing
  Author: coderofstuff
  Status: Active

Motivation

Signing messages provides a mechanism for proving access to a given address without revealing your private keys. This paves the way for proving ownership of funds, native assets (not implemented yet) among many possible use-cases.

This document aims to provide a standard which applications can implement their message signing and verification functionalities.

Specifications

Signing a message

This part of the process is relevant to applications that have access to the private key and will sign some message.

Given:

  • A string of arbitrary length. We'll call this raw_message
  • A private_key

Output: signature associated with that string with some given private key

  1. Hash the message using Blake2B. To create sufficient domain separation with transaction input sighash, use a different Blake2B key PersonalMessageSigningHash (Transaction hashes uses TransactionSigningHash as key to blake2b) and a digest length of 32
  2. Schnorr sign the hashed message

In summary: schnorr_sign(blake2b(raw_message, digest_size=32, key='PersonalMessageSigningHash'), private_key)

Why hash a message?

  1. Reduces the size of some arbitrary message to a fixed length hash
  2. Prevents signing of sighashes accidentally - the raw message is hashed with a different blake2b key (PersonalMessageSigningHash) from what is used for transaction hashes (TransactionSigningHash), creating sufficient domain separation

Verifying a message signature

This part of the process is relevant to applications that is asking some public_key owner to provide evidence that they have access to the private_key of this public_key.

Given:

  • A string of arbitrary length. We'll call this raw_message
  • A public_key which the application has asked to sign the message

Output: true if the signature is valid, false otherwise

  1. Hash the raw message in the same way as above for signing
  2. Schnorr verify the signature matches the public_key you are testing for

In summary: schnorr_verify(blake2b(raw_message, digest_size=32, key='PersonalMessageSigningHash'), public_key)

Sample Implementation

Full code in /kip-0005/test-cases.py

from hashlib import blake2b
from secp256k1 import PublicKey, PrivateKey

# Assume we have a private-public key pair
# some_secret_key (private) and some_public_key (public)

def hash_message(raw_message) -> bytes:
    message_hash = blake2b(digest_size=32, key=bytes("PersonalMessageSigningHash", "ascii"))
    message_hash.update(raw_message)
    
    return message_hash.digest()

def sign_message(raw_message) -> bytes:
    message_digest = hash_message(raw_message)

    return PrivateKey(some_secret_key).schnorr_sign(message_digest, None)

def verify_message_signature(raw_message, message_signature) -> bool:    
    message_digest = hash_message(raw_message)

    return PublicKey(some_public_key).schnorr_verify(message_digest, message_signature, None)

Test Vectors

Keys taken from https://github.com/bitcoin/bips/blob/master/bip-0340/test-vectors.csv

index secret key public key aux_rand message_str signature
0 0000000000000000000000000000000000000000000000000000000000000003 F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9 0000000000000000000000000000000000000000000000000000000000000000 Hello Kaspa! 40B9BB2BE0AE02607279EDA64015A8D86E3763279170340B8243F7CE5344D77AFF1191598BAF2FD26149CAC3B4B12C2C433261C00834DB6098CB172AA48EF522
1 B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659 0000000000000000000000000000000000000000000000000000000000000001 Hello Kaspa! EB9E8A3C547EB91B6A7592644F328F0648BDD21ABA3CD44787D429D4D790AA8B962745691F3B472ED8D65F3B770ECB4F777BD17B1D309100919B53E0E206B4C6
2 B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659 0000000000000000000000000000000000000000000000000000000000000001 こんにちは世界 810653D5F80206DB519672362ADD6C98DAD378844E5BA4D89A22C9F0C7092E8CECBA734FFF7922B656B4BE3F4B1F098899C95CB5C1023DCE3519208AFAFB59BC
3 B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659 0000000000000000000000000000000000000000000000000000000000000001 (See Test CAse 3 Full Text section) 40CBBD3938867B10076BB14835557C062F5BF6A4682995FC8B0A1CD2ED986EEDAAA00CFE04F6C9E5A9546B860732E5B903CC82780228647D5375BEC3D2A4983A

Test Case 3 Full Text

Lorem ipsum dolor sit amet. Aut omnis amet id voluptatem eligendi sit accusantium dolorem 33 corrupti necessitatibus hic consequatur quod et maiores alias non molestias suscipit? Est voluptatem magni qui odit eius est eveniet cupiditate id eius quae aut molestiae nihil eum excepturi voluptatem qui nisi architecto?

Et aliquid ipsa ut quas enim et dolorem deleniti ut eius dicta non praesentium neque est velit numquam. Ut consectetur amet ut error veniam et officia laudantium ea velit nesciunt est explicabo laudantium sit totam aperiam.

Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qui dolores quis et voluptate labore et adipisci deleniti. Est nostrum explicabo aut quibusdam labore et molestiae voluptate. Qui omnis nostrum At libero deleniti et quod quia.