Giter VIP home page Giter VIP logo

ruby_ecdsa's Introduction

ECDSA gem for Ruby

Build Status

This gem implements the Elliptic Curve Digital Signature Algorithm (ECDSA) almost entirely in pure Ruby. It aims to be easier to use and easier to understand than Ruby's OpenSSL EC support. This gem does use OpenSSL but it only uses it to decode and encode ASN1 strings for ECDSA signatures. All cryptographic calculations are done in pure Ruby.

The main classes of this gem are ECDSA::Group, ECDSA::Point, and ECDSA::Signature. These classes operate on Ruby integers and do not deal at all with binary formatting. Encoding and decoding of binary formats is solely handled by classes under the ECDSA::Format module.

You can enter your own curve parameters by instantiating a new ECDSA::Group object or you can use a pre-existing group object such as ECDSA::Group::Secp256k1. The pre-existing groups can be seen in the lib/ecdsa/group folder, and include all the curves defined in SEC2 and NIST's Recommended Elliptic Curves for Federal Government Use.

This gem does not use any randomness; all the algorithms are deterministic. In order to sign a message, you must generate a secure random number k between 0 and the order of the group and pass it as an argument to ECDSA.sign. You should take measures to ensure that you never use the same random number to sign two different messages, or else it would be easy for someone to compute your private key from those two signatures.

This gem is hosted at the DavidEGrayson/ruby_ecdsa github repository.

Current limitations

  • This gem only supports fields of integers modulo a prime number (Fp). ECDSA's characteristic 2 fields are not supported.
  • The algorithms have not been optimized for speed, and will probably never be, because that would hinder the goal of helping people understand ECDSA.

This gem was not written by a cryptography expert and has not been carefully checked. It is provided "as is" and it is the user's responsibility to make sure it will be suitable for the desired purpose.

Installation

This library is distributed as a gem named ecdsa at RubyGems.org. To install it, run:

gem install ecdsa

Generating a private key

An ECDSA private key is a random number between 1 and the order of the group. If you trust the SecureRandom class provided by your Ruby implementation, you could generate a private key using this code:

require 'ecdsa'
require 'securerandom'
group = ECDSA::Group::Secp256k1
private_key = 1 + SecureRandom.random_number(group.order - 1)
puts 'private key: %#x' % private_key

Computing the public key for a private key

The public key consists of the coordinates of the point that is computed by multiplying the generator point of the curve with the private key. This is equivalent to adding the generator to itself private_key times.

public_key = group.generator.multiply_by_scalar(private_key)
puts 'public key: '
puts '  x: %#x' % public_key.x
puts '  y: %#x' % public_key.y

The public_key object produced by the code above is an ECDSA::Point object.

Encoding a public key as a binary string

Assuming that you have an ECDSA::Point object representing the public key, you can convert it to the standard binary format defined in SEC1 with this code:

public_key_string = ECDSA::Format::PointOctetString.encode(public_key, compression: true)

Setting the compression option to true decreases the size of the string by almost 50% by only including one bit of the Y coordinate. The other bits of the Y coordinate are deduced from the X coordinate when the string is decoded.

This code returns a binary string.

Decoding a public key from a binary string

To decode a SEC1 octet string, you can use the code below. The group object is assumed to be an ECDSA::Group.

public_key = ECDSA::Format::PointOctetString.decode(public_key_string, group)

Signing a message

This example shows how to generate a signature for a message. In this example, we will use SHA2 as our digest algorithm, but other algorithms can be used.

This example assumes that you trust the SecureRandom class in your Ruby implementation to generate the temporary key (also known as k). Beware that if you accidentally sign two different messages with the same temporary key, it is easy for someone to compute your private key from those two signatures and then forge your signature. Also, if someone can correctly guess the value of the temporary key used for a signature, they can compute your private key from that signature.

This example assumes that you have required the ecdsa gem, that you have an ECDSA::Group object named group, and that you have the private key stored as an integer in a variable named private_key.

require 'digest/sha2'
message = 'ECDSA is cool.'
digest = Digest::SHA2.digest(message)
signature = nil
while signature.nil?
  temp_key = 1 + SecureRandom.random_number(group.order - 1)
  signature = ECDSA.sign(group, private_key, digest, temp_key)
end
puts 'signature: '
puts '  r: %#x' % signature.r
puts '  s: %#x' % signature.s

Encoding a signature as a DER string

Signatures can be stored and transmitted as a DER string. The code below encodes an ECDSA::Signature object as a binary DER string.

signature_der_string = ECDSA::Format::SignatureDerString.encode(signature)

Decoding a signature from a DER string

The code below decodes a binary DER string to produce an ECDSA::Signature object.

signature = ECDSA::Format::SignatureDerString.decode(signature_der_string)

Verifying a signature

The code below shows how to verify an ECDSA signature. It assumes that you have an ECDSA::Point object representing a public key, a string or integer representing the digest of the signed messaged, and an ECDSA::Signature object representing the signature. The valid_signature? method returns true if the signature is valid and false if it is not.

valid = ECDSA.valid_signature?(public_key, digest, signature)
puts "valid: #{valid}"

Supported platforms

This library should run on any Ruby interpreter that is compatible with Ruby 1.9.3. It has been tested on JRuby 1.7.11 and MRI.

Documentation

For complete documentation, see the ECDSA page on RubyDoc.info.

ruby_ecdsa's People

Contributors

davidegrayson avatar jamoes avatar sanemat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby_ecdsa's Issues

Slow Performance...

I am using the function pub_key = curve.generator.multiply_by_scalar(key) but I am noticing that for high scalars the performance of the function drops significantly.
Example is that if I load the last 100 records of the private key spectrum it takes 30 seconds to load the page on my computer instead of the 50ms compared with the first 100 records of the private key spectrum. Is there anything I can do? If not can you please let me know how can I switch this to an Openssl solution? thanks

are the y-points correct? problems validating ietf-cose-msg examples

Background: I am writing some code to implement the IETF COSE specification (here: https://datatracker.ietf.org/doc/draft-ietf-cose-msg/ about to be RFC). The examples from Jim are at: https://github.com/cose-wg/Examples . I am actually implementing a CWT library in ruby ( https://datatracker.ietf.org/doc/draft-ietf-ace-cbor-web-token/ ) for use in the ANIMA and 6tisch WG, if you care.
My code, which is still a skeletal mess at: [email protected]:mcr/ChariWTs.git is just trying to use the ecdsa libraries to validate the examples. There are a few challenges here, which you can read more about at: cose-wg/Examples#79

So I took the two ecdsa examples: https://github.com/cose-wg/Examples/blob/master/ecdsa-examples/ecdsa-sig-01.json and https://github.com/cose-wg/Examples/blob/master/ecdsa-examples/ecdsa-sig-02.json
and I did ran some really simple ruby code to re-derive the x/y coordinates (the public key) from the d value presented:

2.3.0 :004 > load 'check1.rb'
derived x: 84479481090508879236361810314595438639920637850206250382769291656310074416895 
       vs: 84479481090508879236361810314595438639920637850206250382769291656310074416895
derived y: 14508547282523033594077281899984253063221771617900828323772342424228169781630 
       vs: 221382765198319077083920120796396551052321440967416757858684904626210296

Here is the shortest code: https://gist.github.com/mcr/b1c9dd9cfcab249e73200d0d056ac0da to attempt to validate this. That the X matches is surprising if there is numerically wrong. My hunch is that there is some problem with Jim's examples that is corrupting the Y value coming out.

How to read from PEM file to sign ECDSA

I have private key in pem format.
I want to sign with following code.

signature = ECDSA.sign($group, $private_key, digest, temp_key)
I want to know is how to read from pem file.

Broken links to secg.org

In issue #10, @mcr pointed out that some of my links to secg.org are broken.

http://www.secg.org/collateral/sec1_final.pdf
This is supposed to go to a document called "SEC 1: Elliptic Curve Cryptography" dated 2000-09-20, with version number 1.0 and a SHA256 hash of abe38d818c470d3e5a57e991e2ae410cbe0608fd0f191ed8788d0401e7d6c616. There is a new document from the same domain with version number 2.0, but I have not read it carefully enough to know if all the broken links can be updated to it.

http://www.secg.org/collateral/sec2_final.pdf
This is supposed to go to a document called "SEC 2: Recommended Elliptic Curve Domain Parameters" dated 2000-09-20, with version number 1.0 and a SHA256 hash of d1b16728ad83888fd656d16b99dc71bcd5541d42d848ffd0de7c62c19010d8c3. There is a new document with version number 2.0 from the same domain, but it is not a suitable replacement for version 1.0 because it removes several curves.

I'll go ahead and attach the original documents (that I seem to have downloaded on 2017-05-19) to this issue. Thanks for the free file storage, GitHub!

sec1_final.pdf
sec2_final.pdf

NIST vs SECP

 nistp256.rb             
 secp256r1.rb   

As far as I can verify, these are two names for the same group.
Ditto for the 192 and 521.
http://www.secg.org/collateral/

no longer answers, being directed to certicom's web site. I wonder if it wouldn't be better to just have one or the other in the source code base?

The binary decode methods should not be sensitive to the string encoding

In Ruby 2.0, the default encoding of source files, and hence the string literals inside them, is UTF-8. If you aren't careful you get weird errors about the length being wrong when passing a string into ruby_ecdsa, and you have to write # coding: ASCII-8BIT at the top of your file to prevent it. We should fix any encoding issues when binary strings are entering the gem, or else deal with the strings in a way that does not depend on the encoding, which is meaningless for strings holding binary data.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.