⛓ دانشکدهٔ ۲ · رمزنگاری کاربردی
امضای دیجیتال: ECDSA و Schnorr
Digital signatures: ECDSA and Schnorr
پیشنیازها: کلید عمومی، کلید خصوصی و آدرس
📚 آموزش در سه سطح
از سطح ساده شروع کنید؛ اگر روشن بود، سطح بعد را بخوانید. سطح مناسب شما ذخیره میشود.
🌱 توضیح ساده
وقتی یک برگهٔ بانکی را امضا میکنید، بانک امضای شما را با نمونهٔ ثبتشده مقایسه میکند. امضای دیجیتال همین کار را با ریاضی انجام میدهد، ولی خیلی محکمتر: شما با کلید خصوصیتان روی یک پیام مشخص، مثلاً «۰٫۱ بیتکوین از این خروجی به آن آدرس برود»، امضا تولید میکنید و هر کس با کلید عمومیتان میتواند بررسی کند که امضا درست است؛ بدون اینکه هرگز کلید خصوصی شما را ببیند.
امضای دیجیتال برخلاف امضای روی کاغذ، به محتوای پیام گره خورده است. اگر کسی پس از امضا حتی یک رقم از مبلغ یا یک نویسه از آدرس گیرنده را عوض کند، امضا دیگر معتبر نیست. پس امضا دو چیز را همزمان ثابت میکند: این پیام را صاحب کلید خصوصی تأیید کرده، و پیام پس از امضا تغییر نکرده است. به همین دلیل نودهای بلاکچین میتوانند تراکنش شما را از هر مسیری که رسیده باشد، با اطمینان بپذیرند.
یک هشدار مهم: امضا فقط برای «ارسال پول» نیست. در اتریوم و شبکههای مشابه، سایتها ممکن است از شما بخواهند یک «پیام» را امضا کنید. برخی از این پیامها کاملاً بیخطرند، مثل ورود به یک سایت، ولی برخی دیگر اجازهٔ خرجکردن توکنهایتان را به دیگری میدهند. قاعدهٔ طلایی این است که هیچ چیزی را که محتوایش را نمیفهمید امضا نکنید.
📘 توضیح متوسط
در بیتکوین، آنچه امضا میشود خود تراکنش نیست، بلکه هشی از بخشهای مشخصی از آن است که «sighash» نامیده میشود. حالت پیشفرض (SIGHASH_ALL) همهٔ ورودیها و خروجیها را پوشش میدهد، پس هیچکس نمیتواند پس از امضا، گیرنده یا مبلغ را تغییر دهد. حالتهای دیگر هم وجود دارد، مثلاً امضایی که فقط یک ورودی و یک خروجی را تضمین میکند؛ این حالتها کاربردهای خاصی دارند ولی اگر بیدقت استفاده شوند، خطرناکاند.
الگوریتم سنتی بیتکوین و اتریوم ECDSA روی منحنی secp256k1 است. امضای ECDSA یک جفت عدد (r و s) است: امضاکننده یک عدد تصادفی یکبارمصرف به نام نانس (k) انتخاب میکند، r از مختص x نقطهٔ k·G به دست میآید و s از ترکیب k، هش پیام، r و کلید خصوصی ساخته میشود. بررسیکننده فقط با کلید عمومی، هش پیام و (r, s) درستی امضا را میسنجد. امضای ECDSA در تراکنشهای بیتکوین با قالب DER معمولاً ۷۱ تا ۷۲ بایت است.
در نوامبر ۲۰۲۱ با فعالشدن Taproot، امضای Schnorr (استاندارد BIP340) به بیتکوین اضافه شد. امضای Schnorr دقیقاً ۶۴ بایت است و کلید عمومی آن ۳۲ بایت. مزیت بزرگتر «خطیبودن» آن است: چند کلید میتوانند با پروتکلهایی مثل MuSig2 یک کلید و یک امضای مشترک بسازند، طوری که یک کیف پول چندامضایی روی زنجیره درست مثل یک کیف پول معمولی دیده شود؛ هم ارزانتر است و هم حریم خصوصی بیشتری دارد. ابزار کلید و امضای آزمایشگاه آکادمی برای نمایش مفهوم از یک منحنی استاندارد WebCrypto مرورگر (مانند P-256) استفاده میکند، نه از secp256k1؛ اصل کار یکی است ولی امضای آن در بیتکوین معتبر نیست.
🔬 توضیح تخصصی
شکنندگی اصلی ECDSA در نانس است. اگر یک کلید خصوصی برای دو پیام متفاوت با نانس یکسان امضا کند، مقدار r در هر دو امضا یکی میشود و هر ناظری میتواند از دو معادله، ابتدا k و سپس کلید خصوصی را محاسبه کند. حتی سوگیری کوچک در نانسها، با جمعآوری تعداد زیادی امضا و روشهای شبکه (lattice)، میتواند کلید را فاش کند. راهحل استاندارد، نانس قطعی طبق RFC 6979 است: k از هش کلید خصوصی و پیام ساخته میشود، پس برای پیام یکسان همیشه یکسان و برای پیام متفاوت متفاوت است. BIP340 هم روش قطعی مشابهی با امکان افزودن تصادف کمکی را توصیه میکند.
«انعطافپذیری امضا» (malleability) ظرافت دیگری است: در ECDSA اگر (r, s) معتبر باشد، (r, n−s) هم معتبر است. پیش از SegWit، شخص ثالث میتوانست با این ترفند شناسهٔ تراکنش (txid) را بدون باطلکردن آن عوض کند و نرمافزارهایی را که تراکنش را با txid دنبال میکردند گمراه کند. بیتکوین با قاعدهٔ «s کوچک» در سیاست نودها و سپس جدا کردن witness از محاسبهٔ txid در SegWit این مشکل را مهار کرد؛ همین اصلاح پیشنیاز کانالهای پرداخت مثل شبکهٔ لایتنینگ بود. Schnorr طبق BIP340 از ابتدا غیرقابلانعطاف طراحی شده است.
در اتریوم امضا (v, r, s) کنار تراکنش قرار میگیرد و فرستنده از روی امضا «بازیابی» میشود؛ به همین دلیل تراکنش فیلد «از» جداگانه ندارد. EIP-155 شناسهٔ زنجیره را وارد امضا کرد تا تراکنش یک شبکه در شبکهٔ دیگر بازپخش نشود. اما خطرناکترین بخش برای کاربران، امضای پیامهای ساختاریافته طبق EIP-712 است: امضای یک پیام permit (EIP-2612) یا مجوزهای مشابه هیچ کارمزدی ندارد و هیچ تراکنشی هم نمیفرستد، ولی به گیرندهٔ امضا اجازه میدهد بعداً توکنهای شما را خرج کند. بسیاری از سرقتهای فیشینگ دقیقاً از همین راه انجام میشوند. امنیت امضا دو لایه دارد: ریاضی الگوریتم، که محکم است، و فهم انسانی از آنچه امضا میشود، که حلقهٔ ضعیف است.
🌍 مثال واقعی: باگ مولد تصادفی اندروید و تکرار نانس (اوت ۲۰۱۳)
در ۱۱ اوت ۲۰۱۳ وبسایت bitcoin.org هشداری امنیتی منتشر کرد: یک نقص در پیادهسازی SecureRandom جاوا در اندروید باعث میشد برخی کیف پولهای بیتکوین اندرویدی هنگام امضا، نانس تکراری تولید کنند. نتیجه همان چیزی بود که در بخش تخصصی دیدید: هر کس دو امضا با r یکسان روی زنجیره میدید، میتوانست کلید خصوصی را محاسبه کند و موجودی آدرس را منتقل کند.
کیف پولهای آسیبدیده بهروزرسانی منتشر کردند که کلید تازه میساخت و موجودی را به آدرسهای جدید منتقل میکرد. این حادثه یکی از دلایل گسترش نانس قطعی RFC 6979 در کیف پولهای بیتکوین بود.
نمونهٔ مشابه پیشتر در دسامبر ۲۰۱۰ رخ داده بود: گروه fail0verflow نشان داد سونی در امضای نرمافزارهای پلیاستیشن ۳ از نانس ثابت استفاده میکرد و کلید خصوصی امضای سونی را به دست آورد. ریاضی ECDSA سالم بود؛ پیادهسازی شکست خورد.
🔤 واژگان تخصصی
دادهای که با کلید خصوصی روی هش یک پیام تولید میشود و هر کس با کلید عمومی میتواند درستی آن و تغییرنکردن پیام را بررسی کند.
مثال: هر ورودی تراکنش بیتکوین امضایی دارد که مالکیت خروجی خرجشده را ثابت میکند.
الگوریتم امضای مبتنی بر منحنی بیضوی که امضایی شامل دو عدد r و s تولید میکند و به نانس یکبارمصرف و مخفی نیاز دارد.
مثال: اتریوم برای امضای همهٔ تراکنشهای حسابهای کاربری از ECDSA روی secp256k1 استفاده میکند.
طرح امضای خطی با امضای ۶۴ بایتی که با Taproot وارد بیتکوین شد و امکان تجمیع کلید و امضا را میدهد.
مثال: یک کیف پول ۲ از ۲ با MuSig2 روی زنجیره مانند یک امضای تکنفره دیده میشود.
عدد یکبارمصرف و مخفی که در هر امضا به کار میرود؛ تکرار یا قابل حدس بودن آن کلید خصوصی را فاش میکند.
مثال: دو امضا با r یکسان از یک کلید، نشانهٔ تکرار نانس و فاششدن کلید است.
امضای پیامی با ساختار مشخص در اتریوم که بدون تراکنش و کارمزد انجام میشود ولی میتواند اجازههای واقعی مانند مجوز خرج توکن بدهد.
مثال: امضای یک پیام permit در سایت جعلی میتواند به مهاجم اجازهٔ برداشت توکنها را بدهد.
🔑 نکات کلیدی
- امضا مالکیت را بدون فاشکردن کلید خصوصی اثبات میکند و هر تغییری در پیام آن را باطل میکند.
- در ECDSA نانس باید یکتا و مخفی باشد؛ تکرار آن کلید خصوصی را فاش میکند و نانس قطعی RFC 6979 راهحل استاندارد است.
- Schnorr از ۲۰۲۱ در بیتکوین فعال است: امضای ۶۴ بایتی، خطی، با امکان تجمیع کلیدها و حریم خصوصی بهتر برای چندامضاییها.
- امضای پیام در اتریوم بیهزینه است ولی ممکن است اجازهٔ خرج توکن بدهد؛ فقط چیزی را امضا کنید که میفهمید.
- دمو آزمایشگاه از منحنی استاندارد WebCrypto استفاده میکند؛ بیتکوین از ECDSA و Schnorr روی secp256k1 استفاده میکند.
⚠️ اشتباهات رایج
- تصور اینکه امضا پیام را رمزگذاری میکند؛ پیام امضاشده برای همه قابل خواندن است و امضا فقط اصالت و تمامیت آن را ثابت میکند.
- امضای هر درخواستی که کیف پول نشان میدهد با این فرض که «چون کارمزد ندارد، خطری هم ندارد»؛ امضای permit یا مجوز میتواند دارایی را در اختیار دیگری بگذارد.
- نوشتن پیادهسازی شخصی ECDSA با مولد تصادفی دستساز؛ بیشتر شکستهای واقعی از پیادهسازی و تصادف معیوب آمدهاند، نه از ریاضی.
- فرض اینکه امضای ساختهشده در دمو یا هر منحنی دیگر در بیتکوین هم معتبر است؛ منحنی و قالب امضا باید دقیقاً با پروتکل یکی باشد.
🛠 تمرین عملی: امضا، تغییر پیام و شکست بررسی
- در ابزار کلید و امضای آزمایشگاه یک جفت کلید آزمایشی بسازید.
- پیامی مثل «پرداخت ۱۰ واحد به علی» را امضا کنید و امضا را بررسی کنید تا نتیجهٔ «معتبر» ببینید.
- فقط عدد ۱۰ را به ۱۱ تغییر دهید و بدون امضای دوباره، همان امضا را بررسی کنید.
- پیام اصلی را برگردانید ولی این بار امضا را با کلید عمومی یک جفت کلید دیگر بررسی کنید.
- پیام اصلی را دو بار امضا کنید و دو امضا را مقایسه کنید؛ توضیح دهید چرا ممکن است متفاوت باشند و چرا این در ECDSA عیب نیست.
✅ معیار درستی: در مرحلهٔ ۲ امضا معتبر است؛ در مرحلههای ۳ و ۴ بررسی شکست میخورد؛ در مرحلهٔ ۵ اگر امضاها متفاوتاند، علتش نانس تصادفی متفاوت است و هر دو معتبرند. باید بتوانید بگویید این دمو از منحنی WebCrypto استفاده میکند و امضایش در بیتکوین قابل استفاده نیست.
🔒 در هیچ تمرینی از سرمایهٔ واقعی، عبارت بازیابی (Seed Phrase)، کلید خصوصی یا اتصال کیف پول اصلی استفاده نکنید.
📝 آزمون تطبیقی
هر بار ۵ سؤال از بانک ۹ سؤالی این درس انتخاب میشود؛ سؤالهایی که قبلاً اشتباه زدهاید زودتر برمیگردند. حدنصاب قبولی ۸۰٪ (۴ از ۵) است و درس بعد با قبولی باز میشود.
✍️ پرسش تشریحی
توضیح دهید چرا گفته میشود «ریاضی امضای دیجیتال محکم است ولی امنیت امضا در عمل اغلب در پیادهسازی یا رفتار کاربر شکست میخورد». دستکم دو رویداد یا سناریوی واقعی را تحلیل کنید.
بعد از نوشتن، پاسخ خود را با این معیارها بسنجید
خودارزیابی: هر نکتهای را که پاسخ شما بهروشنی پوشش داده علامت بزنید.
🤖 دستیار آموزشی
دستیار آفلاین آکادمی: پاسخها فقط از متن درسها و واژگان همین آکادمی پیدا میشوند و منبع هر پاسخ نشان داده میشود. هوش مصنوعی مولد نیست، حدس نمیزند و هیچ سیگنال خرید و فروشی نمیدهد.
📎 منابع مطالعاتی
- BIP340 — Schnorr Signatures for secp256k1
- Bitcoin Developer Guide — Transactions (signature hash types)
- RFC 6979 — Deterministic Usage of DSA and ECDSA
- ethereum.org — Transactions
🏁 معیار تسلط بر این درس: بتوانید با دمو آزمایشگاه نشان دهید که تغییر پیام امضا را باطل میکند، خطر تکرار نانس را توضیح دهید و یک درخواست امضای مخرب را از یک امضای بیخطر تشخیص دهید.