امضای Schnorr چگونه می‌‌تواند بیت کوین‌‌ را بهبود دهد؟

به کمک امضاهای Schnorr می‌‌توان در هنگام اعتبارسنجی بلوک‌های زیاد، در نیروی محاسباتی صرفه‌‌جویی کرد. برخی ویژگی‌‌های امضای Schnorr یا اشنور بسیار عالی و هوشمندانه هستند، اما برخی از آن‌‌ها مشکلاتی به دنبال دارند که در ادامه به بررسی آنها می‌پردازیم.

0 88

هنگامی که در حال خواندن مقاله MuSig  یا چند امضایی در بلاک‌‌ استریم (Blockstream) بودم، مدام سعی می‌‌کردم تصور کنم این مسائل برای من که کاربر بیت کوین‌‌ هستم چه معنایی دارد. آن طور که من دریافتم، برخی ویژگی‌‌های امضای Schnorr یا اشنور بسیار عالی و مناسب هستند ولی برخی از آن‌‌ها واقعا آزاردهنده‌‌اند. در اینجا می‌‌خواهم دیدگاه‌‌های خودم در این زمینه را در میان بگذارم. پیش از هر کاری لازم است یک یادآوری مختصر انجام دهیم.

الگوریتم امضای دیجیتالی منحنی بیضی (ECDSA)

در حال حاضر ما در بیت کوین‌‌ از ECDSA استفاده می‌‌کنیم. برای امضاء کردن یک پیام (به نام m) آن را هش می‌‌کنیم و این هش را یک شماره در نظر می‌‌گیریم. بنابراین (z = hash(m. در کنار این، ما به یک عدد رندوم یا دسته‌‌کم شبیه به رندوم نیاز داریم که آن را k می‌‌نامیم. ترجیح ما بر این است که به سازنده‌‌های عددهای رندوم اعتماد نکنیم (این RGNها می‌‌توانند اشکالات و آسیب‌‌پذیری‌‌های زیادی داشته باشند). بنابراین معمولا برای محاسبه‌‌ k قطعی از RFC6979  استفاده می‌‌کنیم و این کار بر اساس پیامی که می‌‌خواهیم امضاء کنیم انجام می‌‌گیرد.

ما به کمک یک کلید خصوصی pk می‌‌توانیم برای پیامی به نام m امضایی بسازیم که شامل دو عدد است. یکی r  که مختصات x نقطه تصادفی R = k×G است و دیگری s = (z+r⋅pk)/k. سپس هرکس با داشتن کلید عمومی ما می‌‌تواند امضایمان را تایید کند. به این صورت که بررسی می‌‌کند مختصات x نقطه‌‌یz/s)×G+(r/s)×P) برابر با r باشد.

امضای Schnorr چگونه می‌‌تواند بیت کوین‌‌ را بهبود دهد؟

نمای الگوریتم ECDSA. برای نشان دادن بهتر، منحنی بیضی روی نقطه‌‌های حقیقی رسم شده است.

این الگوریتم بسیار رایج و خوب است ولی می‌‌توان آن را بهبود داد. نخست اینکه که در تایید امضاء یک وارونه‌‌سازی (1/s) و دو ضرب نقطه‌‌ای وجود دارد که این عملیات‌‌ها نیازمند توان کامپیوتری زیادی هستند. در بیت کوین‌‌ هر گره باید تمامی تراکنش‌‌ها را تایید نماید. یعنی هنگامی که یک تراکنش ارسال می‌‌کنید، هزاران کامپیوتر باید امضای شما را تایید کنند. ساده‌‌ کردن فرآیند تایید بسیار مفید خواهد بود حتی اگر باعث سخت‌‌تر شدن فرآیند امضاء کردن شود.

دوم اینکه هر کدام از گره‌‌ها باید هر کدام از امضاها را جداگانه تایید کنند. در مورد تراکنش چندامضایی m از n حتی ممکن است گره مجبور شود یک امضاء را چند بار تایید کند. برای نمونه ورودی یک تراکنش چندامضایی 7 از 11 شامل 7 امضاء است و در هر گره باید بین 7 تا 11 تایید امضاء داشته باشد. چنین تراکنشی جای بسیار زیادی در بلوک خواهد گرفت و شما مجبورید کارمزد هنگفتی برای انجام آن بپردازید.

امضای Schnorr

ساخت امضاهای Schnorr اندکی متفاوت است. برای این کار به جای دو اسکالر (r,s)  از یک نقطه R و یک اسکالر s استفاده می‌‌کنیم. به مانند ECDSA در اینجا نیزR  یک نقطه‌‌ رندوم روی منحنی بیضی (R = k×G) است. محاسبه‌‌ بخش دوم امضاء کمی متفاوت است، یعنی s = k + hash(P,R,m) ⋅ pk که در آن pk همان کلید خصوصی، P = pk×G کلید عمومی و m هم پیام است. در این حالت برای تایید امضاء باید معادله‌‌ s×G = R + hash(P,R,m)×P را بررسی کنیم.

این معادله خطی است بنابراین می‌‌توان معادلات را با هم جمع و تفریق کرد، بدون اینکه درستی رابطه برهم بخورد. با این روش می‌‌توان از چندین ویژگی خوب امضای Schnorr برخوردار شد.

امضای Schnorr چگونه می‌‌تواند بیت کوین‌‌ را بهبود دهد؟

نمای تایید امضای Schnorr

1. اعتبارسنجی بچ (Batch validation)

برای تایید یک بلوک در بلاک چین بیت کوین‌‌ باید اطمینان یابیم که همه امضاهای بلوک معتبر هستند. اگر حتی یکی از امضاها اعتبار نداشته باشد (هر کدام که باشد) می‌‌بایست کل بلوک را رد کنیم. در ECDSA هر امضاء باید به طور جداگانه تایید شود. یعنی اگر در یک بلوک 1000 امضاء داشته باشیم باید 1000 وارونه‌‌سازی و 2000 ضرب نقطه‌‌ای را محاسبه نماییم. پس باید روی هم نزدیک به 3000 عملیات سنگین انجام شود.

با وجود امضای Schnorr می‌‌توانیم همه‌‌ معادلات تایید امضاء را با هم جمع کنیم و در نیروی محاسباتی صرفه‌‌جویی نماییم. در این حالت برای بلوکی که 1000 تراکنش دارد، روی هم باید تایید کنیم که:

امضای Schnorr چگونه می‌‌تواند بیت کوین‌‌ را بهبود دهد؟در اینجا یک دسته جمع نقطه داریم (نیروی لازم برای محاسبه‌‌ آن‌‌ها تقریبا هیچ است) و 1001 ضرب نقطه‌‌ای. تا به همین جای کار سه فاکتور بهبود وجود دارد. باید به ازای هر امضاء تقریبا یک عملیات محاسباتی سنگین انجام شود.

امضای Schnorr چگونه می‌‌تواند بیت کوین‌‌ را بهبود دهد؟

اعتبارسنجی دسته‌‌ای یا بچ دو امضاء. از آنجایی که معادله‌‌ی تایید خطی است، به شرط معتبر بودن همه‌‌ی امضاها، جمع چند معادله معتبر است. با این روش در نیروی محاسباتی صرفه‌‌جویی می‌‌شود زیرا جمع اسکالر و نقطه بسیار آسان‌‌تر از ضرب نقطه‌‌ها است.

2. انباشتگی کلید (Key aggregation)

تامین امنیت سکه‌‌های بیت کوین‌‌ یکی از هدف‌‌های ما است، بنابراین می‌‌توانیم برای کنترل آن‌‌ها دسته‌‌کم از دو کلید خصوصی متفاوت استفاده کنیم. یکی از این کلیدها روی لپ‌‌تاپ یا تلفن استفاده می‌‌شود و دیگری روی کیف پول سخت‌‌افزاری یا کیف پول سرد. در این صورت اگر یکی از کلیدها لو برود باز هم کنترل بیت کوین‌‌‌‌ها در اختیار ما خواهد بود. در حال حاضر این روش با اسکریپت چندامضایی 2 از 2 به اجرا درآمده است. در این روش می‌‌بایست در تراکنش دو امضای جداگانه وجود داشته باشد.

با وجود امضای Schnorr می‌‌توانیم از یک جفت کلید خصوصی (pk1,pk2) استفاده کرده و یک امضای مشترک بسازیم که با متناسب با یک کلید عمومی مشترک P=P1+P2=pk1×G+pk2×G است. برای ساخت این امضاء باید روی هر دستگاه یک شماره‌‌ی رندوم (k1,k2) انتخاب کنیم، یک نقطه‌‌ی رندوم Ri=ki×G ایجاد نماییم، آن‌‌ها را با هم جمع کنیم و یک هش یکسان (hash(P,R1+R2,m  محاسبه کنیم و سپس از هر دستگاه s1 و s2 بگیریم (si = ki + hash(P,R,m) ⋅ pki). سپس می‌‌توانیم این دو امضاء را با هم جمع کنیم و برای کلید عمومی مشترک P از یک جفت (R, s) = (R1+R2, s1+s2)  استفاده نماییم. دیگران نمی‌‌توانند تشخیص دهند که این یک امضای انباشته (aggregated signature) است یا خیر، زیرا درست به مانند یک امضای Schnorr عادی است.

این ساختار سه مشکل دارد. نخست اینکه از دید UI برای انجام یک تراکنش به چند دور ارتباط نیاز داریم که مربوط به محاسبه‌‌ی R و سپس امضاء کردن هستند. با وجود دو کلید خصوصی می‌‌توان این کار را با یک دسترسی به کیف پول سرد انجام داد؛ به این صورت که یک تراکنش امضاء نشده روی کیف پول آنلاین خود ایجاد می‌‌کنیم، سپس k1 را برمی‌‌گزینیم و R1=k1×G  را همراه با تراکنش امضاء نشده می‌‌نویسیم. سپس این دیتا را وارد کیف پول سرد کرده و امضاء می‌‌کنیم. از آنجایی که R1 را داریم، می‌‌توانیم در یک اجرا تراکنش را در کیف پول سرد امضاء نماییم. R2 و s2  را از کیف پول سرد گرفته و به کیف پول آنلاین می‌‌بریم. کیف پول آنلاین با آنچه قبلا انتخاب شده (k1, R1) تراکنش را امضاء می‌‌کند، در امضاء را با هم ترکیب می‌‌نماید و تراکنش امضاء شده را می‌‌فرستد. این روند بسیار همانند رویه‌‌ی موجود است ولی اگر یک کلید خصوصی سوم به آن افزوده شود، همه چیز بسیار پیچیده می‌‌گردد. تصور کنید دارایی چشمگیری دارید که با 10 کلید خصوصی کنترل می‌‌شود و آن‌‌ها در جاهای امنی در گوشه و کنار جهان نگهداری می‌‌شوند. در این صورت اگر بخواهید یک تراکنش انجام دهید، در حال حاضر مجبورید یک بار به تمام این مکان‌‌ها بروید ولی اگر از کلید انباشته استفاده کنید باید دو بار به این مکان‌‌ها بروید؛ یک بار برای جمع کردن Ri  و سپس برای امضاء کردن. بنابراین در این حالت بهتر است از امضاهای جداگانه‌‌ی بدون انباشت استفاده کنید، در این صورت تنها یک دور کافی است.

برای داشتن یک روند چندامضایی با امنیت اثبات‌‌پذیر، نیاز به سه دور ارتباط دارید:

  • یک عدد رندوم ki انتخاب کنید و برحسب آن یک Ri=ki×G . به همه تنها هش آن( ti=hash(Ri را بگویید تا همه مطمئن شوند شما پس از آگاهی از اعداد رندوم دیگران دیدگاه خود را تغییر نخواهید داد.
  • همه‌‌ی اعداد Ri را گردآوری کنید و R یکسان را محاسبه نمایید.
  • امضاء کنید.

مشکل دوم این رویه، حمله‌‌ای به نام کلید مخرب (Rogue key attack) است. ایده‌‌ کلی آن این است که اگر یکی از دستگاه‌‌های شما هک شود (برای نمونه کیف پول آنلاین شما) و وانمود کند که کلید عمومی آن (P1-P2) است، آنگاه می‌‌تواند با استفاده از کلید خصوصی pk1 خود دارایی‌‌های مشترک شما را به دست گیرد. یکی از آسان‌‌ترین راه‌‌های جلوگیری از این حمله، ضروری ساختن امضای کلید عمومی با کلید خصوصی مربوط به آن در هنگام راه‌‌اندازی دستگاه‌‌ها است.

سومین مشکل و مهم‌‌ترین آن‌‌ها این است که نمی‌‌توان برای امضاء کردن از k قطعی استفاده نمود. یک حمله‌‌ی ساده وجود دارد که در آن اگر از k قطعی استفاده کنید، هکر می‌‌تواند کلید خصوصی شما را به دست آورد. روند حمله به این صورت است که یک نفر لپ‌‌تاپ شما را هک می‌‌کند و یکی از دو کلید خصوصی شما (فرض کنیم pk1) را به دست می‌‌آورد. در این حالت احساس امنیت می‌‌کنید زیرا دستیابی به بیت کوین‌‌‌‌های شما نیاز به امضای انباشته از pk1 و pk2 دارد. بنابراین همانند همیشه به انجام تراکنش می‌‌پردازید؛ یک تراکنش امضاء نشده و شماره R1 تهیه می‌‌کنید، آن‌‌ها را وارد کیف پول سخت افزاری خود کرده و آنجا امضاء می‌‌نمایید. سپس (R2, s2) را بازمی‌‌گردانید. ناگهان اتفاقی برای کیف پول آنلاین شما می‌‌افتد و دیگر نمی‌‌تواند امضاء و ارسال کند. بار دیگر تلاش می‌‌کنید ولی کامپیوتر هک شده‌‌ی شما این بار از یک عدد رندوم دیگر (فرض کنید R1′) استفاده می‌‌کند. شما همان تراکنش را بار دیگر با کیف پول سخت‌‌افزاری خود امضاء می‌‌کنید و عددها (R2, s2′) را به کامپیوتر هک شده‌‌ی خود بازمی‌‌گردانید. به این ترتیب همه‌‌ی بیت کوین‌‌‌‌های شما از دست می‌‌رود.

در این حمله، هکر برای یک تراکنش یک جفت امضای معتبر دریافت می‌‌کند که عبارت‌‌اند از (R1, s1, R2, s2) و (R1′, s1′, R2, s2′). در اینجا R2 یکی است ولی R = R1+R2 و R’=R1’+R2  متفاوت هستند. این یعنی هکر می‌‌تواند دومین کلید خصوصی ما را محاسبه کند؛ به این صورت که

s2-s2’=(hash(P,R1+R2,m)-hash(P,R1’+R2,m))⋅pk2 و

(pk2=(s2-s2′)/(hash(P,R1+R2,m)-hash(P,R1’+R2,m .

از دید من این بدترین ویژگی کلید انباشته است. ما در همه جا برای استفاده از کلید انباشته می‌‌بایست از یک سازنده‌‌ی اعداد تصادفی خوب بهره بگیریم.

3. MuSig

MuSig  یکی از این سه مشکل را حل می‌‌کند و انجام حمله کلید مخرب را ناممکن می‌‌سازد. هدف این است که از چند طرف/ دستگاه مختلف، چندین امضاء و کلید عمومی را جمع آوری کنیم، طوری که ثابت نشود کلید خصوصی مربوط به آن کلید عمومی را در اختیار داریم.

امضای انباشته متناسب با کلید عمومی انباشته است. ولی برای اینکه تنها کلیدهای عمومی همه‌‌ی امضاء کنندگان را با هم جمع کنیم، آن‌‌ها را در فاکتور ضرب می‌‌نماییم. کلید عمومی انباشته برابر با P=hash(L,P1)×P1+…+hash(L,Pn)×Pn خواهد بود. در اینجا L=hash(P1,…,Pn) یک عدد یکسان است که به همه‌‌ی کلید‌‌های عمومی بستگی دارد. این حالت غیرخطی اجازه نمی‌‌دهد هکر به مانند حمله کلید مخرب بتواند یک کلید عمومی بد بسازد. با اینکه هکر دقیقا می‌‌داند hash(L,Patk)×Patk باید چه باشد ولی نمی‌‌تواند Patk  را از آن به دست آورد. این همان مشکل به دست آوردن کلید خصوصی از کلید عمومی است.

ادامه‌‌ کار همانند مورد پیشین است. برای ایجاد یک امضاء باید هر کدام از امضاء کنندگان یک عدد رندوم ki انتخاب کنند و Ri=ki×G  را با دیگران به اشتراک بگذارند. سپس آن‌‌ها همه‌‌ی این نقطه‌‌های رندوم را با هم جمع می‌‌کنند تا یک نقطه R=R1+…+Rn  و یک امضاء si = ki + hash(P,R,m) ⋅ hash(L,Pi) ⋅ pki به دست آید. امضای انباشته (R, s)=(R1+…+Rn, s1+…+sn) است و معادله‌‌ی تایید همچون گذشته s×G = R + hash(P,R,m)×P می‌‌باشد.

4. چندامضای مرکل

همان گونه که دیدید MuSig و کلید انباشته برای هر تراکنش به امضای همه‌‌ی امضاء کننده‌‌ها نیاز دارند. ولی اگر بخواهید یک چندامضایی 2 از 3 داشته باشید چه؟ آیا در این صورت اصلا می‌‌توان از امضای انباشته استفاده کرد یا مجبوریم به روش رایج از OP_CHECKMULTISIG یا امضاهای جداگانه استفاده کنیم؟

البته امکان آن وجود دارد ولی باید یک تغییر کوچک در پروتکل ایجاد شود. می‌‌توانیم یک آپ‌‌ – کد (op-code) مانند OP_CHECKMULTISIG به وجود آوریم که همخوانی امضای انباشته را با یک آیتم مشخص در درخت مرکل کلیدهای عمومی بررسی می‌‌کند.

برای نمونه اگر از یک چندامضایی 2 از 3 با کلیدهای عمومی P1 ، P2 و P3 استفاده کنیم، آنگاه باید از کلیدهای عمومی انباشته‌‌ برای همه‌‌ی ترکیب‌‌های ممکن (P1, P2)(P2, P3)(P1, P3)  یک درخت مرکل ایجاد کنیم و ریشه را در اسکریپت قفل کننده (locking script) قرار دهیم. برای پرداخت بیت کوین‌‌‌‌ها یک امضاء و یک اثبات تهیه می‌‌کنیم که کلید عمومی ما در درخت است. برای چندامضایی 2 از 3 تنها سه المان در درخت وجود دارد و اثبات نیز دارای دو هش می‌‌باشد؛ یک هش که ما از آن استفاده می‌‌کنیم و دیگری همسایه آن. برای چندامضایی 7 از 11 شمار ترکیب‌‌های احتمالی کلید 11!/7!/4!=330 است و اثبات نیازمند 8 المان است. به طور کلی شمار المان‌‌های موجود در اثبات تقریبا مقیاسی خطی دارد که برحسب تعداد کلیدها در چندامضایی تغییر می‌‌کند ((log2(n!/m!/(n-m)!.

ولی با وجود درخت مرکل کلیدهای عمومی دیگر به چندامضایی‌‌های m از n محدود نیستیم. می‌‌توانیم با هر کلید عمومی که می‌‌خواهیم درخت بسازیم. برای نمونه اگر یک لپ‌‌تاپ، یک تلفن، یک کیف پول سخت‌‌افزاری و یک سید بازیابی (recovery seed) داشته باشیم، می‌‌توانیم ساختاری ایجاد کنیم که به ما امکان می‌‌دهد بیت کوین‌‌‌‌ها را با لپ‌‌تاپ و کیف پول سخت‌‌افزاری، تلفن و کیف پول سخت‌‌افزاری یا تنها با سید بازیابی خرج کنیم. در حال حاضر این کار تنها با OP_CHECKMULTISIG قابل انجام نیست و تنها در صورتی امکان‌‌پذیر است که از اسکریپت بسیار پیچیده با شاخه‌‌ها و بخش‌‌های زیاد استفاده نماییم.

امضای Schnorr چگونه می‌‌تواند بیت کوین‌‌ را بهبود دهد؟

درخت مرکل از کلیدهای عمومی انباشته. فراتر از چندامضایی m از n

نتیجه

امضای Schnorr عالی است. به کمک امضاهای Schnorr می‌‌توان در هنگام اعتبارسنجی بلوک های زیاد، در نیروی محاسباتی صرفه‌‌جویی نمود. همچنین به کمک آن‌‌‌‌ها می‌‌توانیم از کلیدهای انباشته استفاده کنیم. استفاده از این روش مشکلاتی به دنبال دارد ولی ما مجبور به استفاده از آن‌‌ها نیستیم. در حالت عادی می‌‌توانیم همچنان از روش‌‌های چندامضایی نرمال با امضاهای جداگانه و غیر انباشته استفاده کنیم و کارهای زیادی انجام دهیم. من بسیار مشتاقم استفاده از این کلیدها را آغاز کنیم و امیدوارم به زودی آن‌‌ها را در پروتکل بیت کوین‌‌ ببینم.

طرح MuSig هوشمندانه است و خواندن خود تحقیق بسیار آسان و روان است. من به شدت توصیه می‌‌کنم اگر فرصت کردید نگاهی به آن بیندازید.

از سوی دیگر، یک نوع امضای خوب دیگر هم وجود دارد. امضاهای BLS که از برخی جهات حتی از امضای Schnorr هم بهتر هستند.

منبع

شاید از این مطالب هم خوشتان بیاید.

ارسال پاسخ

آدرس ایمیل شما منتشر نخواهد شد.