public void Binary_Regular_Float_Dot_Separated_Test() { INumber number = new NumberModel("100101.010101", 2); number.IntegerPart.Should().Be("100101"); number.FloatPart.Should().Be("010101"); number.Base.Should().Be(2); number = new BinaryNumber("100101.010101"); number.IntegerPart.Should().Be("100101"); number.FloatPart.Should().Be("010101"); number.Base.Should().Be(2); }
private EndPoint[] QueryAnnounce(NodeContact[] initialContacts, BinaryNumber networkId, EndPoint serviceEP) { NodeContact[] contacts = QueryFindNode(initialContacts, networkId); if ((contacts == null) || (contacts.Length == 0)) { return(null); } List <EndPoint> peers = new List <EndPoint>(); lock (peers) { int respondedContacts = 0; foreach (NodeContact contact in contacts) { ThreadPool.QueueUserWorkItem(delegate(object state) { DhtRpcPacket response = Query(DhtRpcPacket.CreateAnnouncePeerPacketQuery(_currentNode, networkId, serviceEP), contact); if ((response != null) && (response.Type == DhtRpcType.ANNOUNCE_PEER) && (response.Peers.Length > 0)) { lock (peers) { foreach (EndPoint peer in response.Peers) { if (!peers.Contains(peer)) { peers.Add(peer); } } respondedContacts++; if (respondedContacts == contacts.Length) { Monitor.Pulse(peers); } } } }); } if (Monitor.Wait(peers, _queryTimeout)) { return(peers.ToArray()); } return(null); } }
public SecureChannelHandshakeKeyExchange(KeyAgreement keyAgreement, SecureChannelHandshakeHello serverHello, SecureChannelHandshakeHello clientHello, byte[] psk) : base(SecureChannelCode.None) { _ephemeralPublicKey = keyAgreement.GetPublicKey(); if (serverHello.Options.HasFlag(SecureChannelOptions.PRE_SHARED_KEY_AUTHENTICATION_REQUIRED)) { _pskAuth = GetPskAuthValue(serverHello.SupportedCiphers, _ephemeralPublicKey, serverHello.Nonce.Value, clientHello.Nonce.Value, psk); } else { _pskAuth = new BinaryNumber(new byte[] { }); } }
public SharedFileMetaData(string fileName, ContentType contentType, DateTime lastModified, long fileSize, int blockSize, string hashAlgo, byte[][] blockHash) { _fileName = fileName; _contentType = contentType; _lastModified = lastModified; _fileSize = fileSize; _blockSize = blockSize; _hashAlgo = hashAlgo; _blockHash = blockHash; _fileID = ComputeFileID(); }
public bool RequestStopTcpRelay(BinaryNumber[] networkIDs, int timeout) { BinaryNumber channelName = BinaryNumber.GenerateRandomNumber160(); object lockObject = new object(); lock (_tcpRelayRequestLockList) { _tcpRelayRequestLockList.Add(channelName, lockObject); } try { lock (lockObject) { using (MemoryStream mS = new MemoryStream(1024)) { byte[] XORnetworkID = new byte[20]; byte[] randomChannelID = channelName.Number; //write networkid list mS.WriteByte(Convert.ToByte(networkIDs.Length)); foreach (BinaryNumber networkID in networkIDs) { byte[] network = networkID.Number; for (int i = 0; i < 20; i++) { XORnetworkID[i] = (byte)(randomChannelID[i] ^ network[i]); } mS.Write(XORnetworkID, 0, 20); } byte[] data = mS.ToArray(); WriteFrame(SignalType.StopTcpRelay, channelName, data, 0, data.Length); } return(Monitor.Wait(lockObject, timeout)); } } finally { lock (_tcpRelayRequestLockList) { _tcpRelayRequestLockList.Remove(channelName); } } }
public MessageRecipient(BinaryReader bR) { switch (bR.ReadByte()) //version { case 1: _userId = new BinaryNumber(bR.BaseStream); _status = (MessageRecipientStatus)bR.ReadByte(); _deliveredOn = bR.ReadDate(); break; default: throw new InvalidDataException("Cannot decode data format: version not supported."); } }
public static bool IsUserIdValid(byte[] publicKey, BinaryNumber userId) { if (userId.Value.Length != 20) { return(false); } byte[] random = new byte[4]; Buffer.BlockCopy(userId.Value, 0, random, 0, 4); byte[] generatedValue = GenerateUserId(publicKey, random); return(BinaryNumber.Equals(userId.Value, generatedValue)); }
public SecureChannelHandshakeAuthentication(Stream s) : base(s) { _userId = new BinaryNumber(s); byte[] buffer = new byte[2]; s.ReadBytes(buffer, 0, 2); _publicKey = new byte[BitConverter.ToUInt16(buffer, 0)]; s.ReadBytes(_publicKey, 0, _publicKey.Length); s.ReadBytes(buffer, 0, 2); _signature = new byte[BitConverter.ToUInt16(buffer, 0)]; s.ReadBytes(_signature, 0, _signature.Length); }
private void ConnectionManager_BitChatNetworkChannelInvitation(BinaryNumber hashedPeerEmailAddress, IPEndPoint peerEP, string message) { BinaryNumber networkID = BitChatNetwork.GetNetworkID(_profile.LocalCertificateStore.Certificate.IssuedTo.EmailAddress, hashedPeerEmailAddress); bool networkExists; lock (_chats) { networkExists = _chats.ContainsKey(networkID); } if (!networkExists) { CreateInvitationPrivateChat(hashedPeerEmailAddress, networkID, peerEP, message); } }
public void AnnounceAsync(BinaryNumber networkId, bool localNetworkOnly, Action <DhtNetworkType, ICollection <EndPoint> > callback) { EndPoint serviceEP; if (_torInternetDhtNode == null) { serviceEP = _ipv4InternetDhtNode.LocalNodeEP; } else { serviceEP = _torInternetDhtNode.LocalNodeEP; } AnnounceAsync(networkId, localNetworkOnly, serviceEP, callback); }
public SharedFileMetaData(Stream s) { switch (s.ReadByte()) //version { case 1: int length; byte[] buffer = new byte[255]; length = s.ReadByte(); OffsetStream.StreamRead(s, buffer, 0, length); _fileName = Encoding.UTF8.GetString(buffer, 0, length); length = s.ReadByte(); OffsetStream.StreamRead(s, buffer, 0, length); _contentType = new ContentType(Encoding.UTF8.GetString(buffer, 0, length)); OffsetStream.StreamRead(s, buffer, 0, 8); _lastModified = _epoch.AddSeconds(BitConverter.ToInt64(buffer, 0)); OffsetStream.StreamRead(s, buffer, 0, 8); _fileSize = BitConverter.ToInt64(buffer, 0); OffsetStream.StreamRead(s, buffer, 0, 4); _blockSize = BitConverter.ToInt32(buffer, 0); length = s.ReadByte(); OffsetStream.StreamRead(s, buffer, 0, length); _hashAlgo = Encoding.ASCII.GetString(buffer, 0, length); int totalBlocks = Convert.ToInt32(Math.Ceiling(Convert.ToDouble((double)_fileSize / _blockSize))); _blockHash = new byte[totalBlocks][]; int hashLength = s.ReadByte(); for (int i = 0; i < totalBlocks; i++) { _blockHash[i] = new byte[hashLength]; OffsetStream.StreamRead(s, _blockHash[i], 0, hashLength); } _fileID = ComputeFileID(); break; default: throw new BitChatException("FileMetaData format version not supported."); } }
// this method should be called for numbers greater than 0. // When calling this function, only the first parameter should be given public string ConvertToBinaryNumber(int DecimalNumber, StringBuilder BinaryNumber = null) { if (BinaryNumber == null) { BinaryNumber = new StringBuilder(); } if (DecimalNumber > 0) { BinaryNumber.Insert(0, DecimalNumber % 2); return(ConvertToBinaryNumber(DecimalNumber / 2, BinaryNumber)); } return(BinaryNumber.ToString() != "" ? BinaryNumber.ToString() : "0"); }
/// <summary> /// Gets the equivalent binary number for the given integer, then reverses the order of the bits for use as a polynomial's coefficients /// </summary> /// <param name="decimalForm"></param> /// <returns></returns> private static bool[] ConvertToPolynomialBits(BigInteger decimalForm) { var binary = new BinaryNumber(decimalForm); // 10 => 1010. But note that this is in Big-Endian format, where we need Little-Endian var bits = new bool[binary.Count]; var node = binary.Last; var i = 0; while (node != null) { bits[i] = node.Value; i++; node = node.Previous; } return(bits); }
public bool IsThisNetwork(BinaryNumber networkID) { if (_isResponse) { throw new Exception("Packet is not a query."); } BinaryNumber computedHmac; using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.Number)) { computedHmac = new BinaryNumber(hmacSHA256.ComputeHash(_challenge.Number)); //computed hmac } return(_hmac.Equals(computedHmac)); }
private PeerEndPoint[] QueryAnnounce(NodeContact[] initialContacts, BinaryNumber networkID, ushort servicePort) { NodeContact[] contacts = QueryFindNode(initialContacts, networkID); if ((contacts == null) || (contacts.Length == 0)) { return(null); } List <PeerEndPoint> peers = new List <PeerEndPoint>(); lock (peers) { foreach (NodeContact contact in contacts) { Thread t = new Thread(delegate(object state) { DhtRpcPacket response = Query(DhtRpcPacket.CreateAnnouncePeerPacketQuery(_currentNode, networkID, servicePort), contact); if ((response != null) && (response.Type == DhtRpcType.ANNOUNCE_PEER) && (response.Peers.Length > 0)) { lock (peers) { foreach (PeerEndPoint peer in response.Peers) { if (!peers.Contains(peer)) { peers.Add(peer); } } Monitor.Pulse(peers); } } }); t.IsBackground = true; t.Start(); } if (Monitor.Wait(peers, QUERY_TIMEOUT)) { return(peers.ToArray()); } return(null); } }
/// <summary> /// Returns the index form of the given decimal, assuming that this polynomial is a primitive polynomial for a finite field /// </summary> /// <param name="decimalForm"></param> /// <returns></returns> public BigInteger GetIndexForm(BigInteger decimalForm) { if (decimalForm.IsZero) { return(0); // This is by definition } // This is kind of the opposite of performing modulus. Instead of subtracting increasing smaller multiples of the primitive polynomial to cancel out the higher bits until there's only a remainder left, we start with the remainder and add on increasingly larger multiples of the primitive polynomial in order to cancel out the lower bits until only a single bit is set var binary = new BinaryNumber(decimalForm); // The binary version of the given decimal var polynomial = new BinaryNumber(GetNumber()); // The binary version of this polynomial. Note that BinaryNumber's bits are set from most- to least-significant, which is the opposite of a Polynomial // Define a method that will throw an exception if things don't work var throwException = new Action(() => { throw new Exception("This number doesn't work as a primitive polynomial for the given number, because a power of the generator couldn't be found"); }); // Figure out the maximum number of shifts that we'll allow before giving up var maxShifts = BigInteger.Pow(2, polynomial.Count - 1); // We'll look for up to this power of the generator var shifts = new BigInteger(); // Keeps track of the number of shifts that have been made while (binary.Count > 1) // Keep looping as long as there is more than one bit left to cancel out { binary ^= polynomial; // XOR with the polynomial. This gets rid of successively more lower bits while (!binary.LeastSignificantBit() && binary.Count > 1) // Shift right to get rid of trailing zeros { binary.RotateRight(); shifts++; // Keep track of the number of shifts that were made } if (shifts > maxShifts) { throwException(); } } if (binary.First.Value) // We wound up with the number "1" by itself. This means that the index is x^shifts { return(shifts); } else // We wound up with zero. This means that the index form of the given decimal is undefined { throwException(); } // Code shouldn't get this far, but the compiler doesn't recognize that our exception method will always throw an exception throw new NotImplementedException(); }
public void EnableTcpRelayClientMode() { if (_tcpRelayClientModeTimer == null) { _tcpRelayClientModeTimer = new Timer(delegate(object state) { try { WriteFrame(ConnectionSignal.PingRequest, BinaryNumber.GenerateRandomNumber256(), null, 0, 0); } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); } }, null, 1000, TCP_RELAY_CLIENT_MODE_TIMER_INTERVAL); } }
internal MessageItem(DateTime messageDate, BinaryNumber senderUserId, MessageRecipient[] recipients, MessageType type, string messageText, byte[] imageThumbnail, string fileName, long fileSize, string filePath) { _messageNumber = -1; _remoteMessageNumber = -1; _messageDate = messageDate; _senderUserId = senderUserId; _recipients = recipients; _type = type; _messageText = messageText; _imageThumbnail = imageThumbnail; _fileName = fileName; _fileSize = fileSize; _filePath = filePath; }
internal void MeshNetworkRequest(Connection connection, BinaryNumber networkId, Stream channel) { MeshNetwork network = null; lock (_networks) { if (_networks.ContainsKey(networkId)) { network = _networks[networkId]; } } if (network == null) { if (!networkId.Equals(_maskedUserId)) { //no network found channel.Dispose(); return; } //private network connection invitation attempt if (!_allowInboundInvitations || (_allowOnlyLocalInboundInvitations && ((connection.RemotePeerEP.AddressFamily == AddressFamily.Unspecified) || !NetUtilities.IsPrivateIP((connection.RemotePeerEP as IPEndPoint).Address)))) { //not allowed channel.Dispose(); return; } //accept invitation network = MeshNetwork.AcceptPrivateNetworkInvitation(_connectionManager, connection, channel); //add network lock (_networks) { _networks.Add(network.NetworkId, network); } //notify UI RaiseEventInvitationReceived(network); } else { network.AcceptConnectionAndJoinNetwork(connection, channel); } }
public EndPoint[] GetPeers(BinaryNumber networkId) { List <PeerEndPoint> peers; lock (_data) { if (_data.ContainsKey(networkId)) { peers = _data[networkId]; } else { return(new EndPoint[] { }); } } List <PeerEndPoint> finalPeers; lock (peers) { if (peers.Count > MAX_PEERS_TO_RETURN) { finalPeers = new List <PeerEndPoint>(peers); Random rnd = new Random(DateTime.UtcNow.Millisecond); while (finalPeers.Count > MAX_PEERS_TO_RETURN) { finalPeers.RemoveAt(rnd.Next(finalPeers.Count - 1)); } } else { finalPeers = _data[networkId]; } } EndPoint[] finalEPs = new EndPoint[finalPeers.Count]; int i = 0; foreach (PeerEndPoint peer in finalPeers) { finalEPs[i++] = peer.EndPoint; } return(finalEPs); }
public BitChat CreatePrivateChat(MailAddress peerEmailAddress, string sharedSecret, bool enableTracking, bool dhtOnlyTracking, string invitationMessage) { Uri[] trackerURIs; if (dhtOnlyTracking) { trackerURIs = new Uri[] { } } ; else { trackerURIs = _profile.TrackerURIs; } BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, peerEmailAddress, sharedSecret, null, null, new Certificate[] { }, BitChatNetworkStatus.Online, _profile.LocalCertificateStore.Certificate.IssuedTo.EmailAddress.Address, invitationMessage); return(CreateBitChat(network, BinaryNumber.GenerateRandomNumber160().ToString(), BinaryNumber.GenerateRandomNumber256().Number, 0, null, new BitChatProfile.SharedFileInfo[] { }, trackerURIs, enableTracking, !string.IsNullOrEmpty(invitationMessage), false)); }
public BitChat CreateGroupChat(string networkName, string sharedSecret, bool enableTracking, bool dhtOnlyTracking) { Uri[] trackerURIs; if (dhtOnlyTracking) { trackerURIs = new Uri[] { } } ; else { trackerURIs = _profile.TrackerURIs; } BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, networkName, sharedSecret, null, null, new Certificate[] { }, BitChatNetworkStatus.Online); return(CreateBitChat(network, BinaryNumber.GenerateRandomNumber160().ToString(), BinaryNumber.GenerateRandomNumber256().Number, -1, null, new BitChatProfile.SharedFileInfo[] { }, trackerURIs, enableTracking, false, false)); }
public MeshNode(Stream s, string password, string profileFolder, TorController torController) { _password = password; _profileFolder = profileFolder; switch (s.ReadByte()) //version { case 1: //read headers and init decryptor Aes decryptionAlgo = Aes.Create(); decryptionAlgo.Key = MeshNetwork.GetKdfValue32(Encoding.UTF8.GetBytes(password), s.ReadBytes(32), 1, 1 * 1024 * 1024); //salt decryptionAlgo.IV = s.ReadBytes(16); //IV decryptionAlgo.Padding = PaddingMode.ISO10126; decryptionAlgo.Mode = CipherMode.CBC; byte[] hmac = s.ReadBytes(32); //hmac long cipherTextStartPosition = s.Position; //authenticate data in Encrypt-then-MAC (EtM) mode using (HMAC aeHmac = new HMACSHA256(decryptionAlgo.Key)) { byte[] computedHmac = aeHmac.ComputeHash(s); if (!BinaryNumber.Equals(hmac, computedHmac)) { throw new CryptographicException("Invalid password or data tampered."); } } //decrypt data and init node s.Position = cipherTextStartPosition; CryptoStream cS = new CryptoStream(s, decryptionAlgo.CreateDecryptor(), CryptoStreamMode.Read); InitMeshNode(new BinaryReader(cS), torController); break; case -1: throw new EndOfStreamException(); default: throw new InvalidDataException("MeshNode format version not supported."); } }
public MeshNetwork CreateGroupChat(string networkName, string sharedSecret, bool localNetworkOnly) { //use random userId for each independent chat network for privacy reasons BinaryNumber randomUserId = SecureChannelStream.GenerateUserId(SecureChannelStream.GetPublicKeyFromPrivateKey(_privateKey)); MeshNetwork network = new MeshNetwork(_connectionManager, randomUserId, networkName, sharedSecret, localNetworkOnly); lock (_networks) { if (_networks.ContainsKey(network.NetworkId)) { network.Dispose(); throw new MeshException("Mesh network for group chat '" + network.NetworkName + "' already exists."); } _networks.Add(network.NetworkId, network); } return(network); }
public MeshNetworkPeerInfo(BinaryReader bR) { _peerUserId = new BinaryNumber(bR.BaseStream); _peerName = Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte())); if (_peerName == "") { _peerName = null; } { _peerEPs = new EndPoint[bR.ReadByte()]; for (int i = 0; i < _peerEPs.Length; i++) { _peerEPs[i] = EndPointExtension.Parse(bR); } } }
public void RemoveNetwork(BinaryNumber networkID) { lock (_networks) { bool removed = _networks.Remove(networkID); if (!removed) { return; } } lock (_tcpRelayConnections) { foreach (Connection relayConnection in _tcpRelayConnections.Values) { ThreadPool.QueueUserWorkItem(RemoveTcpRelayFromConnectionAsync, new object[] { relayConnection, new BinaryNumber[] { networkID } }); } } }
public SecureChannelHandshakeAuthentication(SecureChannelHandshakeKeyExchange keyExchange, SecureChannelHandshakeHello serverHello, SecureChannelHandshakeHello clientHello, BinaryNumber userId, byte[] privateKey) : base(SecureChannelCode.None) { _userId = userId; switch (serverHello.SupportedCiphers) { case SecureChannelCipherSuite.DHE2048_RSA2048_WITH_AES256_CBC_HMAC_SHA256: case SecureChannelCipherSuite.ECDHE256_RSA2048_WITH_AES256_CBC_HMAC_SHA256: using (RSA rsa = RSA.Create()) { RSAParameters rsaPrivateKey = DEREncoding.DecodeRSAPrivateKey(privateKey); rsa.ImportParameters(rsaPrivateKey); if (rsa.KeySize != 2048) { throw new SecureChannelException(SecureChannelCode.PeerAuthenticationFailed, null, _userId, "RSA key size is not valid for selected crypto option: " + serverHello.SupportedCiphers.ToString()); } _publicKey = DEREncoding.EncodeRSAPublicKey(rsaPrivateKey); if (!SecureChannelStream.IsUserIdValid(_publicKey, _userId)) { throw new SecureChannelException(SecureChannelCode.PeerAuthenticationFailed, null, _userId, "UserId does not match with public key."); } using (MemoryStream mS = new MemoryStream()) { mS.Write(keyExchange.EphemeralPublicKey); mS.Write(serverHello.Nonce.Value); mS.Write(clientHello.Nonce.Value); mS.Position = 0; _signature = rsa.SignData(mS, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } } break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCipherAvailable, null, null); } }
public DiscoveryPacket(Stream s) { switch (s.ReadByte()) { case 5: //query { byte[] bufferChallenge = new byte[32]; byte[] bufferHmac = new byte[32]; OffsetStream.StreamRead(s, bufferChallenge, 0, 32); OffsetStream.StreamRead(s, bufferHmac, 0, 32); _isResponse = false; _challenge = new BinaryNumber(bufferChallenge); _hmac = new BinaryNumber(bufferHmac); } break; case 6: //response { byte[] bufferServicePort = new byte[2]; byte[] bufferChallenge = new byte[32]; byte[] bufferHmac = new byte[32]; OffsetStream.StreamRead(s, bufferServicePort, 0, 2); OffsetStream.StreamRead(s, bufferChallenge, 0, 32); OffsetStream.StreamRead(s, bufferHmac, 0, 32); _isResponse = true; _servicePort = BitConverter.ToUInt16(bufferServicePort, 0); _challenge = new BinaryNumber(bufferChallenge); _hmac = new BinaryNumber(bufferHmac); } break; case -1: throw new EndOfStreamException(); default: throw new IOException("Invalid local discovery packet."); } }
public byte[] ToArray(BinaryNumber networkID, IPAddress senderPeerIP = null) { using (MemoryStream mS = new MemoryStream(BUFFER_MAX_SIZE)) { if (_isResponse) { byte[] servicePort = BitConverter.GetBytes(_servicePort); mS.WriteByte(6); //version mS.Write(servicePort, 0, 2); //service_port mS.Write(_challenge.Number, 0, 32); //query_challenge using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.Number)) { using (MemoryStream mS2 = new MemoryStream(50)) { mS2.Write(_challenge.Number, 0, 32); //query_challenge byte[] ipAddr = senderPeerIP.GetAddressBytes(); mS2.Write(ipAddr, 0, ipAddr.Length); //peer_ip_address mS2.Write(servicePort, 0, 2); //service_port mS2.Position = 0; mS.Write(hmacSHA256.ComputeHash(mS2), 0, 32); //hmac } } } else { mS.WriteByte(5); //version mS.Write(_challenge.Number, 0, 32); //challenge using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.Number)) { mS.Write(hmacSHA256.ComputeHash(_challenge.Number), 0, 32); //hmac } } return(mS.ToArray()); } }
public Stream ConnectMeshNetwork(BinaryNumber channelId) { ChannelStream channel; lock (_channels) { if (_channels.ContainsKey(channelId)) { throw new InvalidOperationException("Channel already exists."); } channel = new ChannelStream(this, channelId); _channels.Add(channel.ChannelId, channel); } //send connect signal WriteFrame(ConnectionSignal.ConnectChannelMeshNetwork, channelId, null, 0, 0); return(channel); }
public static Bool EqualTo(this BinaryNumber x, BinaryNumber y) { return x.IsZero.And(y.IsZero).Or(() => x.IsOdd.EqualTo(y.IsOdd).And(() => x.Rest.EqualTo(y.Rest))); }
public static Bool GreaterThanOrEqualTo(this BinaryNumber x, BinaryNumber y) { return y.LessThanOrEqualTo(x); }
public static Bool LessThanOrEqualTo(this BinaryNumber x, BinaryNumber y) { return x.Accept(y, LessThanOrEqualToFunc.Instance); }
public static BinaryNumber Multiply(this BinaryNumber x, BinaryNumber y) { // For efficency always recur down the smaller number return x.LessThan(y).Accept(() => y.Accept(MultiplyFunc.Instance, x), () => x.Accept(MultiplyFunc.Instance, y)); }
public static DivisionResult<BinaryNumber> DivideBy(this BinaryNumber dividend, BinaryNumber divisor) { return divisor.IsZero.Accept(() => { throw new DivideByZeroException(); }, () => dividend.UncheckedDivideBy(divisor)); }
public Integer ShiftRight(BinaryNumber places) { return new Integer(value.ShiftRight(places), sign); }
public Integer(BinaryNumber value) { this.value = value; sign = Sign.Positive; }
public static BinaryNumber ShiftLeft(this BinaryNumber x, BinaryNumber places) { var result = x; places.Repeat(() => result = result.Double()); return result; }
public static BinaryNumber Subtract(this BinaryNumber x, BinaryNumber y) { return x.Accept(y, SubtractFunc.Instance); }
private static DivisionResult<BinaryNumber> UncheckedDivideBy(this BinaryNumber dividend, BinaryNumber divisor) { return dividend.IsZero.Accept(() => DivisionResult.Create(BinaryNumber.Zero, BinaryNumber.Zero), () => { var partial = dividend.Rest.DivideBy(divisor); var remainder = dividend.IsOdd.Accept(() => partial.Remainder.DoubleAddOne(), () => partial.Remainder.Double()); var quotient = remainder.GreaterThanOrEqualTo(divisor) .Accept(() => { remainder = remainder.Subtract(divisor); return partial.Quotient.DoubleAddOne(); }, () => partial.Quotient.Double()); return DivisionResult.Create(quotient, remainder); }); }
public static BinaryNumber ShiftRight(this BinaryNumber x, BinaryNumber places) { var result = x; places.Repeat(() => result = result.Rest); return result; }
public Integer() { value = BinaryNumber.Zero; sign = Sign.Zero; }
public Integer(BinaryNumber value, Bool positive) { this.value = value; sign = Sign.Create(positive).CheckZero(value); }
public Integer(Integer value) { sign = value.sign; this.value = value.value; }
public Integer(BinaryNumber value, Sign sign) { this.sign = sign.CheckZero(value); this.value = value; }
public static BinaryNumber Add(this BinaryNumber x, BinaryNumber y) { return x.Accept(y, AddFunc.Instance); }