Чуть-чуть привел в порядок мозги по поводу тапрута - что там есть простые транзакции где только подпись, и есть сложные с контрольным блоком, и деревом возможных redeem-скриптов. Вообще красиво, конечно. Самый простой пример: мы делали раньше мультисиг: допустим, с какого-то адреса могут забрать баблоса либо Алиса, либо Боб. Это multisig 1-из-2 в каком бы обличии он ни был - в bare-multisig, потом в p2sh, потом в p2wsh. В любом случае в блокчейн записывали оба публичных ключа. А нахуа? Теперь если выводит бабло Боб - он свою подпись ставит и свой скрипт. И никто никогда не узнает что к этой транзакции имела отношение Алиса. Ну да это детали.
Я свою реализацию schnorr-подписей сделал для подписывания транзакций. Стыдно признаться, но ихнюю библиотеку secp256k1 которую они повсеместно используют в биткойне я не могу в свой виндусовый проект вставить. У меня не получается. Пришлось переписать на использование встроенного в Qt OpenSSL. По скорости оно хуже, но мне торопиться некуда. Мне важнее чтобы за попытками оптимизации можно было разглядеть алгоритм. Выглядит примерно так. Ну, это фрагмент, конечно.
{
const MyKey32 tag_hash ( MyKey32::brain ( tag ) );
return MyByteArray ( tag_hash ).putArray ( tag_hash ).putArray ( data ).sha256 ( );
}
const QByteArray Schnorr::sign ( const MyKey32& msg, const MyKey32& priv, const MyKey32& aux ) const
{
const MyEcPoint p ( ctx, MyBigNum ( priv ) );
const MyKey32 x ( p.x ( ) );
const MyKey32 y ( p.y ( ) );
const MyKey32 d ( ( y.constData ( )[31] & 1 ) ? MyKey32::SUB ( n, priv ) : priv );
const MyKey32 t ( MyKey32::XOR ( d, tagged_hash ( "BIP0340/aux", aux ) ) );
const MyKey32 k0 ( tagged_hash ( "BIP0340/nonce", QByteArray ( t ).append ( x ).append ( msg ) ) );
const MyEcPoint r ( ctx, MyBigNum ( k0 ) );
const MyKey32 R ( r.x ( ) );
const MyKey32 e ( tagged_hash ( "BIP0340/challenge", QByteArray ( R ).append ( x ).append ( msg ) ) );
const MyKey32 k ( ( r.y ( ).constData ( )[31] & 1 ) ? MyKey32::SUB ( n, k0 ) : k0 );
return MyByteArray ( R ).putArray ( MyKey32::ADD ( k, MyKey32::MUL ( e, d ) ) );
}