red25519 1.1.0-jruby
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/.rspec +4 -0
- data/.travis.yml +14 -0
- data/CHANGES.md +3 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +140 -0
- data/Rakefile +9 -0
- data/ed25519.png +0 -0
- data/ext/red25519/api.h +4 -0
- data/ext/red25519/crypto_int32.h +6 -0
- data/ext/red25519/crypto_sign.h +13 -0
- data/ext/red25519/crypto_uint32.h +6 -0
- data/ext/red25519/crypto_verify_32.h +7 -0
- data/ext/red25519/ed25519.c +136 -0
- data/ext/red25519/extconf.rb +4 -0
- data/ext/red25519/fe25519.c +326 -0
- data/ext/red25519/fe25519.h +63 -0
- data/ext/red25519/ge25519.c +311 -0
- data/ext/red25519/ge25519.h +35 -0
- data/ext/red25519/ge25519_base.data +850 -0
- data/ext/red25519/org/red25519/ed25519.java +228 -0
- data/ext/red25519/red25519_engine.c +82 -0
- data/ext/red25519/sc25519.c +298 -0
- data/ext/red25519/sc25519.h +73 -0
- data/ext/red25519/sha512-blocks.c +239 -0
- data/ext/red25519/sha512-hash.c +72 -0
- data/ext/red25519/sha512.h +4 -0
- data/ext/red25519/verify.c +40 -0
- data/lib/red25519/jruby_engine.rb +27 -0
- data/lib/red25519/keys.rb +73 -0
- data/lib/red25519/version.rb +3 -0
- data/lib/red25519.rb +41 -0
- data/lib/red25519_engine.jar +0 -0
- data/red25519.gemspec +31 -0
- data/spec/red25519/engine_spec.rb +33 -0
- data/spec/red25519/keys_spec.rb +65 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/extension.rake +12 -0
- data/tasks/rspec.rake +7 -0
- metadata +134 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGES.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Tony Arcieri
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
Red25519
|
2
|
+
========
|
3
|
+
[](http://travis-ci.org/tarcieri/red25519)
|
4
|
+
|
5
|
+
Red25519 provides a Ruby binding to the Ed25519 public-key signature system
|
6
|
+
based on elliptic curves and created by Dan Bernstein et al. Two
|
7
|
+
implementations are provided: a MRI C extension which uses the "ref"
|
8
|
+
implementation from the SUPERCOP benchmark suite, and a pure Java version
|
9
|
+
which is a direct port of the Python implementation.
|
10
|
+
|
11
|
+
Ed25519 provides a 128-bit security level, that is to say, all known attacks
|
12
|
+
take at least 2^128 operations, providing the same security level as AES-128,
|
13
|
+
NIST P-256, and RSA-3072.
|
14
|
+
|
15
|
+

|
16
|
+
|
17
|
+
Ed25519 has a number of unique properties that make it one of the best-in-class
|
18
|
+
digital signature algorithms:
|
19
|
+
|
20
|
+
* ***Small keys***: Ed25519 keys are only 256-bits (32 bytes), making them
|
21
|
+
small enough to easily copy around. Ed25519 also allows the public key
|
22
|
+
to be derived from the private key, meaning that it doesn't need to be
|
23
|
+
included in a serialized private key in cases you want both.
|
24
|
+
* ***Small signatures***: Ed25519 signatures are only 512-bits (64 bytes),
|
25
|
+
one of the smallest signature sizes available.
|
26
|
+
* ***Deterministic***: Unlike (EC)DSA, Ed25519 does not rely on an entropy
|
27
|
+
source when signing messages. This can be a potential attack vector if
|
28
|
+
the entropy source is not generating good random numbers. Ed25519 avoids
|
29
|
+
this problem entirely and will always generate the same signature for the
|
30
|
+
same data.
|
31
|
+
* ***Collision Resistant***: Hash-function collisions do not break this
|
32
|
+
system. This adds a layer of defense against the possibility of weakness
|
33
|
+
in the selected hash function.
|
34
|
+
|
35
|
+
You can read more on [Dan Bernstein's Ed25519 site](http://ed25519.cr.yp.to/).
|
36
|
+
|
37
|
+
Installation
|
38
|
+
------------
|
39
|
+
|
40
|
+
Add this line to your application's Gemfile:
|
41
|
+
|
42
|
+
gem 'red25519'
|
43
|
+
|
44
|
+
And then execute:
|
45
|
+
|
46
|
+
$ bundle
|
47
|
+
|
48
|
+
Or install it yourself as:
|
49
|
+
|
50
|
+
$ gem install red25519
|
51
|
+
|
52
|
+
Usage
|
53
|
+
-----
|
54
|
+
|
55
|
+
Require red25519 in your Ruby program:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
require 'red25519'
|
59
|
+
```
|
60
|
+
|
61
|
+
Generate a new random signing key:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
signing_key = Ed25519::SigningKey.generate
|
65
|
+
```
|
66
|
+
|
67
|
+
Sign a message with the signing key:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
signature = signing_key.sign(message)
|
71
|
+
```
|
72
|
+
|
73
|
+
Obtain the verify key for a given signing key:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
verify_key = signing_key.verify_key
|
77
|
+
```
|
78
|
+
|
79
|
+
Check the validity of a signature:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
verify_key.verify(signature, message)
|
83
|
+
```
|
84
|
+
|
85
|
+
The verify method will return `true` or `false` depending on if the signature matches.
|
86
|
+
|
87
|
+
### Serializing Keys
|
88
|
+
|
89
|
+
Keys can be serialized as 32-byte binary strings as follows:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
signature_key_bytes = signing_key.to_bytes
|
93
|
+
verify_key_bytes = verify_key.to_bytes
|
94
|
+
```
|
95
|
+
|
96
|
+
The binary serialization can be passed directly into the constructor for a given key type:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
signing_key = Ed25519::SigningKey.new(signature_key_bytes)
|
100
|
+
verify_key = Ed25519::VerifyKey.new(verify_key_bytes)
|
101
|
+
```
|
102
|
+
|
103
|
+
You can also serialize keys to a hex string instead of a binary string:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
signing_key_hex = signing_key.to_hex
|
107
|
+
```
|
108
|
+
|
109
|
+
The hex representation can also be passed into the constructor:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
signing_key = Ed25519::SigningKey.new(signing_key_hex)
|
113
|
+
```
|
114
|
+
|
115
|
+
JRuby Notes
|
116
|
+
-----------
|
117
|
+
|
118
|
+
red25519 provides a pure Java backend, however this backend is much slower
|
119
|
+
than the C-based version. While red25519 will function on JRuby, it may be
|
120
|
+
too slow to be usable for a given use case. You should benchmark your
|
121
|
+
application to determine if it will be fast enough for your purposes.
|
122
|
+
|
123
|
+
In the future, red25519 can use an FFI extension to provide better performance
|
124
|
+
on JRuby. Alternatively, red25519 can be abandoned for a more comprehensive
|
125
|
+
FFI binding to Dan Bernstein's NaCl library, which will soon incorporate
|
126
|
+
the SUPERCOP implementation of Ed25519.
|
127
|
+
|
128
|
+
Contributing
|
129
|
+
------------
|
130
|
+
|
131
|
+
* Fork this repository on github
|
132
|
+
* Make your changes and send me a pull request
|
133
|
+
* If I like them I'll merge them
|
134
|
+
* If I've accepted a patch, feel free to ask for commit access
|
135
|
+
|
136
|
+
License
|
137
|
+
-------
|
138
|
+
|
139
|
+
Copyright (c) 2012 Tony Arcieri. Distributed under the MIT License. See
|
140
|
+
LICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rake/clean"
|
4
|
+
|
5
|
+
Dir[File.expand_path("../tasks/**/*.rake", __FILE__)].each { |task| load task }
|
6
|
+
|
7
|
+
task :default => %w(compile spec)
|
8
|
+
|
9
|
+
CLEAN.include "**/*.o", "**/*.so", "**/*.bundle", "**/*.jar", "pkg", "tmp"
|
data/ed25519.png
ADDED
Binary file
|
data/ext/red25519/api.h
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef crypto_sign_edwards25519sha512batch_H
|
2
|
+
#define crypto_sign_edwards25519sha512batch_H
|
3
|
+
|
4
|
+
#define SECRETKEYBYTES 64
|
5
|
+
#define PUBLICKEYBYTES 32
|
6
|
+
#define SIGNATUREBYTES 64
|
7
|
+
|
8
|
+
extern int crypto_sign(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
|
9
|
+
extern int crypto_sign_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
|
10
|
+
extern int crypto_sign_keypair(unsigned char *,unsigned char *);
|
11
|
+
extern int crypto_sign_publickey(unsigned char *pk, unsigned char *sk, unsigned char *seed);
|
12
|
+
|
13
|
+
#endif
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#include "crypto_sign.h"
|
2
|
+
|
3
|
+
#include "crypto_verify_32.h"
|
4
|
+
#include "sha512.h"
|
5
|
+
|
6
|
+
#include "ge25519.h"
|
7
|
+
|
8
|
+
static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
|
9
|
+
{
|
10
|
+
unsigned long long i;
|
11
|
+
|
12
|
+
for (i = 0;i < 32;++i) playground[i] = sm[i];
|
13
|
+
for (i = 32;i < 64;++i) playground[i] = pk[i-32];
|
14
|
+
for (i = 64;i < smlen;++i) playground[i] = sm[i];
|
15
|
+
|
16
|
+
crypto_hash_sha512(hram,playground,smlen);
|
17
|
+
}
|
18
|
+
|
19
|
+
|
20
|
+
int crypto_sign_publickey(
|
21
|
+
unsigned char *pk, // write 32 bytes into this
|
22
|
+
unsigned char *sk, // write 64 bytes into this (seed+pubkey)
|
23
|
+
unsigned char *seed // 32 bytes
|
24
|
+
)
|
25
|
+
{
|
26
|
+
sc25519 scsk;
|
27
|
+
ge25519 gepk;
|
28
|
+
int i;
|
29
|
+
|
30
|
+
crypto_hash_sha512(sk, seed, 32);
|
31
|
+
sk[0] &= 248;
|
32
|
+
sk[31] &= 127;
|
33
|
+
sk[31] |= 64;
|
34
|
+
|
35
|
+
sc25519_from32bytes(&scsk,sk);
|
36
|
+
|
37
|
+
ge25519_scalarmult_base(&gepk, &scsk);
|
38
|
+
ge25519_pack(pk, &gepk);
|
39
|
+
for(i=0;i<32;i++)
|
40
|
+
sk[32 + i] = pk[i];
|
41
|
+
for(i=0;i<32;i++)
|
42
|
+
sk[i] = seed[i];
|
43
|
+
return 0;
|
44
|
+
}
|
45
|
+
|
46
|
+
int crypto_sign(
|
47
|
+
unsigned char *sm,unsigned long long *smlen,
|
48
|
+
const unsigned char *m,unsigned long long mlen,
|
49
|
+
const unsigned char *sk
|
50
|
+
)
|
51
|
+
{
|
52
|
+
sc25519 sck, scs, scsk;
|
53
|
+
ge25519 ger;
|
54
|
+
unsigned char r[32];
|
55
|
+
unsigned char s[32];
|
56
|
+
unsigned char extsk[64];
|
57
|
+
unsigned long long i;
|
58
|
+
unsigned char hmg[crypto_hash_sha512_BYTES];
|
59
|
+
unsigned char hram[crypto_hash_sha512_BYTES];
|
60
|
+
|
61
|
+
crypto_hash_sha512(extsk, sk, 32);
|
62
|
+
extsk[0] &= 248;
|
63
|
+
extsk[31] &= 127;
|
64
|
+
extsk[31] |= 64;
|
65
|
+
|
66
|
+
*smlen = mlen+64;
|
67
|
+
for(i=0;i<mlen;i++)
|
68
|
+
sm[64 + i] = m[i];
|
69
|
+
for(i=0;i<32;i++)
|
70
|
+
sm[32 + i] = extsk[32+i];
|
71
|
+
|
72
|
+
crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */
|
73
|
+
|
74
|
+
/* Computation of R */
|
75
|
+
sc25519_from64bytes(&sck, hmg);
|
76
|
+
ge25519_scalarmult_base(&ger, &sck);
|
77
|
+
ge25519_pack(r, &ger);
|
78
|
+
|
79
|
+
/* Computation of s */
|
80
|
+
for(i=0;i<32;i++)
|
81
|
+
sm[i] = r[i];
|
82
|
+
|
83
|
+
get_hram(hram, sm, sk+32, sm, mlen+64);
|
84
|
+
|
85
|
+
sc25519_from64bytes(&scs, hram);
|
86
|
+
sc25519_from32bytes(&scsk, extsk);
|
87
|
+
sc25519_mul(&scs, &scs, &scsk);
|
88
|
+
|
89
|
+
sc25519_add(&scs, &scs, &sck);
|
90
|
+
|
91
|
+
sc25519_to32bytes(s,&scs); /* cat s */
|
92
|
+
for(i=0;i<32;i++)
|
93
|
+
sm[32 + i] = s[i];
|
94
|
+
|
95
|
+
return 0;
|
96
|
+
}
|
97
|
+
|
98
|
+
int crypto_sign_open(
|
99
|
+
unsigned char *m,unsigned long long *mlen,
|
100
|
+
const unsigned char *sm,unsigned long long smlen,
|
101
|
+
const unsigned char *pk
|
102
|
+
)
|
103
|
+
{
|
104
|
+
int i, ret;
|
105
|
+
unsigned char t2[32];
|
106
|
+
ge25519 get1, get2;
|
107
|
+
sc25519 schram, scs;
|
108
|
+
unsigned char hram[crypto_hash_sha512_BYTES];
|
109
|
+
|
110
|
+
if (ge25519_unpackneg_vartime(&get1, pk)) return -1;
|
111
|
+
|
112
|
+
get_hram(hram,sm,pk,m,smlen);
|
113
|
+
|
114
|
+
sc25519_from64bytes(&schram, hram);
|
115
|
+
|
116
|
+
sc25519_from32bytes(&scs, sm+32);
|
117
|
+
|
118
|
+
ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
|
119
|
+
ge25519_pack(t2, &get2);
|
120
|
+
|
121
|
+
ret = crypto_verify_32(sm, t2);
|
122
|
+
|
123
|
+
if (!ret)
|
124
|
+
{
|
125
|
+
for(i=0;i<smlen-64;i++)
|
126
|
+
m[i] = sm[i + 64];
|
127
|
+
*mlen = smlen-64;
|
128
|
+
}
|
129
|
+
else
|
130
|
+
{
|
131
|
+
for(i=0;i<smlen-64;i++)
|
132
|
+
m[i] = 0;
|
133
|
+
*mlen = (unsigned long long) -1;
|
134
|
+
}
|
135
|
+
return ret;
|
136
|
+
}
|