2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../core/juce_StandardHeader.h"
30 #include "juce_RSAKey.h"
31 #include "juce_Primes.h"
34 //==============================================================================
39 RSAKey::RSAKey (const String
& s
)
41 if (s
.containsChar (','))
43 part1
.parseString (s
.upToFirstOccurrenceOf (",", false, false), 16);
44 part2
.parseString (s
.fromFirstOccurrenceOf (",", false, false), 16);
48 // the string needs to be two hex numbers, comma-separated..
57 bool RSAKey::operator== (const RSAKey
& other
) const noexcept
59 return part1
== other
.part1
&& part2
== other
.part2
;
62 bool RSAKey::operator!= (const RSAKey
& other
) const noexcept
64 return ! operator== (other
);
67 String
RSAKey::toString() const
69 return part1
.toString (16) + "," + part2
.toString (16);
72 bool RSAKey::applyToValue (BigInteger
& value
) const
74 if (part1
.isZero() || part2
.isZero() || value
<= 0)
76 jassertfalse
; // using an uninitialised key
83 while (! value
.isZero())
88 value
.divideBy (part2
, remainder
);
90 remainder
.exponentModulo (part1
, part2
);
95 value
.swapWith (result
);
99 BigInteger
RSAKey::findBestCommonDivisor (const BigInteger
& p
, const BigInteger
& q
)
101 // try 3, 5, 9, 17, etc first because these only contain 2 bits and so
102 // are fast to divide + multiply
103 for (int i
= 2; i
<= 65536; i
*= 2)
105 const BigInteger
e (1 + i
);
107 if (e
.findGreatestCommonDivisor (p
).isOne() && e
.findGreatestCommonDivisor (q
).isOne())
113 while (! (e
.findGreatestCommonDivisor (p
).isOne() && e
.findGreatestCommonDivisor (q
).isOne()))
119 void RSAKey::createKeyPair (RSAKey
& publicKey
, RSAKey
& privateKey
,
120 const int numBits
, const int* randomSeeds
, const int numRandomSeeds
)
122 jassert (numBits
> 16); // not much point using less than this..
123 jassert (numRandomSeeds
== 0 || numRandomSeeds
>= 2); // you need to provide plenty of seeds here!
125 BigInteger
p (Primes::createProbablePrime (numBits
/ 2, 30, randomSeeds
, numRandomSeeds
/ 2));
126 BigInteger
q (Primes::createProbablePrime (numBits
- numBits
/ 2, 30, randomSeeds
== nullptr ? 0 : (randomSeeds
+ numRandomSeeds
/ 2), numRandomSeeds
- numRandomSeeds
/ 2));
128 const BigInteger
n (p
* q
);
129 const BigInteger
m (--p
* --q
);
130 const BigInteger
e (findBestCommonDivisor (p
, q
));
138 privateKey
.part1
= d
;
139 privateKey
.part2
= n
;