Первый вопрос: зачем всё это надо? Дело в том, что (применительно к Ethereum) любая транзакция должна быть подписана пользователем. Мы должны подтвердить, что, условно говоря, вот этот денежный перевод со своего кошелька делаю действительно я, а не какой-то неизвестный товарищ. Если говорить из общих соображений, то подпись транзакции можно представить высчитывание её хэша и затем шифрование получившегося хэша с помощью закрытого ключа (private key) пользователя. Закрытый ключ, как подсказывает название, известен лишь самому юзеру.
Принимающая сторона берёт транзакцию и тоже считает её хэш, после чего расшифровывает присланную подпись. Расшифровка происходит с помощью открытого ключа пользователя, который может быть известен кому угодно. Если хэши совпали, то всё хорошо, если нет - где-то есть проблема. Кроме того, мы знаем, что в том же Solidity есть ecrecover, которая может сказать, кто именно подписал сообщение.
Другой пример - это использование ассиметричного шифрования для так называемого handshake, когда две стороны вырабатывают общий ключ. Этот ключ используется во время обмена данными (например, по https). Про это мы говорили в лекции по RSA.
Из всего этого мы делаем простой вывод: наличие открытого и закрытого ключа принципиально важно для криптовалют и не только. И вот тут-то мы задаёмся другим вопросом: а откуда эти ключи взять и как сделать их надёжными? В частности, нам нужно, чтобы на основе известного закрытого ключа можно было легко посчитать открытый, но ни в коем случае не наоборот, иначе закрытые ключи пользователей будут скомпрометированы! Собственно говоря, над этой проблемой, в том числе, и работают криптографы. Один вариант - это использовать старый добрый RSA, где ключами выступают обычные числа (только очень большие). Но мир не стоит на месте, и поэтому был придуман другой подход, который и основывается на эллиптической кривой. Он быстрее, надёжнее и менее ресурсозатратен, что особенно важно для маломощных устройств.
Таким образом, мы поняли, зачем вообще этот ECC нужен - мы можем использовать эллиптические кривые, чтобы создавать надёжные ключи. Что же это за кривые такие? В общем случае у таких кривых довольно длинное уравнение, но в крипте мы работаем с кривыми Вейерштрасса, которые попроще. Описываются они как
y ** 2 = x ** 3 + a * x + b, где ** - это возведение в степень. a и b - это параметры кривой, которые подбираются криптографами и могут варьироваться в зависимости от стандарта (важно то, что эти параметры известны всем). К примеру, для Bitcoin и Ethereum используется кривая под названием secp256k1, параметры которой равны 0 и 7 соответственно. Уравнение же превращается в y ** 2 = x ** 3 + 7.Как выглядят эллиптические кривые и как меняются в зависимости от параметров можно посмотреть вот на этой визуализации https://www.desmos.com/calculator/ialhd71we3 В частности, можно видеть, что эта кривая симметрична относительно оси Х, что довольно важно (есть у неё и ряд других свойств, о которых позже).
Также следует отметить, что в ECC эти кривые строятся на конечном поле Fp (оно называется поле Галуа), где p - это натуральное число. Если говорить простым, языком, то кривая не бесконечна, а лежит в квадрате p x p. В существующих стандартах число p очень большое. К примеру, для кривой secp256k1 значение p равно
2 ** 190 - 1 - это совершенно гигантское число. Спецификацию можно глянуть тут https://en.bitcoin.it/wiki/Secp256k1 Это нужно для того, чтобы мы могли сгенерировать очень много потенциальных ключевых пар. Поэтому фактически мы можем сказать, что наше уравнение трансформируется в y ** 2 = x ** 3 + 7 (mod p), где mod - остаток от деления.