diff --git a/core/ed25519.md b/core/ed25519.md new file mode 100644 index 0000000..a6bd470 --- /dev/null +++ b/core/ed25519.md @@ -0,0 +1,61 @@ +# ED25519 Signatures WIP +Ed25519 is a type of Edwards-curve Digital Signature Algorithm (EdDSA) using a variant of Schnorr signature based on twisted Edwards curves using SHA-512 and Curve25519 elliptic curve. + +## Usage +Solana uses ed25519-dalek library with the edwards representation of Curve25519 the signature verification is done using “verify_restrict” function. +Ed25519 digital signature scheme was standardized in [RFC8032](https://www.rfc-editor.org/rfc/rfc8032). Although the standardization, there are variations in signature verification in different implementations which is explained in the section below. Some variations have their own custom criteria that are check the validity of the signatures. We have to ensure that the signatures are non-malleable, can be verified in constant time and have abstracted implementation. + +## Structure +Curve25519 which can be represented in Edwards form doesn't have a prime order ```l```. Instead they provide a group of order ```h.l``` where ```h``` is the co-factor and h = 8. This produces inconsistencies in signatures which is highly undesireable in production. This implies that there is: ++ A prime order subgroup ++ A "torsion" subgroup of small order points + +Due to the above case, two variations arise in the types of verification equations namely ++ Batched equation: ```[8]R = [8]([s]B - [k]A)``` ++ Unbatched equation: ```R = [s]B - [k]A``` + + +More details can be found [here](https://hdevalence.ca/blog/2020-10-04-its-25519am). +The dalek implementation verifier equation is of unbatched type given by ```R = [s]B - [k]A```. +Each ed25519 signature is serialized into a fixed 64 byte sized array represented as ```[u8; 64]``` in rust. The Publickey is a ```[u8; 32]``` in serialized form. + +## Algorithm +### Signature generation +The user generates a Keypair which is a combination of a Private key and a Public key. +The private key 'a' is generated from a Cryptographically secure pseudo-random generator and is a scalar see [RFC4086](https://datatracker.ietf.org/doc/html/rfc4086) + +The scalar is multiplied by the Curves basepoint 'B' to give the publickey. + +```A = a.B``` + +To generate a signature of a message M, the user first has to generate a random number 'r' and multiply it with the basepoint B resulting in R. +```R = r.B``` + +Then a hash is generated using SHA-512 algorithm and a scalar 'k' is generated from the hash according to RFC-8032 +k <- H(R, A, M) + +To generate the final signature 'f', the algorithm computes this ```s = r + k``` and appends it with R to form a fixed signature of 64 bits which is a ```[u8; 64]```in serialized form. + +### Verification +The protocol follows a variation in the implementation from the RFC8032 fixing some vulnerabilities caused due to point malleabilities. +As mentioned above, we use the unbatched equation for signature verification given by: +```R = [s]B - [k]A``` +Due to the malleabilities found in signatures, the library implements a ```verify_strict``` function which checks for both scalar and elliptic curve point validity i.e. whether or not they're of canonical form. + + ### Algorithm: For any honestly generated R the following procedure holds + ``` + [s]B−[k]A = [r+k.a]B−[k]A + = [r]B+[k]([a]B)−[k]A + = R+[k]A−[k]A + = R + + ``` +## Security + ++ The random number generator for generating private keys is cryptographically secure. ++ This version of verification is technically non-RFC8032 compliant due to several scalar and curve point malleabilities that were initially + ignored in the RFC which produce inconsistent signatures and hence require different verification methods based on the implementation. ++ Despite the variations in verification of ed25519 signatures as discussed in this [blog post](https://hdevalence.ca/blog/2020-10-04-its-25519am), + the dalek implementation checks for consistency in R when doing the computation mentioned in the above section. ++ Discrete log is a hard problem in the finite field of Curve25519 so factoring of private keys takes exponential time as of Jan 2023 ++ No practical collisions of SHA-512 are known as of Jan 2023.