Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Dmitry Baryshkov
nettle
Commits
4ebc67a7
Commit
4ebc67a7
authored
Jan 10, 2016
by
Niels Möller
Browse files
RSA documentation update.
parent
d78467e1
Changes
2
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
4ebc67a7
2016-01-10 Niels Möller <nisse@lysator.liu.se>
* nettle.texinfo (RSA): Document the rsa_pkcs1_verify and
rsa_pkcs1_sign functions, and the new rsa_*_tr functions.
2015-12-18 Niels Möller <nisse@lysator.liu.se>
* testsuite/testutils.h: Fix include order, system headers before
...
...
nettle.texinfo
View file @
4ebc67a7
...
...
@@ -3537,7 +3537,7 @@ F(x) = x^e mod n
I.e. raise x to the @code
{
e
}
'th power, while discarding all multiples of
@code
{
n
}
. The pair of numbers @code
{
n
}
and @code
{
e
}
is the public key.
@code
{
e
}
can be quite small, even @code
{
e = 3
}
has been used, although
slightly larger numbers are recommended. @code
{
n
}
should be about
1
000
slightly larger numbers are recommended. @code
{
n
}
should be about
2
000
bits or larger.
If @code
{
n
}
is large enough, and properly chosen, the inverse of F,
...
...
@@ -3546,8 +3546,8 @@ But, where's the trapdoor?
Let's first look at how @acronym
{
RSA
}
key-pairs are generated. First
@code
{
n
}
is chosen as the product of two large prime numbers @code
{
p
}
and @code
{
q
}
of roughly the same size (so if @code
{
n
}
is
1
000 bits,
@code
{
p
}
and @code
{
q
}
are about
5
00 bits each). One also computes the
and @code
{
q
}
of roughly the same size (so if @code
{
n
}
is
2
000 bits,
@code
{
p
}
and @code
{
q
}
are about
10
00 bits each). One also computes the
number @code
{
phi = (p-1)(q-1)
}
, in mathematical speak, @code
{
phi
}
is the
order of the multiplicative group of integers modulo n.
...
...
@@ -3591,6 +3591,16 @@ from the message in the same way as above. Then @code{s^e mod n} is
computed, the operation returns true if and only if the result equals
@code
{
x
}
.
The @acronym
{
RSA
}
algorithm can also be used for encryption. RSA encryption uses
the public key @code
{
(n,e)
}
to compute the ciphertext @code
{
m
^
e mod n
}
.
The @cite
{
PKCS#1
}
padding scheme will use at least 8 random and non-zero
octets, using @var
{
m
}
of the form @code
{
[00 02 padding 00 plaintext]
}
.
It is required that @code
{
m < n
}
, and therefor the plaintext must be
smaller than the octet size of the modulo @code
{
n
}
, with some margin.
To decrypt the message, one needs the private key to compute @code
{
m =
c
^
e mod n
}
followed by checking and removing the padding.
@subsubsection Nettle's @acronym
{
RSA
}
support
Nettle represents @acronym
{
RSA
}
keys using two structures that contain
...
...
@@ -3641,17 +3651,60 @@ zero if the key can't be used, for instance if the modulo is smaller
than the minimum size needed for @acronym
{
RSA
}
operations specified by PKCS#1.
@end deftypefun
For each operation using the private key, there are two variants, e.g.,
@code
{
rsa
_
sha256
_
sign
}
and @code
{
rsa
_
sha256
_
sign
_
tr
}
. The former
function is older, and it should be avoided, because it provides no
defenses against side-channel attacks. The latter function use
randomized @acronym
{
RSA
}
blinding, which defends against timing attacks
using chosen-ciphertext, and it also checks the correctness of the
private key computation using the public key, which defends against
software or hardware errors which could leak the private key.
Before signing or verifying a message, you first hash it with the
appropriate hash function. You pass the hash function's context struct
to the @acronym
{
RSA
}
signature function, and it will extract the message
digest and do the rest of the work. There are also alternative functions
that take the hash digest as argument.
that take the hash digest as argument.
There is currently no support for using SHA224 or SHA384 with
@acronym
{
RSA
}
signatures, since there's no gain in either computation
time nor message size compared to using SHA256 and SHA512, respectively.
Creation and verification of signatures is done with the following functions:
Creating an @acronym
{
RSA
}
signature is done with one of the following
functions:
@deftypefun int rsa
_
md5
_
sign
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, struct md5
_
ctx *@var
{
hash
}
, mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha1
_
sign
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, struct sha1
_
ctx *@var
{
hash
}
, mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha256
_
sign
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, struct sha256
_
ctx *@var
{
hash
}
, mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha512
_
sign
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, struct sha512
_
ctx *@var
{
hash
}
, mpz
_
t @var
{
signature
}
)
The signature is stored in @var
{
signature
}
(which must have been
@code
{
mpz
_
init
}
'ed earlier). The hash context is reset so that it can be
used for new messages. The @var
{
random
_
ctx
}
and @var
{
random
}
pointers
are used to generate the @acronym
{
RSA
}
blinding. Returns one on success,
or zero on failure. Signing fails if an error in the computation was
detected, or if the key is too small for the given hash size, e.g., it's
not possible to create a signature using SHA512 and a 512-bit
@acronym
{
RSA
}
key.
@end deftypefun
@deftypefun int rsa
_
md5
_
sign
_
digest
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, const uint8
_
t *@var
{
digest
}
, mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha1
_
sign
_
digest
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, const uint8
_
t *@var
{
digest
}
, mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha256
_
sign
_
digest
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, const uint8
_
t *@var
{
digest
}
, mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha512
_
sign
_
digest
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, const uint8
_
t *@var
{
digest
}
, mpz
_
t @var
{
signature
}
)
Creates a signature from the given hash digest. @var
{
digest
}
should
point to a digest of size @code
{
MD5
_
DIGEST
_
SIZE
}
,
@code
{
SHA1
_
DIGEST
_
SIZE
}
, @code
{
SHA256
_
DIGEST
_
SIZE
}
, or
@code
{
SHA512
_
DIGEST
_
SIZE
}
respectively. The signature is stored in
@var
{
signature
}
(which must have been @code
{
mpz
_
init
}
:ed earlier).
Returns one on success, or zero on failure.
@end deftypefun
@deftypefun int rsa
_
pkcs1
_
sign
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, size
_
t @var
{
length
}
, const uint8
_
t *@var
{
digest
_
info
}
, mpz
_
t @var
{
signature
}
)
Similar to the above @code
{_
sign
_
digest
_
tr
}
functions, but the input is not the
plain hash digest, but a PKCS#1 ``DigestInfo'', an ASN.1 DER-encoding
of the digest together with an object identifier for the used hash
algorithm.
@end deftypefun
@deftypefun int rsa
_
md5
_
sign (const struct rsa
_
private
_
key *@var
{
key
}
, struct md5
_
ctx *@var
{
hash
}
, mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha1
_
sign (const struct rsa
_
private
_
key *@var
{
key
}
, struct sha1
_
ctx *@var
{
hash
}
, mpz
_
t @var
{
signature
}
)
...
...
@@ -3669,13 +3722,23 @@ it's not possible to create a signature using SHA512 and a 512-bit
@deftypefunx int rsa
_
sha1
_
sign
_
digest (const struct rsa
_
private
_
key *@var
{
key
}
, const uint8
_
t *@var
{
digest
}
, mpz
_
t @var
{
signature
}
);
@deftypefunx int rsa
_
sha256
_
sign
_
digest (const struct rsa
_
private
_
key *@var
{
key
}
, const uint8
_
t *@var
{
digest
}
, mpz
_
t @var
{
signature
}
);
@deftypefunx int rsa
_
sha512
_
sign
_
digest (const struct rsa
_
private
_
key *@var
{
key
}
, const uint8
_
t *@var
{
digest
}
, mpz
_
t @var
{
signature
}
);
Creates a signature from the given hash digest. @var
{
digest
}
should
point to a digest of size @code
{
MD5
_
DIGEST
_
SIZE
}
,
@code
{
SHA1
_
DIGEST
_
SIZE
}
, or @code
{
SHA256
_
DIGEST
_
SIZE
}
, respectively. The
signature is stored in @var
{
signature
}
(which must have been
Creates a signature from the given hash digest; otherwise analoguous to
the above signing functions. @var
{
digest
}
should point to a digest of
size @code
{
MD5
_
DIGEST
_
SIZE
}
, @code
{
SHA1
_
DIGEST
_
SIZE
}
,
@code
{
SHA256
_
DIGEST
_
SIZE
}
, or @code
{
SHA512
_
DIGEST
_
SIZE
}
, respectively.
The signature is stored in @var
{
signature
}
(which must have been
@code
{
mpz
_
init
}
:ed earlier). Returns one on success, or zero on failure.
@end deftypefun
@deftypefun int rsa
_
pkcs1
_
sign(const struct rsa
_
private
_
key *@var
{
key
}
, size
_
t @var
{
length
}
, const uint8
_
t *@var
{
digest
_
info
}
, mpz
_
t @var
{
s
}
)
Similar to the above
_
sign
_
digest functions, but the input is not the
plain hash digest, but a PKCS#1 ``DigestInfo'', an ASN.1 DER-encoding
of the digest together with an object identifier for the used hash
algorithm.
@end deftypefun
Verifying an RSA signature is done with one of the following functions:
@deftypefun int rsa
_
md5
_
verify (const struct rsa
_
public
_
key *@var
{
key
}
, struct md5
_
ctx *@var
{
hash
}
, const mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha1
_
verify (const struct rsa
_
public
_
key *@var
{
key
}
, struct sha1
_
ctx *@var
{
hash
}
, const mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha256
_
verify (const struct rsa
_
public
_
key *@var
{
key
}
, struct sha256
_
ctx *@var
{
hash
}
, const mpz
_
t @var
{
signature
}
)
...
...
@@ -3688,17 +3751,18 @@ the hash context is reset so that it can be used for new messages.
@deftypefunx int rsa
_
sha1
_
verify
_
digest (const struct rsa
_
public
_
key *@var
{
key
}
, const uint8
_
t *@var
{
digest
}
, const mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha256
_
verify
_
digest (const struct rsa
_
public
_
key *@var
{
key
}
, const uint8
_
t *@var
{
digest
}
, const mpz
_
t @var
{
signature
}
)
@deftypefunx int rsa
_
sha512
_
verify
_
digest (const struct rsa
_
public
_
key *@var
{
key
}
, const uint8
_
t *@var
{
digest
}
, const mpz
_
t @var
{
signature
}
)
Returns 1 if the signature is valid, or 0 if it isn't. @var
{
digest
}
should
point to a digest of size @code
{
MD5
_
DIGEST
_
SIZE
}
,
@code
{
SHA1
_
DIGEST
_
SIZE
}
, or @code
{
SHA256
_
DIGEST
_
SIZE
}
, respectively.
Returns 1 if the signature is valid, or 0 if it isn't. @var
{
digest
}
should point to a digest of size @code
{
MD5
_
DIGEST
_
SIZE
}
,
@code
{
SHA1
_
DIGEST
_
SIZE
}
, @code
{
SHA256
_
DIGEST
_
SIZE
}
, or
@code
{
SHA512
_
DIGEST
_
SIZE
}
respectively.
@end deftypefun
The RSA algorithm can also be used for encryption. RSA encryption uses
the public key @code
{
(n,e)
}
to comp
ut
e
the
ciphertext @code
{
m
^
e mod n
}
.
The PKCS#1 padding scheme will use at least 8 random and non-zero
o
ctets, using @var
{
m
}
of the form @code
{
[00 02 padding 00 plaintext]
}
.
It is required that @code
{
m < n
}
, and theref
or
th
e plaintext must be
smaller than the octet size of the modulo @code
{
n
}
, with some margin.
@deftypefun int rsa
_
pkcs1
_
verify(const struct rsa
_
public
_
key *@var
{
key
}
, size
_
t @var
{
length
}
, const uint8
_
t *@var
{
digest
_
info
}
, const mpz
_
t @var
{
signature
}
)
Similar to the above
_
verify
_
digest functions, b
ut the
input is not the
plain hash digest, but a PKCS#1 ``DigestInfo'', and ASN.1 DER-encoding
o
f the digest together with an object identifier for the used hash
alg
or
i
th
m.
@end deftypefun
The following function is used to encrypt a clear text message using RSA.
@deftypefun int rsa
_
encrypt (const struct rsa
_
public
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, size
_
t @var
{
length
}
, const uint8
_
t *@var
{
cleartext
}
, mpz
_
t @var
{
ciphertext
}
)
...
...
@@ -3724,8 +3788,13 @@ that isn't supported by the above functions Nettle also includes a
function that computes @code
{
x
^
d mod n
}
and nothing more, using the
@acronym
{
CRT
}
optimization.
@deftypefun int rsa
_
compute
_
root
_
tr(const struct rsa
_
public
_
key *@var
{
pub
}
, const struct rsa
_
private
_
key *@var
{
key
}
, void *@var
{
random
_
ctx
}
, nettle
_
random
_
func *@var
{
random
}
, mpz
_
t @var
{
x
}
, const mpz
_
t @var
{
m
}
)
Computes @code
{
x = m
^
d
}
. Returns one on success, or zero if a failure in
the computation was detected.
@end deftypefun
@deftypefun void rsa
_
compute
_
root (struct rsa
_
private
_
key *@var
{
key
}
, mpz
_
t @var
{
x
}
, const mpz
_
t @var
{
m
}
)
Computes @code
{
x = m
^
d
}
, efficiently
.
Computes @code
{
x = m
^
d
}
.
@end deftypefun
At last, how do you create new keys?
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment