//Dividiert einen BigNum (result = a / c) public bool Div(BigNum a, BigNum b) { var o1 = new BigNum(); var o2 = new BigNum(); Reset(); o1.Copy(a); o2.Copy(b); //Fange falsche Werte ab if (o1.IsZero() || o2.IsZero()) { return(false); } //Suche maximum var shiftCount = 0; while (o1.Compare(o2) >= 0 && (o2.Content[BignumSize - 1] & 0x80) == 0) { ++shiftCount; o2.Double(); } //Mache den letzten Verdoppler Rückgängig o2.Half(); //Solange b ist nicht Null while (shiftCount > 0) { //Rücke result Double(); //Passt b in a? if (o1.Compare(o2) >= 0) // (a-b)>=0 { //Subtrahiere von a o1.Sub(o1, o2); //Setze Result Content[0] |= 1; } //Halbiere b o2.Half(); //Zähle shiftanzahl --shiftCount; } //Return erfolg return(true); }
//Berechnet den Modulo einer Bignumdivision (result = A%B) public bool Mod(BigNum a, BigNum b) { var factor = new BigNum(); //Runde Factor auf a/b*b factor.Div(a, b); factor.Mul(factor, b); //Berechne Rest Sub(a, factor); //Return Erfolg return(true); }
//Bignumvergleiche //Vergleicht zwei Bignums (-1,0,1) public int Compare(BigNum b) { for (var i = (BignumSize - 1); i >= 0; --i) { var vergleich = Content[i] - b.Content[i]; //Falls unterschiedlich, gib Unterschied zurück if (vergleich != 0) { return(vergleich); } } //Return gleich return(0); }
//Addiert zwei Bignums (A = B + C), gibt den Überlauf zurück public uint Add(BigNum b, BigNum c) { var overflow = 0U; for (var i = 0; i < BignumSize; ++i) { //Addiere zu overflow die beiden BigNum Ziffern overflow += (uint)b.Content[i] + c.Content[i]; //Speichere aktuellen Ziffernwert Content[i] = (byte)(overflow & 0xFF); overflow = overflow >> 8; } return(overflow); }
//Subtrahiert zwei Bignums (Result = B - C), gibt den Überlauf zurück public uint Sub(BigNum b, BigNum c) { var overflow = 1U; for (var i = 0; i < BignumSize; i++) { //Addiere zu overflow die beiden BigNum Ziffern b + ~d overflow += b.Content[i] + (uint)((~c.Content[i]) & 0xFF); //Speichere aktuellen Ziffernwert Content[i] = (byte)(overflow & 0xFF); //Rücke overflow Wert overflow = overflow >> 8; } return(overflow); }
//Multipliziert zwei Bignums (result = a * b) public bool Mul(BigNum a, BigNum b) { //Zwischenspeicher für Ziffern-Multiplikationsergebniss var storer = new BigNum(); var resultnew = new BigNum(); var o1 = new BigNum(); var o2 = new BigNum(); o1.Copy(a); o2.Copy(b); //Ziffernwertspeicher resultnew.Reset(); for (var i = 0; i < BignumSize; ++i) { //Setze storer und overflow auf 0 storer.Reset(); var overflow = 0U; //Berechne Ziffernmultiplikation for (var i2 = 0; i2 < (BignumSize - i); ++i2) { //Multipliziere Ziffern overflow += o1.Content[i] * (uint)o2.Content[i2]; //Speichere Ziffer storer.Content[i + i2] = (byte)(overflow & 0xFF); //Schiebe Ziffern overflow = overflow >> 8; } //Addiere Ziffernprodukt zu result resultnew.Add(resultnew, storer); } //Kopiere Ergebniss Copy(resultnew); //Return erfolg return(true); }
//Modulare Exponentiation (result = (B^E)%N) public bool ModExp(BigNum b, BigNum e, BigNum n) { var p = new BigNum(); var exponent = new BigNum(); var bitCount = e.CountBits(); //Setze p auf 1 p.Reset(); p.SetUInt32(0x01); //Kopiere Exponent exponent.Copy(e); //Beginne schleife while (bitCount >= 0) { p.Mul(p, p); p.Mod(p, n); //Falls ungerade multiplizierte mit Basis if ((exponent.Content[bitCount / 8] & (1 << (bitCount % 8))) != 0) { p.Mul(p, b); p.Mod(p, n); } //Halbiere exponent //Bignum_Half(&exponent); --bitCount; } //Kopiere Ergebniss Copy(p); //Return erfolg return(true); }
public bool Copy(BigNum src) { Array.Copy(src.Content, Content, src.Content.Length); return(true); }