How to determine the full private key(d) of RSA from partially exposed private key, public key, and a plain text-cipher sample? - rsa

To be exact, I search google and couldn't find a solution for 3 days of the problem I am working with. Suppose we have the following data:
n = 982596486168164533679068138587450785169755353624059289415533430269902156543301980948452346231423154225707198230814993348325199962226568104628565333075845055110102001513777733822186085910101000971046266247429174698114691926560611342709382763139596083197537103114770536908672391590105944592251557906143423217780862508367523890586749066935355289953519893896713070059149756252671523659055578969907046141090712181640128224480409352033671783234281312447922211039322683639827785375953048086752423328929034805397916713370525669627143719501631537708814980908413840526128966499935897121680247985318025315384432533966964970611
e = 775190819167897631176142663411710999205806087066006443944461953857164338723429823393075674707262963522955617554826880616304988501826679958870898278895792058663197079023581172699525499730454631775015710961671445041794828644629497864625721929989036131201919514003587819878166711621561908547096468667207449797364848789764697856316618498498262452131344181751100590894300580042093702563188859707307216778764928603993071688639278368716846438563956083192844147422032192904730022839373187650224028121273760154048735208506631714555638879414307491200334008651297901472141550888866381591119048114628581521511748434670177461179
partial_d = '-95565380254798212446005426258216042596447135211594111758298376905772484520767625755935413800669744238121798572594037451626724012931827766106358351478966798584005019009384238898207884272864530665811386839587882471633582853938828186423489977-9459392793578-40967083934080473816647050888832190567572370521068219500490996231305841427576808669937665219704595531248268617-5599327544524071502796886348357733378359580273401775-675875610000035372696866273647137752244631988192623168740165719-026394435253643-803573379032337236455340563330139187876245576753031434070779821311882343039420232356-695651945321825753034064267619'
# Where '-' indicated that there is a missing digit. ( 8 digits to be exact)
# 1 sample
plaintext = 174596092887654220987999701151903265828974992233780278786639791235060519357446652195813
cipher = 260977107293095133032309663678665608543832656460900996720257468374788017140947614258160916323627264388927881981964653682851857258414365923694922215834257866016746133459164584766333741801333836289264940490770115570246717428812182110996286021561959704431405293135763955578136678340591578529145822533102991723988404068808248644828190915120779197049355084277184754391753499206475581581888976149876298335630332113681471472312538242128023259706503821080332553580167351146645606566285812912942045955359708168832979660560414335437348485330250971110555548644448362107391181731840051573148892882755700853070019719373415171351
How do I get the full private key?

Related

Generate strong password from a Big Integer

I have a big integer in javascript, having 128 single digit numbers. I generated this big integer from the hex sum of SHA3-512.
I would like to derive a password from this big integer, following the rules for a strong pasword:
At least 8 characters long
Has capital letters
Has small letters
Has numbers
Has special characters
Now, I would like to generate a password of at least 20 characters from this big integer. How can I do that? I would like to make this function so that whenever I pass the same big integer, it gives me the same password everytime (just like hashing algorithms).
So you have this huge number X in the range [0, 2^512). Surely you can get a password from it, and you can use something like base conversion.
What you first want to do is to create a range for each character position starting from 0, which could e.g. be the character A, say [0, Mi) where M is the amount of characters and i is the index in the password. The number of characters at a certain position is called an alphabet (the English ABC is one specific alphabet, usually called the alphabet).
Now if you create the product over all the Mi, giving you the value N. Now you get the remainder of X over N, let's call this Y. Now you have a number that is reasonably unbiased as long as 2^512 is much larger than N. It and represents all of the passwords possible by index. Nice, but how do you get a password by index, you cannot list them all.
This is where we need to do some more number magic. What you do need to do is to calculate the remainder of Y over Mi, then divide Y by Mi, giving you Ci. You then lookup character Ci within the alphabet for position i, and put it into the password string.
Here's an example I created before in Java (sorry, conversion necessary):
import java.math.BigInteger;
import java.security.MessageDigest;
public class CreatePasswordFromLargeRandom {
private static final String ALPHABET_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String ALPHABET_LOWER = "abcdefghijklmnopqrstuvwxyz";
private static final String ALPHABET_UPPERLOWER = ALPHABET_UPPER + ALPHABET_LOWER;
private static final String ALPHABET_DIGITS = "0123456789";
private static final BigInteger SHA512_RANGE = BigInteger.TWO.pow(512);
public static char[] createPassword(BigInteger rangeOfX, BigInteger x, char[]... alphabets) {
// n is the amount of passwords possible
var n = BigInteger.ONE;
for (int i = 0; i < alphabets.length; i++) {
n = n.multiply(BigInteger.valueOf(alphabets[i].length));
}
if (rangeOfX.bitLength() - n.bitLength() < 64) {
throw new IllegalArgumentException("Range of X value too small compared with the number of possible passwords, bias would be introduced");
}
// y is an index into all the possible passwords
var y = x.remainder(n);
var password = new char[alphabets.length];
// using least significant values for digits on the right
for (int i = alphabets.length - 1; i >= 0; i--) {
var yc = y.divideAndRemainder(BigInteger.valueOf(alphabets[i].length));
y = yc[0];
// c is the index in the current alphabet
var c = yc[1].intValueExact();
password[i] = alphabets[i][c];
}
return password;
}
public static void main(String[] args) throws Exception {
var sha512 = MessageDigest.getInstance("SHA-512");
var digest = sha512.digest(new byte[0]);
var x = new BigInteger(1, digest);
var upperLower = ALPHABET_UPPERLOWER.toCharArray();
var digits = ALPHABET_DIGITS.toCharArray();
var password = createPassword(SHA512_RANGE, x, upperLower, digits, upperLower, digits);
System.out.println(new String(password));
}
}
which simply outputs h5g6.
To get an idea how this works: if you input zero for X then you'd get password "A0A0", the password that has the lowest index. You'd get the same value if you'd input K times N for any K, as that will produce the same index. Any X that is N - 1 (mod N) will produce the last password possible, "z9z9" in this case.

Sakai 12 auto truncation of score and rounding

I have install Sakai version 12, I encountered the following problem: The input score for the question was 0.525 but after clicking the Save button the score became 0.53. I tried to reconfigure the sakai.properties file at line gradebook.class.average.decimal.places and assignment.grading.decimals but failed.
I have attached the picture, expect anyone to help me.
Thanks!
Picture 1: http://prntscr.com/j36o75
Picture 2: http://prntscr.com/j36ogy Picture 3: http://prntscr.com/j36on1 Picture 4: http://prntscr.com/j36ork
From your pictures it looks like you're referring to Tests & Quizzes rather than assignment. It looks like T&Q (Samigo) is hardcoded to only be 2 decimal places. From what I can see Gradebook is also hardcoded for individual grade items to be 2 decimal places.
You'd have to submit a feature request on Sakai's Jira or a Pull Request to allow these values to be configured. There may be some loss in precision if too many decimal places are supported.
samigo-app/src/java/org/sakaiproject/tool/assessment/ui/bean/evaluation/TotalScoresBean.java
359: String newmax= ContextUtil.getRoundedValue(maxScore, 2);
samigo-app/src/java/org/sakaiproject/tool/assessment/ui/bean/evaluation/AgentResults.java
241: String newscore = ContextUtil.getRoundedValue(totalAutoScore.replace(',', '.'), 2);
270: String newscore = ContextUtil.getRoundedValue(
296: String newscore = ContextUtil.getRoundedValue(finalScore.replace(',', '.'), 2);
samigo-app/src/java/org/sakaiproject/tool/assessment/ui/bean/delivery/DeliveryBean.java
1253: String newscore= ContextUtil.getRoundedValue(rawScore, 2);
1272: String newscore= ContextUtil.getRoundedValue(rawScore, 2);
samigo-app/src/java/org/sakaiproject/tool/assessment/ui/bean/delivery/DeliveryBeanie.java
382: String newscore= ContextUtil.getRoundedValue(rawScore, 2);
samigo-app/src/java/org/sakaiproject/tool/assessment/ui/listener/util/ContextUtil.java
334: public static String getRoundedValue(String orig, int maxdigit) {
336: return getRoundedValue(origdouble, maxdigit);
338: public static String getRoundedValue(Double orig, int maxdigit) {

How do I convert a 50 digit string into the appropriate integer type in Swift?

I need to convert this 50 digit string 53503534226472524250874054075591789781264330331690 into the appropriate number type. I tried this:
let str = "53503534226472524250874054075591789781264330331690"
let num = str.toInt(); // Returns nil
let num = Int64(str.toInt()); // Errors out
The maximimum size of an Int64 is 9,223,372,036,854,775,807 when it is signed. So you cannot convert it just like that.
You need something like the BigInt class found in other languages. Check this other question where they answer with alternatives about BigInt in Swift:
BigInteger equivalent in Swift?
In summary, there are third-party libraries out there for arbitrary long integers. The only alternative from Apple is NSDecimalNumber but its limit is 38 digits, whereas your number has 50.

Transforming ciphertext from digital format to alphabetic format

Consider a message "STOP" which we are to encrypt using the RSA algorithm. The values given are p = 43, q = 59, n = pq, e = 13. At first I have transformed "STOP" into blocks of 4-bit code which are 1819 (S = 18 and T = 19) and 1415 (O = 14, P = 15) respectively (alphabets are numbered from 00 to 25).
Finally after calculation I have got 20812182 as the encrypted message (after combining 2081 and 2182). Is there any way to transform this digital code of the ciphertext to the alphabet form?
If we start by considering 2 bits, then 20 = U, 81 = ?, 21 = V, 82 = ?,what will be the alphabets for 81 and 82? I mean to ask,what will be the ciphertext for the plaintext "STOP" in the above case?
RSA works with numbers not binary data nor letters. You can of course convert one to another. E.g. this is what you did when you wrote 20812182. The number with that value can have an endless number of other representations.
Now creating an alphabetical representation that has a minimum size is pretty tricky to do. Basically you can divide by powers of 26. This is however not easy to implement. Instead you can take a subset of your alphabet and use that to represent your number.
To do this use your original number representation and replace 0 with A, 1 with B ... and 9 with J. This would result in CAIBCBIC for your ciphertext.
Note that plaintext and ciphertext are used as names for the input and output of cryptographic ciphers. Both names seem to indicate some kind of human readable text - and maybe they once did - but in cryptography they can be thought of as any kind of data.

Is there a simple way to create a unique integer key from a two-integer composite key?

For various reasons that aren't too germane to the question, I've got a table with a composite key made out of two integers and I want to create a single unique key out of those two numbers. My initial thought was to just concatenate them, but I ran into a problem quickly when I realized that a composite key of (51,1) would result in the same unique key as (5,11), namely, 511.
Does anyone have a clever way to generate an integer out of two integers such that the generated integer is unique to the pair of start integers?
Edit: After being confronted with an impressive amount of math, I'm realizing that one detail I should have included is the sizes of the keys in question. In the originating pair, the first key is currently 6 digits and will probably stay in 7 digits for the life of the system; the second key has yet to get larger than 20. Given these constraints, it looks like the problem is much less daunting.
You can mathematically prove this is impossible if you want the resulting key to comprise the same number of bits as its two components. However, if you start with two 32 bit ints, and can use a 64 bit int for the result, you could obviously do something like this:
key1 << 32 | key2
SQL Syntax
SELECT key1 * POWER(2, 32) + key2
This has been discussed in a fair amount of detail already (as recursive said, however, the output must be comprised of more bits than the individual inputs).
Mapping two integers to one, in a unique and deterministic way
How to use two numbers as a Map key
http://en.wikipedia.org/wiki/Cantor_pairing_function#Cantor_pairing_function
Multiply one with a high enough value
SELECT id1 * 1000000 + id2
Or use text concatenation:
SELECT CAST(CAST(id1 AS nvarchar(10)) + RIGHT('000000' + CAST(id2 AS nvarchar(10)), 6) AS int)
Or skip the integer thing and separate the IDs with something non-numeric:
SELECT CAST(id1 AS nvarchar) + ':' + CAST(id2 AS nvarchar)
You can only do it if you have an upper bound for one of the keys. Say you have key1 and key2, and up1 is a value that key1 will never reach, then you can combine the keys like this:
combined = key2 * up1 + key1;
Even if the keys could theoretically grow without limit, it's usually possible to estimate a save upper bound in practice.
As I like the theoretical side of your question (it really is beautiful), and to contradict what many of the practical answers say, I would like to give an answer to the "math" part of your tags :)
In fact it is possible to map any two numbers (or actually any series of numbers) to a single number. This is called the Gödel number and was first published in 1931 by Kurt Gödel.
To give a quick example, with your question; say we have two variables v1 and v2. Then v3=2v1*3v2 would give a unique number. This number also uniquely identifies v1 and v2.
Of course the resulting number v3 may grow undesirably rapid. Please, just take this answer as a reply to the theoretical aspect in your question.
Both of the suggested solutions require some knowledge about the range of accepted keys.
To avoid making this assumption, one can riffle the digits together.
Key1 = ABC => Digits = A, B, C
Key2 = 123 => Digits = 1, 2, 3
Riffle(Key1, Key2) = A, 1, B, 2, C, 3
Zero-padding can be used when there aren't enough digits:
Key1 = 12345, Key2 = 1 => 1020304051
This method also generalizes for any number of keys.
wrote these for mysql they work fine
CREATE FUNCTION pair (x BIGINT unsigned, y BIGINT unsigned)
RETURNS BIGINT unsigned DETERMINISTIC
RETURN ((x + y) * (x + y + 1)) / 2 + y;
CREATE FUNCTION reversePairX (z BIGINT unsigned)
RETURNS BIGINT unsigned DETERMINISTIC
RETURN (FLOOR((-1 + SQRT(1 + 8 * z))/2)) * ((FLOOR((-1 + SQRT(1 + 8 * z))/2)) + 3) / 2 - z;
CREATE FUNCTION reversePairY (z BIGINT unsigned)
RETURNS BIGINT unsigned DETERMINISTIC
RETURN z - (FLOOR((-1 + SQRT(1 + 8 * z))/2)) * ((FLOOR((-1 + SQRT(1 + 8 * z))/2)) + 1) / 2;
At the risk of sounding facetious:
NewKey = fn(OldKey1, OldKey2)
where fn() is a function that looks up a new autonumbered key value from a column added to your existing table.
Obviously, two integer fields can hold exponentially more values than a single integer field.
Why don't you just use ROW_NUMBER() or IDENTITY(int,1,1) to set new ID? Do they REALLY need to be in relation?